ToString ()을 사용하지 않고 C #에서 Int를 String으로 어떻게 변환합니까?
기본 toString 기능을 사용하지 않고 다음 int 인수를 문자열로 변환합니다.
public string integerToString(int integerPassedIn){ //Your code here }
모든 것을 상속 이후 Object
및 Object
가 ToString()
당신이 변환 얼마나 방법 int
A를 string
네이티브 사용하지 않고 ToString()
방법을?
문자열 연결의 문제점은 ToString()
하나에 도달하거나 Object
클래스에 도달 할 때까지 체인 을 호출한다는 것입니다 .
사용하지 않고 C #에서 정수를 문자열로 어떻게 변환 ToString()
합니까?
이 같은:
public string IntToString(int a)
{
var chars = new[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
var str = string.Empty;
if (a == 0)
{
str = chars[0];
}
else if (a == int.MinValue)
{
str = "-2147483648";
}
else
{
bool isNegative = (a < 0);
if (isNegative)
{
a = -a;
}
while (a > 0)
{
str = chars[a % 10] + str;
a /= 10;
}
if (isNegative)
{
str = "-" + str;
}
}
return str;
}
업데이트 : 고정 길이 배열을 조작하기 위해 모든 문자열 연결을 제거하기 때문에 더 짧고 훨씬 더 나은 성능을 발휘해야하는 또 다른 버전이 있습니다. 최대 16 개의베이스를 지원하지만 더 높은베이스로 확장하기 쉽습니다. 더 개선 될 수 있습니다.
public string IntToString(int a, int radix)
{
var chars = "0123456789ABCDEF".ToCharArray();
var str = new char[32]; // maximum number of chars in any base
var i = str.Length;
bool isNegative = (a < 0);
if (a <= 0) // handles 0 and int.MinValue special cases
{
str[--i] = chars[-(a % radix)];
a = -(a / radix);
}
while (a != 0)
{
str[--i] = chars[a % radix];
a /= radix;
}
if (isNegative)
{
str[--i] = '-';
}
return new string(str, i, str.Length - i);
}
이것이 내가 항상 사용하는 솔루션입니다.
public static string numberBaseChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public static string IntToStringWithBase(int n, int b) {
return IntToStringWithBase(n, b, 1);
}
public static string IntToStringWithBase(int n, int b, int minDigits) {
if (minDigits < 1) minDigits = 1;
if (n == 0) return new string('0', minDigits);
string s = "";
if ((b < 2) || (b > numberBaseChars.Length)) return s;
bool neg = false;
if ((b == 10) && (n < 0)) { neg = true; n = -n; }
uint N = (uint)n;
uint B = (uint)b;
while ((N > 0) | (minDigits-- > 0)) {
s = numberBaseChars[(int)(N % B)] + s;
N /= B;
}
if (neg) s = "-" + s;
return s;
}
이것은 매우 복잡해 보이지만 다음과 같은 기능이 있습니다.
- 기수 2 ~ 36 지원
- 음수 값 처리
- 선택적 총 자릿수
나는 연결 operator +
호출을 진정으로 확신하지 ToString
못하지만 그것이 사실이라면 다음과 같은 작업을 수행하여 두 가지를 피할 수 있습니다.
if (a == 0) return "0";
/* Negative maxint doesn't have a corresponding positive value, so handle it
* as a special case. Thanks to @Daniel for pointing this out.
*/
if (a == 0x80000000) return "-2147483648";
List<char> l = new List<char>();
bool negative = false;
if (a < 0)
{
negative = true;
a *= -1;
}
while (a > 0)
{
l.Add('0' + (char)(a % 10));
a /= 10;
}
if (negative) l.Add('-');
l.Reverse();
return new String(l.ToArray());
정수는 최하위 숫자부터 최상위까지 처리됩니다. 모듈로 10 (% 10)을 사용하여 단일 숫자를 계산 한 다음 문자 값 '0'에 추가합니다. 결과적으로 '0', '1', ..., '9'문자 중 하나가됩니다.
숫자는 처리 될 때 역순으로 표시되어야하므로 스택으로 푸시됩니다 (최상위 숫자에서 최하위 숫자). 문자열 앞에 숫자를 반복적으로 붙이는 대신 이렇게하는 것이 더 효율적일 수 있지만, 숫자 수가 매우 적기 때문에 확실하게 벤치 마크를 수행해야합니다.
양수가 아닌 숫자를 처리하려면 추가 처리가 필요합니다.
public string IntToString(int a) {
if (a == 0)
return "0";
if (a == int.MinValue)
return "-2147483648";
var isNegative = false;
if (a < 0) {
a = -a;
isNegative = true;
}
var stack = new Stack<char>();
while (a != 0) {
var c = a%10 + '0';
stack.Push((char) c);
a /= 10;
}
if (isNegative)
stack.Push('-');
return new string(stack.ToArray());
}
내 첫 번째 버전 StringBuilder
에서는 문자 배열에서 문자열을 만드는 데 a 를 사용했지만 "out of the"문자열을 얻으려면 StringBuilder
라는 메서드를 호출해야합니다 ToString
. 분명히이 방법은이 질문이 무엇인지에 대한 문자열 변환을 int로 수행하지 않습니다.
그러나 호출하지 않고 문자열을 만들 수 있음을 증명하기 위해 생성자 ToString
를 사용하는 것으로 전환 string
했습니다 StringBuilder
.
그리고 ToString
어떤 형태로든 금지 된 경우 문서에 표시된대로 문자열 연결을 사용할 수 없습니다 string.Concat
.
이 메서드는 arg0 및 arg1의 매개 변수가없는 ToString 메서드를 호출하여 arg0과 arg1을 연결합니다. 구분 기호를 추가하지 않습니다.
그래서 실행 s += '1'
하면 '1'.ToString()
. 그러나 나에게 이것은 중요하지 않습니다. 중요한 부분은 int를 문자열로 변환하는 방법입니다.
더 짧은 버전과 다음을 사용하는 버전을 목표로합니다 Math.DivRem
.
string IntToString(int a)
{
if (a == int.MinValue)
return "-2147483648";
if (a < 0)
return "-" + IntToString(-a);
if (a == 0)
return "0";
var s = "";
do
{
int r;
a = Math.DivRem(a, 10, out r);
s = new string((char)(r + (int)'0'), 1) + s;
}
while (a > 0);
return s;
}
new string(..., 1)
생성자 의 사용은 ToString
아무것도 호출되지 않는 OP의 요구 사항을 충족시키는 방법 일뿐 입니다.
여기에 런타임 분석과 함께 반복 및 재귀를 사용하는 방법이 있습니다.
public static class IntegerToString
{
static char[] d = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
public static string Iteration(int num, int radix = 10)
{
if (num == 0) return "0";
if (num < 0) return "-" + Iteration(Math.Abs(num));
var r = new List<char>();
while (num > 0)
{
r.Insert(0, d[num % radix]);
num /= radix;
}
return new string(r.ToArray());
}
public static string Recursion(int num, int radix = 10)
{
if (num == 0) return "0";
if (num < 0) return "-" + Recursion(Math.Abs(num));
return (num > radix - 1 ? Recursion(num / radix) : "") + d[num % radix];
}
}
키 포인트
- 기본 2를 최대 36까지 처리합니다 (주의 : 예외 처리가 없으므로 기본이 올바른지 확인해야합니다.
- 재귀 방법은 단 3 줄입니다! (코드 골프 스타일)
분석
다음은 ToString()
내 컴퓨터 의 표준과 비교 한 두 방법의 런타임 분석입니다 .
50 runs of 100000 items per set
Running Time:
Iteration: 00:00:02.3459591 (00:00:00.0469191 avg)
Recursion: 00:00:02.1359731 (00:00:00.0427194 avg)
Standard : 00:00:00.4271253 (00:00:00.0085425 avg)
Ratios:
| Iter | Rec | Std
-----+------+------+-----
Iter | 1.00 | 0.91 | 0.18
Rec | 1.10 | 1.00 | 0.20
Std | 5.49 | 5.00 | 1.00
결과는 반복 및 재귀 방법이 표준 ToString()
방법 보다 5.49 배 및 5.00 배 느리게 실행됨을 나타냅니다 .
분석에 사용한 코드는 다음과 같습니다.
class Program
{
static void Main(string[] args)
{
var r = new Random();
var sw = new System.Diagnostics.Stopwatch();
var loop = new List<long>();
var recr = new List<long>();
var std = new List<long>();
var setSize = 100000;
var runs = 50;
Console.WriteLine("{0} runs of {1} items per set", runs, setSize);
for (int j = 0; j < runs; j++)
{
// create number set
var numbers = Enumerable.Range(1, setSize)
.Select(s => r.Next(int.MinValue,
int.MaxValue))
.ToArray();
// loop
sw.Start();
for (int i = 0; i < setSize; i++)
IntegerToString.Iteration(numbers[i]);
sw.Stop();
loop.Add(sw.ElapsedTicks);
// recursion
sw.Reset();
sw.Start();
for (int i = 0; i < setSize; i++)
IntegerToString.Recursion(numbers[i]);
sw.Stop();
recr.Add(sw.ElapsedTicks);
// standard
sw.Reset();
sw.Start();
for (int i = 0; i < setSize; i++)
numbers[i].ToString();
sw.Stop();
std.Add(sw.ElapsedTicks);
}
Console.WriteLine();
Console.WriteLine("Running Time:");
Console.WriteLine("Iteration: {0} ({1} avg)",
TimeSpan.FromTicks(loop.Sum()),
TimeSpan.FromTicks((int)loop.Average()));
Console.WriteLine("Recursion: {0} ({1} avg)",
TimeSpan.FromTicks(recr.Sum()),
TimeSpan.FromTicks((int)recr.Average()));
Console.WriteLine("Standard : {0} ({1} avg)",
TimeSpan.FromTicks(std.Sum()),
TimeSpan.FromTicks((int)std.Average()));
double lSum = loop.Sum();
double rSum = recr.Sum();
double sSum = std.Sum();
Console.WriteLine();
Console.WriteLine("Ratios: \n" +
" | Iter | Rec | Std \n" +
"-----+------+------+-----");
foreach (var div in new[] { new {n = "Iter", t = lSum},
new {n = "Rec ", t = rSum},
new {n = "Std ", t = sSum}})
Console.WriteLine("{0} | {1:0.00} | {2:0.00} | {3:0.00}",
div.n, lSum / div.t, rSum / div.t, sSum / div.t);
Console.ReadLine();
}
다음과 같이 모든 숫자를 문자로 변환 할 수 있습니다.
byte = (char)(byte)(digit+48)
매직 번호 48
는 문자의 ASCII 값이며 0
ASCII 테이블에서 순차적이므로 숫자를 추가하여 ASCII 테이블에서 해당 값을 가져올 수 있습니다. 모듈러스 연산자를 사용하여 정수의 숫자를 반복적 %
으로 얻을 수 있습니다. pswg에서 일반 구조를 빌리면 얻을 수 있습니다.
public string IntToString(int a) {
var str = string.Empty;
bool isNegative = false;
if (a < 0) {
isNegative = true;
a = -a;
}
do {
str = (char)(byte)((a % 10) + 48) + str;
a /= 10;
} while(a > 0);
return isNegative ? '-' + str : str
}
public static string integerToString(int integerPassedIn)
{
if (integerPassedIn == 0) return "0";
var negative = integerPassedIn < 0;
var res = new List<char>();
while(integerPassedIn != 0)
{
res.Add((char)(48 + Math.Abs(integerPassedIn % 10)));
integerPassedIn /= 10;
}
res.Reverse();
if (negative) res.Insert(0, '-');
return new string(res.ToArray());
}
재귀 :
public static string integerToString(int integerPassedIn)
{
ICollection<char> res = new List<char>();
IntToStringRecusion(integerPassedIn, res);
if (integerPassedIn < 0) res.Add('-');
return new string(res.Reverse().ToArray()).PadLeft(1,'0');
}
static void IntToStringRecusion(int integerPassedIn, ICollection<char> array)
{
if (integerPassedIn == 0) return;
array.Add((char)(48 + Math.Abs(integerPassedIn % 10)));
IntToStringRecusion(integerPassedIn / 10, array);
}
이것이 C ++ 인 경우 :
public string IntToString(int a){
char rc[20];
int x = a;
if(a < 0) x = -x;
char *p = rc + 19;
*p = 0;
do
*--p = (x % 10) | '0';
while(x /= 10);
if(a < 0) *--p = '-';
return string(p);
}
'IT story' 카테고리의 다른 글
"참조"및 "비정의"의 의미 (0) | 2020.12.29 |
---|---|
IntelliJ IDEA가 Maven에서 내 종속성을 업데이트하도록하려면 어떻게해야합니까? (0) | 2020.12.29 |
Android Studio-푸시 실패 : 치명적 : 원격 저장소에서 읽을 수 없음 (0) | 2020.12.29 |
org.hibernate.QueryException : 컬렉션을 역 참조하려는 잘못된 시도 (0) | 2020.12.29 |
-1 ** 2가 JavaScript에서 구문 오류 인 이유는 무엇입니까? (0) | 2020.12.29 |