Frage

Vor kurzem las ich eine Probe Vorstellungsgespräch Frage:

Schreiben Sie eine Funktion für eine ganze Zahl konvertieren in einen String. Angenommen, Sie haben nicht Zugang zu Bibliotheksfunktionen d.h. itoa (), etc ...

Wie würden Sie vorgehen?

War es hilfreich?

Lösung

schnell Stich an sie: (editiert Griff negative Zahlen)

int n = INT_MIN;
char buffer[50];
int i = 0;

bool isNeg = n<0;

unsigned int n1 = isNeg ? -n : n;

while(n1!=0)
{
    buffer[i++] = n1%10+'0';
    n1=n1/10;
}

if(isNeg)
    buffer[i++] = '-';

buffer[i] = '\0';

for(int t = 0; t < i/2; t++)
{
    buffer[t] ^= buffer[i-t-1];
    buffer[i-t-1] ^= buffer[t];
    buffer[t] ^= buffer[i-t-1];
}

if(n == 0)
{
    buffer[0] = '0';
    buffer[1] = '\0';
}   

printf(buffer);

Andere Tipps

Der Algorithmus ist einfach in Englisch zu sehen.

Da eine ganze Zahl, z.B. 123

  1. Division durch 10 => 123/10. Nachgebend, zur Folge hat und den Rest = 12 = 3

  2. Add 30h bis 3 und Druck auf Stapel (Hinzufügen von 30h 3 in ASCII-Darstellung konvertiert)

  3. Wiederholen Sie Schritt 1 bis Ergebnis <10

  4. Add 30h zu führen und zu speichern auf Stapel

  5. der Stapel enthält die Nummer in der Reihenfolge der | 1 | 2 | 3 | ...

Ein Blick auf das Web für itoa Implementierung finden Sie gute Beispiele. Hier ist eine, die Vermeidung der Zeichenfolge am Ende zu umkehren. Es stützt sich auf einem statischen Puffer, so vorsichtig sein, wenn Sie es für verschiedene Werte wiederverwendet werden.

char* itoa(int val, int base){

    static char buf[32] = {0};

    int i = 30;

    for(; val && i ; --i, val /= base)

        buf[i] = "0123456789abcdef"[val % base];

    return &buf[i+1];

}

Ich würde bedenken Sie, dass alle die Ziffer Zeichen sind, um innerhalb des ASCII-Zeichensatz zu erhöhen und haben keine andere Zeichen zwischen ihnen.

Ich würde auch immer wieder die / und the% Operatoren verwenden.

Wie würde ich gehen über den Speicher für die Zeichenfolge bekommen würde auf Informationen ab, die Sie nicht gegeben haben.

Unter der Annahme, es ist in dezimal, dann wie folgt aus:

   int num = ...;
   char res[MaxDigitCount];
   int len = 0;
   for(; num > 0; ++len)
   {
      res[len] = num%10+'0';
      num/=10; 
   }
   res[len] = 0; //null-terminating

   //now we need to reverse res
   for(int i = 0; i < len/2; ++i)
   {
       char c = res[i]; res[i] = res[len-i-1]; res[len-i-1] = c;
   }   

Eine Implementierung von itoa() Funktion scheint wie eine einfache Aufgabe, aber eigentlich haben Sie kümmern sich um viele Aspekte zu nehmen, die auf Ihre genauen Bedürfnisse verwandt sind. Ich denke, dass in dem Interview, das Sie erwarten sind einige Details über Ihren Weg in die Lösung zu geben, anstatt eine Lösung zu kopieren, die in Google gefunden werden können ( http://en.wikipedia.org/wiki/Itoa )

Hier sind einige Fragen, die Sie sich selbst oder der Interviewer fragen mögen:

  • Wo sollte die Zeichenfolge gesucht werden (malloced? Geleitet durch den Anwender? Statische Variablen?)
  • Should I Unterstützung unterzeichnet Zahlen?
  • Should i Punkt unterstützen floating?
  • Sollte ich Unterstützung andere Basen eher dann 10?
  • Müssen wir jede Eingabe Prüfung?
  • Ist die Ausgabezeichenfolge in legth beschränkt?

Und so weiter.

Konvertieren Integer in String ohne Zugang zu Bibliotheken

Konvertieren Sie die niedrigstwertige Ziffer auf ein Zeichen und dann zu höherwertigen Stellen gehen.


Normalerweise würde ich verschieben, um den resultierenden string in Position, doch Rekursion erlaubt mit einigem engen Code diesen Schritt überspringen.

Mit neg_a in myitoa_helper() vermeidet undefiniertes Verhalten mit INT_MIN.

// Return character one past end of character digits.
static char *myitoa_helper(char *dest, int neg_a) {
  if (neg_a <= -10) {
    dest = myitoa_helper(dest, neg_a / 10);
  }
  *dest = (char) ('0' - neg_a % 10);
  return dest + 1;
}

char *myitoa(char *dest, int a) {
  if (a >= 0) {
    *myitoa_helper(dest, -a) = '\0';
  } else {
    *dest = '-';
    *myitoa_helper(dest + 1, a) = '\0';
  }
  return dest;
}

void myitoa_test(int a) {
  char s[100];
  memset(s, 'x', sizeof s);
  printf("%11d <%s>\n", a, myitoa(s, a));
}

Prüfregeln & Ausgabe

#include "limits.h"
#include "stdio.h"

int main(void) {
  const int a[] = {INT_MIN, INT_MIN + 1, -42, -1, 0, 1, 2, 9, 10, 99, 100,
      INT_MAX - 1, INT_MAX};
  for (unsigned i = 0; i < sizeof a / sizeof a[0]; i++) {
    myitoa_test(a[i]);
  }
  return 0;
}

-2147483648 <-2147483648>
-2147483647 <-2147483647>
        -42 <-42>
         -1 <-1>
          0 <0>
          1 <1>
          2 <2>
          9 <9>
         10 <10>
         99 <99>
        100 <100>
 2147483646 <2147483646>
 2147483647 <2147483647>

Hier ist ein einfacher Ansatz, aber ich vermute, wenn Sie das einschalten in, wie sie ist, ohne zu verstehen und zu paraphrasieren es, Ihr Lehrer wissen Sie nur aus dem Netz kopiert:

char *pru(unsigned x, char *eob)
{
    do { *--eob = x%10; } while (x/=10);
    return eob;
}

char *pri(int x, char *eob)
{
    eob = fmtu(x<0?-x:x, eob);
    if (x<0) *--eob='-';
    return eob;
}

Verschiedene Verbesserungen sind möglich, vor allem, wenn Sie effizient unterstützen wollen larger-than-Wort integer zu intmax_t Größen auf. Ich werde überlasse es Ihnen, um herauszufinden, wie diese Funktionen bestimmt sind, genannt zu werden.

Etwas länger als die Lösung:

static char*
itoa(int n, char s[])
{
    int i, sign;

    if ((sign = n) < 0)  
        n = -n;        

    i = 0;

    do 
    {      
        s[i++] = n % 10 + '0';  
    } while ((n /= 10) > 0);   

    if (sign < 0)
        s[i++] = '-';

    s[i] = '\0';
    reverse(s);

    return s;
} 

Rückseite:

int strlen(const char* str)
{
   int i = 0;
   while (str != '\0')
   {
       i++;
       str++;
   }

   return i;
}

static void
reverse(char s[])
{
    int i, j;
    char c;

    for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}

Und obwohl die Entscheidung davolno lange hier sind einige nützliche Funktionen für Anfänger. Ich hoffe, Sie nützlich sein wird.

Je schneller, desto besser?

unsigned int findDigits(long long x)
{
    int i = 1;
    while ((x /= 10) && ++i);
    return i;
}
// return the number of digits in x.
unsigned int digits(long long x)
{
    x < 0 ? x = -x : 0;
    return x < 10 ? 1 :
        x < 100 ? 2 :
        x < 1000 ? 3 :
        x < 10000 ? 4 :
        x < 100000 ? 5 :
        x < 1000000 ? 6 :
        x < 10000000 ? 7 :
        x < 100000000 ? 8 :
        x < 1000000000 ? 9 :
        x < 10000000000 ? 10 : findDigits(x);
}


char tochar(unsigned short from)
{
    return from == 0 ? '0' :
        from == 1 ? '1' : from == 1 ? '1' : from == 2 ? '2' :
        from == 3 ? '3' : from == 4 ? '4' : from == 5 ? '5' :
        from == 6 ? '6' : from == 7 ? '7' : from == 8 ? '8' :
        from == 9 ? '9' : '\0';
}

char * tostring(long long from)
{
    unsigned char negative = from < 0;
    unsigned int i = digits(from);
    char* to = (char*)calloc(1, i + negative);
    if (negative && (*to = '-') & (from = -from) & i++);
    *(to + i) = 0;
    while ((i>0+negative) && (*(to + (--i)) = tochar(((from) % 10))) | (from /= 10));
    return to;
}

Wenn Sie debuggen möchten, können Sie die Bedingungen aufgespalten (Anweisungen) in
Codezeilen innerhalb der {} Bereiche während.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top