2010-07-28 2 views
5

Mio fratellino di quindici anni sta iniziando la programmazione, e ha scritto un piccolo programma pulito che emette tutte le combinazioni di lettere e numeri di sei o meno cifre. Il suo codice era un ciclo annidato a sestupla che aggiornava gli elementi di un array di char a sei livelli. Sembrava male, ma era certamente veloce! Gli ho mostrato come fare un conteggio semplice e convertire quei numeri in base 36.Come posso contare su una base numerica diversa in C++?

Il problema più grande è che il mio codice era molto più lento del suo, a causa della divisione che stavo facendo. C'è un modo in cui posso semplicemente assumere la base 36 e produrre un conteggio da 1 a 36^6?

Idealmente, sto cercando di fare qualcosa di simile

[base 36] 
for(int i = 0; i < 1000000; i++) 
    SaveForLaterFileOutput(i); 
+6

Si sta confondendo il valore con la presentazione. Il conteggio puro non è un concetto a cui può essere assegnata una radice. Una versione refactored la soluzione di tuo fratello potrebbe essere il migliore dei due! –

+0

Non esiste un costrutto base36 incorporato nella lingua. Tuttavia, non hai bisogno della divisione per fare ciò che vuoi. – driis

risposta

3

Prova questo:

char buffer[1024]; 
for(int i = 0; i < 1000000; i++) 
     cout << itoa (i, buffer, 36); 

Qui è senza itoa (se non lo avete)

cout << setbase (36); 
for(int i = 0; i < 1000000; i++) 
     cout << i << endl; 
cout << setbase (10); // if you intend to keep using cout 

+2

'itoa' non è nello standard e non tutte le librerie C++ lo includono. –

+0

Questo sicuramente fa questo trucco. Grazie. – Jeffrey

+0

Aggiornato per avere una risposta senza itoa (grazie @ Konrad Rudolph) –

1

per convertire un numero da base 36: fare un accumulatore e partire da un grado sufficientemente elevato, per esempio 36^6. Se l'accumulatore più quel numero è inferiore al tuo numero, aggiungilo all'accumulatore e ripeti per lo stesso grado (il conteggio di questo è il valore della cifra), se è maggiore, buttalo via. Ripeti per gradi più bassi finché non arrivi a 36^0. Tieni traccia del conteggio per ogni grado, e questo è il tuo numero nella base 36.

per stamparlo in modo significativo, fare qualcos'altro.

1

Tutti i numeri utilizzati nei calcoli sono in base 2 Qualsiasi altro numero che vedi è solo un'illusione su come viene stampato. Quindi il tuo SaveForLaterOutput è inutile.

La funzione libreria itoa() (che si traduce in "intero in ASCII") (in questi giorni è stata sostituita dalla funzione protetta _itoa_s()) consente di specificare la base durante la preparazione per l'output.

+0

Non esiste una cosa come "2" in binario, quindi tecnicamente tutti i calcoli sono in binario di base 10 (da non confondere con il numero dieci che a noi umani piace tanto). – fredoverflow

+0

Ci sono solo 10 tipi di persone nel mondo: quelli che comprendono il binario e quelli che non lo fanno. –

+0

Ci sono 10 tipi di persone: quelli che comprendono il ternario, quelli che non lo fanno e quelli che lo scambiano per il binario;) –

2

È possibile che tuo fratello aggiorni il suo array di 6 elementi senza bisogno di 6 cicli nidificati. Modificando la funzione increment di seguito, si può contare in qualsiasi "base" che si sceglie:

#include <algorithm> 
#include <iostream> 

#define NUM_CHARS 6 

// assuming ASCII 
// advances through a chosen sequence 0 .. 9, a .. z 
// or returns -1 on overflow 
char increment(char &c) { 
    if (c == 'z') return -1; 
    if (c == '9') { c = 'a'; return c; } 
    return ++c; 
} 

int main() { 
    char source[NUM_CHARS+1] = {0}; 
    std::fill_n(&source[0], NUM_CHARS, '0'); 
    while (true) { 
     std::cout << source << "\n"; 
     int idx = NUM_CHARS; 
     // increment and test for overflow 
     while (increment(source[--idx]) == -1) { 
      // overflow occurred: carry the 1 
      source[idx] = '0'; 
      if (idx == 0) return 0; 
     } 
    } 
} 

Non ho disturbato con la parte "o meno" del problema: ma che hai fatto con 6 cicli probabilmente lavorerò anche con questa tecnica. A rigor di termini, questo è enumerare le combinazioni, che è quasi ma non esattamente la stessa cosa del conteggio.