Iterieren durch Ziffern in Ganzzahlen in C

Lesezeit: 5 Minuten

Benutzeravatar von topgun
Top Gun

Ich habe eine Ganzzahl wie 1191223 und möchte über die Ziffern iterieren. Ich bin mir nicht sicher, wie man das in C macht. Gibt es eine einfache Möglichkeit, das zu machen?

Danke.

Benutzeravatar von BRPocock
BRPocock

Vorwärts oder rückwärts?

Unter der Annahme einer positiven ganzen Zahl:

  unsigned int n = 1191223;

  while (n != 0) {
       doSomething (n % 10);
       n /= 10;
  }

…wird vom Kleinsten zum Größten funktionieren, oder…

BEARBEITEN Ich hatte diese nicht funktionierende Lösung, die ich hier hatte, völlig vergessen. Beachten Sie, dass Very Smart People™ anscheinend konsistent die kleinste bis größte Iteration verwendet (sowohl Linux-Kernel als auch GLibCs). printfzum Beispiel einfach rückwärts iterieren), aber hier ist eine miese Möglichkeit, es zu tun, wenn Sie es wirklich nicht verwenden möchten snprintf aus irgendeinem Grund…

int left_to_right (unsigned int n) {
  unsigned int digit = 0;

  if (0 == n) {
    doSomething (0);
  } else {
    digit = pow(10, 1.0+ floor(log10(n)));
    while (digit /= 10) {
      doSomething ( (n / digit) % 10 );
    }
  }
}

Ich gehe davon aus, dass es sehr dumm ist anzunehmen, dass Sie das getan haben log10 Und pow aber nicht snprintfalso wäre ein alternativer Plan

int left_to_right_fixed_max (unsigned int n) {
  unsigned int digit = 1000000000; /* make this very big */
  unsigned int n10 = 10 * n;

  if (0 == n) {
    doSomething (0);
  } else {
    while (digit > n10) { digit /= 10; }
    while (digit /= 10) {
      doSomething ( (n / digit) % 10 );
    }
  }
}

… oder, wenn Sie wirklich keine Hardware zum Multiplizieren/Dividieren haben, können Sie auf die Verwendung einer Zehnerpotenzentabelle zurückgreifen.

int left_to_right (unsigned int n) {
  static const unsigned int digit [] = 
    { 1,
      10,
      100,
      1000,
      10000,
      100000,
      1000000,
      10000000,
      100000000,
      1000000000 /* make this very big */
    };
  static const unsigned char max_place = 10;
  /* length of the above array */

  unsigned char decimal;
  unsigned char place;
  unsigned char significant = 0; /* boolean */

  if (0 == n) {
    doSomething (0);
  } else {
    place = max_place;
    while (place--) {
      decimal = 0;
      while (n >= digit[place]) {
        decimal++;
        n -= digit[place];
      }
      if (decimal | significant) {
        doSomething (decimal);
        significant |= decimal;
      }
    }
  }
}

…was ich übernommen habe http://www.piclist.com/techref/sprache/ccpp/convertbase.htm in eine etwas allgemeinere Version.

  • Ihre erste Version ist von rückwärts nach vorwärts, wie Sie die Ziffern von vorwärts nach oben erhalten, z. B. 1234 > 1 2 3 und dann 4 statt 4 3 2 und 1. Danke

    – Top Gun

    29. Dezember 2011 um 21:34

  • Die Iteration funktioniert gut für vorwärts, aber es werden Nullen übersprungen. Irgendeine Idee, warum das so ist?

    – Top Gun

    29. Dezember 2011 um 22:09

  • Wow, ich bin mir sicher, dass ich ein dummes Versehen begangen habe – ich werde heute Abend einen Blick darauf werfen. 🙁 Ich habe es dummerweise nur mit „1191123!“ versucht.

    – BRPocock

    30. Dezember 2011 um 0:29

  • Nur neugierig, haben Sie das zufällig mit Nullen gelöst? Ich habe dies viele Male wiederholt und bin mir nicht sicher, was dazu führt, dass 0 eliminiert wird.

    – Top Gun

    30. Dezember 2011 um 15:15 Uhr

Benutzeravatar von moooeeeep
moooeeeep

Im Folgenden gehe ich davon aus, dass Sie Dezimalstellen (Basis 10) meinen. Wahrscheinlich können Sie die Lösungen auch an andere Zahlensysteme anpassen, indem Sie das ersetzen 10S.

Beachten Sie, dass die Modulo-Operation in Bezug auf negative Operanden eine schwierige Sache ist. Deshalb habe ich den Datentyp als vorzeichenlose Ganzzahl gewählt.

Wenn Sie zuerst die niedrigstwertige Ziffer verarbeiten möchten, können Sie den folgenden ungetesteten Ansatz ausprobieren:

uint32_t n = 1191223;
do {
  uint32_t digit = n%10;
  // do something with digit
}
while (n/=10);

Wenn Sie die Ziffern lieber ausgehend von der höchstwertigen Ziffer durchgehen möchten, können Sie versuchen, den folgenden ungetesteten Code anzupassen:

uint32_t n = 1191223;
#define MAX_DIGITS 10 // log10((double)UINT32_MAX)+1
uint32_t div = pow(10, MAX_DIGITS);

// skip the leading zero digits
while ( div && !(n/div) ) div/=10;
if ( !div ) div = 10; // allow n being zero

do {
  uint32_t digit = (n/div)%10;
  // do something with digit
}
while (div/=10);

Sie möchten über Ziffern zur Basis 10 iterieren, aber für eine Ganzzahl gibt es kein Konzept für arabische Notation und Ziffern. Konvertieren Sie es zuerst in einen String:

int i = 1191223;
char buffer[16];
char *j;
snprintf(buffer, 16, "%i", i);
for ( j = buffer; *j; ++j ) { /* digit is in *j - '0' */ }

  • Thiton Ich bin nur neugierig, was du hier mit *j – ‘0’ meinst. Vermeidet es die erste 0? Ich habe es mit der Ziffer 0191223 versucht und die Länge stimmt nicht. Irgendwelche Vorschläge?

    – Top Gun

    29. Dezember 2011 um 19:58

  • @kforkarim wahrscheinlich ist das das char2int Wandlung: uint32_t digit = *j-'0';. Stellen Sie sicher, dass Sie damit umgehen '-' Die Zeichenfolge kann enthalten.

    – moooeeeep

    29. Dezember 2011 um 20:06 Uhr


Sie können verwenden sprintf() um es in ein umzuwandeln char Array erstellen und es dann wie folgt durchlaufen (ungetestet, nur um Ihnen den Einstieg zu erleichtern):

int a = 1191223;
char arr[16];
int rc = sprintf(arr, "%d", a);

if (rc < 0) {
    // error
}

for (int i = 0; i < rc; i++) {
    printf("digit %d = %d\n", i, arr[i]);
}

void access_digits(int n)
{
        int digit;
        if (n < 0) n = -n;
        do {
                digit = n % 10;
                /* Here you can do whatever you
                   want to do with the digit */
        } while ((n/=10) > 0);
}

Etwas wie das:

char data[128];
int digits = 1191223;
sprintf(data, "%d", digits);
int length = strlen(data);
for(int i = 0; i < length; i++) {
   // iterate through each character representing a digit
}

Beachten Sie Folgendes: Wenn Sie eine Oktalzahl wie verwenden 0100 Sie müssen auch das ändern sprintf(data, "%d", digits); Zu sprintf(data, "%o", digits);.

Für meine Zwecke hat der folgende Funktionscode den Zweck erfüllt.

Eine ganzzahlige Variable haben the_integerund eine ganzzahlige Variable sum_of_digits initialisiert. (Zeile 1) Sie könnten Folgendes tun:

1) Konvertieren Sie die Ganzzahlvariable mithilfe von in eine Variable vom Typ String std::to_string(int) Funktion.

2) Iterieren Sie die Zeichen der resultierenden Zeichenfolge. for(char& c: str::to_string(the_integer))

3) Um die Zeichen wieder in Ganzzahlen umzuwandeln, verwenden Sie c -‘0’ . Schauen Sie sich für diese Lösung die Diskussion in (Char in int in C und C++ konvertieren) an.

4) .. und die Ziffern addieren: sum_of_digits += c-‘0’

*) Anschließend können Sie Ihre Variablen ausdrucken: Zeilen 3 und 4.

int the_integer = 123456789; int sum_of_digits;

for (char& c: std::to_string(the_integer)) {sum_of_digits += c-'0';}

std::cout << "Integer: " << the_integer << std::endl;
std::cout << "Sum of Digits << sum_of_digits << std::endl;

Beachten Sie, dass std::to_string() enthält einige Hinweise. Bitte konsultieren Sie die C++-Referenzen, um festzustellen, ob der Code für Ihre Zwecke noch relevant ist.

  • Bitte beschreiben Sie in Ihrer Antwort, was Ihr Code tut.

    – Strg S

    20. März 2019 um 17:29 Uhr

1452370cookie-checkIterieren durch Ziffern in Ganzzahlen in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy