Domanda

Ho letto di recente una domanda colloquio di lavoro di esempio:

  

Scrivi una funzione per convertire un intero   in una stringa. Si supponga non si dispone di   accesso alle funzioni di libreria cioè,   itoa (), ecc ...

Come si va su questo?

È stato utile?

Soluzione

veloce pugnalata a lui: (modificato per i numeri negativi maniglia)

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

Altri suggerimenti

L'algoritmo è facile da vedere in inglese.

Dato un numero intero, ad esempio 123

  1. dividere per 10 => 123/10. Cedevole, result = 12 e il resto = 3

  2. add 30h al 3 e spingere sulla pila (aggiungendo 30h convertirà 3 alla rappresentazione ASCII)

  3. ripetere il passo 1 fino risultato <10

  4. add 30h al risultato e memorizzare sulla pila

  5. lo stack contiene il numero in ordine di | 1 | 2 | 3 | ...

Uno sguardo sul web per itoa applicazione vi darà buoni esempi. Qui è uno, evitando di invertire la stringa alla fine. Esso si basa su un buffer statico, quindi attenzione se si riutilizza per diversi valori.

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

}

vorrei tenere presente che tutti i personaggi sono cifre in ordine crescente all'interno del set di caratteri ASCII e non hanno altri personaggi tra di loro.

Vorrei anche usare gli operatori / e the% ripetutamente.

Come potrei fare per ottenere la memoria per la stringa dipenderebbe informazioni che non hai dato.

Supponendo che è in decimale, quindi in questo modo:

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

Un'implementazione della funzione itoa() sembra un compito facile, ma in realtà si deve prendere cura di molti aspetti che sono legati alle vostre esigenze. Credo che nell'intervista si sono tenuti a dare alcuni dettagli circa la strada per la soluzione piuttosto che la copia di una soluzione che può essere trovato in Google ( http://en.wikipedia.org/wiki/Itoa )

Ecco alcune domande che potete desiderare per chiedere a te stesso o l'intervistatore:

  • Dove dovrebbe essere collocato la stringa (malloced? Passò da parte dell'utente? Variabile statica?)
  • dovrei numeri di assistenza firmato?
  • dovrei sostenere in virgola mobile?
  • dovrei supporto altre basi piuttosto che 10?
  • bisogno abbiamo controllo di input?
  • è la stringa di uscita limitata in legth?

E così via.

  

Converti numero intero in stringa senza accesso alle librerie

Converti la cifra meno significativa di un personaggio e poi procedere alla cifre più significative.


Normalmente mi piacerebbe spostare la risultante stringa al suo posto, ma la ricorsione permette di saltare questo passo con un codice stretto.

Utilizzando neg_a in myitoa_helper() evita comportamento non definito con 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));
}

il codice & uscita di test

#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>

Ecco un approccio semplice, ma ho il sospetto, se si attiva questa in così com'è senza capire e parafrasando, il vostro insegnante saprà appena copiato dalla rete:

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

Vari miglioramenti sono possibili, soprattutto se si desidera supportare in modo efficiente larger-than-parola intera dimensioni fino a intmax_t. Lascio a voi di capire il modo in cui queste funzioni sono destinati ad essere chiamato.

Un po 'più a lungo rispetto alla soluzione:

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

Reverse:

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

E anche se la decisione davolno lungo qui ci sono alcune caratteristiche utili per i principianti. Spero che sarà utile.

Il più veloce è il migliore?

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

Se si desidera eseguire il debug, è possibile dividere le condizioni (istruzioni) in
linee di codice all'interno {} il tempo ambiti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top