2011-01-02 19 views
11

Ich hatte einen int „123456“ jeden Wert davon auf ein Int [], und ich habe bereits eine Lösung zu teilen, aber ich weiß nicht, ist es eine bessere Art und Weise: Meine Lösung war:Integer Integer Array C#

public static int[] intToArray(int num){ 
    String holder = num.ToString(); 
    int[] numbers = new int[Holder.ToString().Length]; 
    for(int i=0;i<numbers.length;i++){ 
     numbers[i] = Convert.toInt32(holder.CharAt(i)); 
    } 
    return numbers; 
} 
+0

meine Antwort pal Überprüfen Sie, es ist der einfachste Weg, wenn Sie 'LINQ' –

+0

@Hans Passant hörte, bin ich ziemlich sicher, dass über die Array-Länge weil die längste Zahl, die ich habe, 999996 sein kann, also 6 ist die höchste Länge eines Arrays, und auch Leistung ist kein Problem wegen dieser Anzahl Beschränkung. – Burimi

Antwort

10

Ich glaube, das wird besser sein als die Konvertierung hin und her. Im Gegensatz zu JBSnorro's Antwort kehre ich nach der Konvertierung in ein Array um und vermeide daher IEnumerable, was meiner Meinung nach zu einem etwas schnelleren Code beitragen wird. Diese Methode funktioniert für nicht negative Zahlen, daher gibt 0new int[1] { 0 } zurück.

Wenn es für negative Zahlen funktionieren sollte, könnten Sie eine n = Math.Abs(n) tun, aber ich denke nicht, dass das Sinn macht.

Darüber hinaus könnte ich, wenn es performanter sein sollte, das endgültige Array erstellen, indem ich eine binäre Suche wie eine Kombination von if-Anweisungen zur Bestimmung der Anzahl der Ziffern mache.

public static int[] digitArr(int n) 
{ 
    if (n == 0) return new int[1] { 0 }; 

    var digits = new List<int>(); 

    for (; n != 0; n /= 10) 
     digits.Add(n % 10); 

    var arr = digits.ToArray(); 
    Array.Reverse(arr); 
    return arr; 
} 
+0

Ich hatte darüber nachgedacht, ob ich zuerst ein Array erstellen oder die Liste zuerst umkehren wollte. Aber ich dachte, warum mache ich sie nicht gleichzeitig (mit den Erweiterungsmethoden IEnumerable). Mir ist klar, dass dies nur eine Mikrooptimalisierung ist, da die Liste nicht lang sein wird. Das andere (wichtigere) Argument, das mir einfiel, war Eleganz. – JBSnorro

+0

Ich denke, dass deine Punkte vollkommen gültig sind :) Ich wollte nur, dass Burim Shala weiß, warum ich das gemacht habe und warum ich denke, dass es besser ist. Ich sehe, Sie haben Ihre Antwort aktualisiert, die ist nett :) –

+0

Ein besserer Ansatz zu diesem ist wirklich die Anzahl der Ziffern zuerst zu finden (kann schnell erledigt werden) und dann das Array zu konstruieren. Dies würde "List" und "Reverse" vermeiden. –

5

Die Konvertierung von int in String und zurück ist wahrscheinlich nicht so schnell. Ich würde folgendes verwenden:

public static int[] ToDigitArray(int i) 
{ 
    List<int> result = new List<int>(); 
    while (i != 0) 
    { 
     result.Add(i % 10); 
     i /= 10; 
    } 
    return result.Reverse().ToArray(); 
} 

Ich muss beachten, dass dies nur für rein positive ganze Zahlen funktioniert.

EDIT:

kam ich mit einer Alternative auf. Wenn Leistung wirklich ein Problem ist, wird dies wahrscheinlich schneller sein, obwohl Sie nur sicher sein können, indem Sie es für Ihre spezifische Verwendung und Anwendung selbst überprüfen.

public static int[] ToDigitArray(int n) 
{ 
    int[] result = new int[GetDigitArrayLength(n)]; 
    for (int i = 0; i < result.Length; i++) 
    { 
     result[result.Length - i - 1] = n % 10; 
     n /= 10; 
    } 
    return result; 
} 
private static int GetDigitArrayLength(int n) 
{ 
    if (n == 0) 
     return 1; 
    return 1 + (int)Math.Log10(n); 
} 

Dies funktioniert, wenn n nichtnegativ ist.

+1

Es funktioniert auch nicht für null, es gibt ein leeres Array anstelle eines Arrays mit einer Ziffer zurück. – Guffa

+0

@Guffa, das habe ich schon gesagt. Ich sagte, es funktioniert nur für positive Ganzzahlen, und Null ist nicht positiv. In der Tat habe ich gesagt, es funktioniert nur für Strictly positive ganze Zahlen, also mit dem Wort "strikt" habe ich explizit festgestellt, dass Fall i = 0 nicht funktioniert. – JBSnorro

+0

Ändern Sie die Funktion GetDigitArrayLength zu int digits = 0; do { n/= 10; Ziffern ++; } while (n! = 0); Ziffern zurückgeben; – TheJackal

1

Sie können das tun, ohne es in einen String konvertiert und zurück:

public static int[] intToArray(int num) { 
    List<int> numbers = new List<int>(); 
    do { 
    numbers.Insert(0, num % 10); 
    num /= 10; 
    } while (num > 0); 
    return numbers.ToArray(); 
} 

Es funktioniert nur für positive Werte, natürlich, aber Ihre ursprünglichen Code auch diese Einschränkung haben.

16

Eine einfache Lösung von LINQ

int[] result = yourInt.ToString().Select(o=> Convert.ToInt32(o)).ToArray() 
+0

+1 Es ist interessant zu bemerken, dass dieser Ansatz nur die nette nebenwirkungsfreie Implementierung des Codes in der Post ist: viele übliche imperative Operationen über homogene Listen haben triviale und saubere "funktionale" Gegenstücke. –

+0

Edge-Cases (zB "-12") sollten dennoch berücksichtigt werden - auch wenn es sich nur um eine dokumentierte Einschränkung der Funktionsdomäne handelt. Der ursprüngliche Post macht diese Einschränkung nicht selbst. –

1

ich es so tun würde:

var result = new List<int>(); 
    while (num != 0) { 
     result.Insert(0, num % 10); 
     num = num/10; 
    } 
    return result.ToArray(); 

Etwas weniger performant, aber möglicherweise ist eleganter:

return num.ToString.Select(c => Convert.ToInt32(c.ToString())).ToArray(); 

Beachten Sie, dass diese beiden re 1, 2, 3, 4, 5, 6 anstelle von 49, 50, 51, 52, 53, 54 (d.h. die Byte-Codes für die Zeichen "1", "2", "3", "4", "5", "6"), wie es Ihr Code tut. Ich nehme an, das ist die eigentliche Absicht?

10
int[] outarry = Array.ConvertAll(num.ToString().ToArray(), x=>(int)x); 

aber wenn Sie wollen, dass es zu 1,2,3,4,5 konvertieren:

int[] outarry = Array.ConvertAll(num.ToString().ToArray(), x=>(int)x - 48); 
+0

Es gibt kein ToCharArray auf int. Die Eingabe ist int nicht Zeichenfolge –

+0

@Rune FS, was? Halter ist String, ich bekomme es von 'OP's Probe. –

+0

Konnte nicht aus Ihrer Antwort sehen, dass war nur ein Teil der Lösung, die mich verwirrt –

1
string DecimalToBase(int iDec, int numbase) 
     { 
      string strBin = ""; 
      int[] result = new int[32]; 
      int MaxBit = 32; 
      for(; iDec > 0; iDec/=numbase) 
      { 
       int rem = iDec % numbase; 
        result[--MaxBit] = rem; 
      } 
      for (int i=0;i<result.Length;i++) 
       if ((int)result.GetValue(i) >= base10) 
        strBin += cHexa[(int)result.GetValue(i)%base10]; 
       else 
        strBin += result.GetValue(i); 
      strBin = strBin.TrimStart(new char[] {'0'}); 
      return strBin; 
     } 
     int BaseToDecimal(string sBase, int numbase) 
     { 
      int dec = 0; 
      int b; 
      int iProduct=1; 
      string sHexa = ""; 
      if (numbase > base10) 
       for (int i=0;i<cHexa.Length;i++) 
        sHexa += cHexa.GetValue(i).ToString(); 
      for(int i=sBase.Length-1; i>=0; i--,iProduct *= numbase) 
      { 
       string sValue = sBase[i].ToString(); 
       if (sValue.IndexOfAny(cHexa) >=0) 
        b=iHexaNumeric[sHexa.IndexOf(sBase[i])]; 
       else 
        b= (int) sBase[i] - asciiDiff; 
       dec += (b * iProduct); 
      } 
      return dec; 
     } 
+3

Können Sie diesen Code erklären, damit jemand weiß, wie er auf die gestellte Frage reagiert? –

1

Ich hatte ähnliche Anforderung .. Ich nahm von vielen guten Ideen und fügte hinzu: Ein paar fehlende Teile .. wo viele Leute nicht mit Null oder negativen Werten umgehen.das ist, was ich kam mit:

public static int[] DigitsFromInteger(int n) 
    { 
     int _n = Math.Abs(n); 
     int length = ((int)Math.Log10(_n > 0 ? _n : 1)) + 1; 
     int[] digits = new int[length]; 
     for (int i = 0; i < length; i++) 
     { 
      digits[(length - i) - 1] = _n % 10 * ((i == (length - 1) && n < 0) ? -1 : 1); 
      _n /= 10; 
     } 
     return digits; 
    } 

Ich denke, das ist ziemlich sauber .. obwohl es wahr ist, dass wir eine bedingte Kontrolle und mehrere Fremd Berechnungen mit jeder Iteration tun .. während ich denke, sie sind in diesem Fall nominal, könnten Sie einen Schritt weiter auf diese Weise optimieren:

public static int[] DigitsFromInteger(int n) 
    { 
     int _n = Math.Abs(n); 
     int length = ((int)Math.Log10(_n > 0 ? _n : 1)) + 1; 
     int[] digits = new int[length]; 
     for (int i = 0; i < length; i++) 
     { 
      //digits[(length - i) - 1] = _n % 10 * ((i == (length - 1) && n < 0) ? -1 : 1); 
      digits[(length - i) - 1] = _n % 10; 
      _n /= 10; 
     } 
     if (n < 0) 
      digits[0] *= -1; 
     return digits; 
    }