How to convert Int to String in C # without using ToString ()?

Convert the following int argument to a string without using any built-in toString functions.

public string integerToString(int integerPassedIn){ //Your code here } 

Since everything inherits from Object and Object , it has a ToString() method, how would you convert an int to a string without using your own ToString() method?

The problem with string concatenation is that it will call the ToString() chain until it clicks on it or in the Object class.

How to convert an integer to a string in C # without using ToString() ?

+54
string c # int
Jul 10 '13 at 15:55
source share
10 answers

Something like that:

 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; } 



Update: Here is another version, which is shorter and should work much better, since it eliminates all string concatenations in favor of controlling a fixed-length array. It supports bases up to 16, but it would be easy to extend them to higher bases. This could probably be improved:

 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); } 
+69
Jul 10 '13 at 15:59
source share

This is the solution that I always use:

  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; } 

It looks rather complicated, but has the following features:

  • Radius Support 2 to 36
  • Handles negative values
  • Additional total digits
+21
Jul 10 '13 at 16:05
source share

I'm not sure if operator + concatenation calls ToString , but if that is the case, you can avoid these two by doing something like the following:

 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()); 
+9
Jul 10 '13 at 16:03
source share

An integer is processed from the least significant digit to the most significant. One digit is calculated modulo 10 (% 10), which is then added to the value of the character '0'. This results in one of the characters '0', '1', ..., '9'.

The numbers are pushed onto the stack because they must be presented in reverse order as they are processed (the most significant digit to the least significant digit). Doing this rather than re-adding numbers to a string may be more efficient, but since the number of digits is pretty low, you will need to run a test to be sure.

Processing non-positive numbers requires some additional processing.

 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()); } 

My first version used StringBuilder to create a string from an array of characters, but to get the string "out of" StringBuilder need to call a method called ToString . Obviously, this method does not do any int conversion for the conversion, which for me is the question in question.

But to prove that you can create a string without calling ToString , I switched to using the string constructor, which I would also suggest more efficient than using StringBuilder .

And if ToString in any form is forbidden, you cannot use string concatenation, as shown in the documentation for string.Concat :

The method combines arg0 and arg1, invoking the inconspicuous ToString method arg0 and arg1; it does not add delimiters.

therefore doing s += '1' will call '1'.ToString() . But for me it doesn’t matter. The important part is how you convert int to string.

+5
Jul 10 '13 at 16:05
source share

Draw for a shorter version and using 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; } 

Using the new string(..., 1) constructor is just a way to satisfy the OP requirement so that ToString not called for anything.

+4
Jul 10 '13 at 16:40
source share

you can convert any digit to char like this

 byte = (char)(byte)(digit+48) 

The magic number 48 is an ASCII char 0 value and they are sequential in the ASCII table, so you can just add a digit to get the corresponding value in the ASCII table. and you can get the numbers in integer iterative order using the module operator % Borrowing the general structure from pswg, you will get

 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 } 
+3
Jul 10 '13 at 16:08
source share

Here are my guidelines for using iteration and recursion with runtime analysis.

 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]; } } 


Key points

  • Handles base 2 to 36 ( CAVEAT:, you will need to make sure your base is correct, as exception handling does not exist.
  • The recursion method lasts only 3 lines! (code golf style)

Analysis

The following is a run-time analysis of both methods compared to the standard ToString() on my computer.

 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 

The results show that iteration and recursion methods run 5.49 and 5.00 times slower than the standard ToString() method.

And here is the code I used for analysis:

 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(); } 
+3
Jul 18 '13 at 14:25
source share
  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()); } 
+1
Jul 10 '13 at 19:02
source share

If it is C ++, then:

 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); } 
0
Jul 10 '13 at 16:12
source share

recursion:

  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); } 
0
Jul 10
source share



All Articles