Zählen der Anzahl der Vorkommen eines Zeichens in einer Zeichenfolge in C

Lesezeit: 5 Minuten

Mikes Benutzeravatar
Mike

Ich habe die Schnur str

char *str = "100.10b.100.100";

Ich möchte die Vorkommen von zählen '.' in str, vorzugsweise ein Einzeiler. (möglichst keine Schleifen)

Mein Ansatz wäre der Standard strchr:

  int i = 0;
  char *pch=strchr(str,'.');
  while (pch!=NULL) {
    i++;
    pch=strchr(pch+1,'.');
  }

  • Zum Mantrabeutel – was hast du probiert? was geht nicht? …….

    – KevinDTimm

    20. November 2010 um 23:14 Uhr

  • @KevinDTimm: Ich habe meinen Ansatz gepostet.

    – Mike

    20. November 2010 um 23:15 Uhr

  • Wie Tvanfosson betonte, können Sie es mit Rekursion machen, und vielleicht wollte Ihr Lehrer das von Ihnen sehen, aber es ist eine absolut idiotische Art, es zu tun. Es wird dazu führen Paketüberfluss für ausreichend große Saiten … und nicht die gute Art von SO, die Ihre Hausaufgaben für Sie erledigt, die schlechte Art! 😉

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 1:00 Uhr

R.. GitHub STOP HELPING ICEs Benutzeravatar
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN

So würde ich es machen (minimale Anzahl von Variablen erforderlich):

for (i=0; s[i]; s[i]=='.' ? i++ : *s++);

  • Nein, ich steigere auch s oder i je nachdem ob s[i] ist ein '.' oder nicht. Der Ausdruck s+i erhöht sich bei jeder Iteration immer um genau 1, aber es könnte der Zähler sein (i) oder der Basiszeiger (s) das verursacht s+i erhöhen.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 14:15 Uhr

  • Ich würde das nennen clever. In Code, clever ist nicht immer gut. Ich bevorzuge normalerweise offensichtlich.

    – tvanfosson

    21. November 2010 um 14:17 Uhr

  • Wenn Sie bereits s inkrementieren, warum verwenden Sie i nicht vollständig zum Zählen des Vorkommens von ‘.’? für (; *s; i += *s == ‘.’, s++)

    – Jake

    29. November 2013 um 1:16 Uhr


  • Ich frage mich, wie viele Leute wie ich den ganzen Tag damit verbracht haben, das herauszufinden.

    – rasieren

    13. Dezember 2015 um 0:30 Uhr

  • eine clevere Lösung, aber dadurch wird der Zeiger an eine andere Stelle verschoben, sodass Sie die Zeichenkette s nicht mehr verwenden können

    – smihael

    13. Januar 2017 um 2:45 Uhr

Benutzeravatar von Michael J
Michael J

OK, eine Non-Loop-Implementierung (und ja, es ist als Witz gemeint).

size_t CountChars(const char *s, char c)
{
  size_t nCount=0;
  if (s[0])
  {
    nCount += ( s[0]==c);
    if (s[1])
    {
      nCount += ( s[1]==c);
      if (s[2])
      {
        nCount += ( s[2]==c);
        if (s[3])
        {
          nCount += ( s[3]==c);
          if (s[4])
          {
            nCount += ( s[4]==c);
            if (s[5])
            {
              nCount += ( s[5]==c);
              if (s[6])
              {
                nCount += ( s[6]==c);
                if (s[7])
                {
                  nCount += ( s[7]==c);
                  if (s[8])
                  {
                    nCount += ( s[8]==c);
                    if (s[9])
                    {
                      nCount += ( s[9]==c);
                      if (s[10])
                      {
                        /* too long */
                        assert(0);
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return nCount;
}

  • Ich glaube, du hast deine 8 hier verdoppelt: nCount += ( s[88]==c);. Sie hätten einen C-Code-Generator schreiben sollen, der aufgerufen hat cc über system um das Endergebnis zu produzieren. Oder noch besser, ein rekursiver Codegenerator, um Schleifen im Codegenerator zu vermeiden.

    – mu ist zu kurz

    21. November 2010 um 0:20 Uhr

  • Sieben Jahre später hat jemand dies abgelehnt, ohne auch nur einen Kommentar dazu zu geben, warum. Dies war ein komisches Stück Code und sagt es oben. Es zeigt die Unpraktikabilität der Frage. Ist jemand besorgt, dass es schlechter Stil ist???

    – Michael J

    22. November 2016 um 2:42 Uhr

Benutzeravatar von tvanfosson
tvanfosson

Schau, Ma, keine Schleifen.

int c = countChars( s, '.' );

int countChars( char* s, char c )
{
    return *s == '\0'
              ? 0
              : countChars( s + 1, c ) + (*s == c);
}

Aber ich würde tatsächlich eine Schleife verwenden, da dies die richtige zu verwendende Kontrollstruktur ist.

  • ah, Süße und Licht 🙂 – aber kannst du nicht einen Dreier machen, damit es nur eine Rückkehr gibt (und kein Wenn)?

    – KevinDTimm

    20. November 2010 um 23:19 Uhr

  • Ich denke, die | soll ein sein :. Auch “keine Schleifen” ist nett, aber es ist nicht genau so lesbar oder wartbar wie eine Schleife, und es wird auch nicht schneller sein. (Obwohl er dank Tail-Rekursion vielleicht nicht langsamer ist.) Cleverer Code ist nicht immer guter Code, besonders wenn er die Bedeutung verschleiert.

    – CDhowie

    20. November 2010 um 23:20 Uhr


  • Aber du sind mit Schleife! (Sie verwenden einfach nicht die Schlüsselwörter for/while).

    Benutzer166390

    20. November 2010 um 23:24 Uhr


  • @pst – keine Schleife, es wird Rekursion verwendet, was in diesem Fall wohl schlimmer ist.

    – tvanfosson

    20. November 2010 um 23:26 Uhr

  • Du brauchst *s==c in Klammern. + hat einen höheren Vorrang als ==offensichtlich.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 14:17 Uhr

Ohne Schleifen wird es schwierig, da es keine Standard-C-Bibliotheksfunktion gibt, die dies tut, und Sie müssen sich alle Zeichen ansehen 🙂

Ich nehme die offensichtliche Lösung:

int i, count;
for (i=0, count=0; str[i]; i++)
  count += (str[i] == '.');

Zögern Sie nicht, die beiden Zeilen des eigentlichen Codes in eine zu quetschen, wenn Sie müssen 🙂

Benutzeravatar von Steve Jessop
Steve Jessop

Wenn Sie auf einen Einzeiler stehen (na ja, zwei-):

size_t count = 0;
while(*str) if (*str++ == '.') ++count;

  • Hier ist es auf eine einzige for-Anweisung reduziert, einschließlich der Schleifenvariablen und der Ausgabe: for (size_t i=0; s[i] || printf("%d\n", i)>INT_MAX; s[i]=='.'?i++:s++); 😉

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 1:05 Uhr

Benutzeravatar von cdhowie
cdhowie

Ich würde dies immer noch in eine Funktion werfen und die Quellzeichenfolge und das zu suchende Zeichen parametrisieren.

int count_characters(const char *str, char character)
{
    const char *p = str;
    int count = 0;

    do {
        if (*p == character)
            count++;
    } while (*(p++));

    return count;
}

  • Hier ist es auf eine einzige for-Anweisung reduziert, einschließlich der Schleifenvariablen und der Ausgabe: for (size_t i=0; s[i] || printf("%d\n", i)>INT_MAX; s[i]=='.'?i++:s++); 😉

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 1:05 Uhr

Benutzeravatar von Sanjeev
Sanjeev

// Ich schätze, es sollte funktionieren. Eine Linie und keine Schleife.

int countChar(char *s, char letter) {
    return ((*s) ? (((*s++ == letter)? 1:0)) + countChar (s, letter)): 0);
}

1401590cookie-checkZählen der Anzahl der Vorkommen eines Zeichens in einer Zeichenfolge in C

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

Privacy policy