Mehrere for schleifen zusammenfasse

Talha111

Grünschnabel
For schleifen zusammenfassen - Hilfe

Hallo

ich soll bei einer Aufgabe von einem eingelesenen String angeben, wie oft bestimmte Buchstaben vorkommen.
Der String darf ausschließlich die Buchstaben A-F enthalten.

Ich hab jetzt für jeden Buchstaben eine for Schleife
...
int i, k, ...A=0, B=0,...;
char Kette[100];

C++:
for(i=0;i <laenge;i++){
              if(Kette[i] == 'A')
              A++;
              }
for(i=0;i <laenge;i++){
              if(Kette[i] == 'B')
              B++;
              }
...
Funktionieren tuts. Beim Versuch die Schleifen zusammen zufassen hatte ich jedoch große Schwierigkeiten.

Nach langer Überlegung und rumprobieren kam ich dann auf:
C++:
for(k=0;k<=5;k++){
    for(i=0;i<laenge;i++){
         if(Kette[i] == 'A'+k){
         if(k==0) A++;
         if(k==1) B++;
         }
     }
}
Funktionieren tut das auch, aber geht glaub ich noch einfacher. Als ich mein prof gefragt hab, gab er als Hinweis, dass ich an die Asci tabelle denken soll. Da hätte ich aber wieder das selbe problem, mit dem inkrementieren und müsste wieder mit if abfragen A++ usw machen.

Danke schonmal im vorraus an alle, die sich Zeit dafür nehmen :)


Hier nochmal mein ganzer code:
C++:
#include <stdio.h>
#include <conio.h>
#include <string.h>

int main(){
    int k, i, j, hilf, laenge, vorgesehene_laenge, Fehler=0, A=0, B=0, C=0, D=0, E=0, F=0;
    char Kette[101];
    printf("Die Buchstaben A-F eingeben:");
    gets(Kette);
    printf("s = %s", Kette);
    laenge = strlen(Kette); 
    
   for(k=0;k<=5;k++){
    for(i=0;i<laenge;i++){
         if(Kette[i] == 'A'+k){
         if(k==0) A++;
         if(k==1) B++;
         }
     }
}
        for(i=0;i<laenge;i++){ //läuft die Zeichenkette ab
        for(j=65;j<71;j++){ //läuft in der Ascii-Tabelle A_F ab
            if(Kette[i]==j){     
            break;
            }
            if(j==70){
            Fehler++;
            }  
        }
    }
    if(Fehler>0)
    printf("\nFalsche Zeiche kommen %i mal vor",Fehler);
    printf("\nSie haben %i Zeichen eingegeben", laenge);                         
    printf("\nIn s richtig vorkommende Zeichen und deren Anzahl:\n");
    printf("A(%i), B(%i), C(%i), D(%i), E(%i), F(%i)\nz = ",A,B,C,D,E,F);
    for(i=0;i<A;i++)
    printf("%c",'A');
    for(i=0;i<B;i++)
    printf("%c",'B');
    for(i=0;i<C;i++)
    printf("%c",'C');
    for(i=0;i<D;i++)
    printf("%c",'D');
    for(i=0;i<E;i++)
    printf("%c",'E');
    for(i=0;i<F;i++)
    printf("%c",'F');              
    

    getch();
    return 0;
}
 
Zuletzt bearbeitet:
Hallo Talha111 und Herzlich Willkommen hier!

Ich gebe dir mal einen Tipp:


Erstelle ein Int-Array mit der Länge A-F, sprich 6.
In diesem kannst du die Anzahlen der Buchstaben speichern, wobei 0 A repräsentiert und 5 F.

Nun musst du nur beim Durchlaufen des Strings noch wissen, auf welches Element du gerade zugreifen musst, damit du inkrementieren kannst.
Dafür reicht eine einfache Differenz (ASCII-Code v. Buchstabe - ASCII-Code v. A [=65]).

Aus einem Buchstaben (char) den ASCII-Code zu bekommen, geht mit einem einfachen Cast:
C++:
int ascii = (int) Kette[i];

// oder besser!
int ascii = static_cast<int>(Kette[i]);

Außerdem solltest du noch prüfen, ob wirklich nur A-F eingegeben wurden. Dies geht anhand des ASCII-Codes ganz einfach (>= und <=-Operatoren!).

Falls du immer noch nicht weiter kommst, kannst du gerne fragen!


PS: In welchem Semester bist du, wenn ich fragen darf?
 
Hi und Willkommen bei tutorials.de,

statt den Variablen A; B... kann man ein Array machen.
Ein Array aus 6 ints
C++:
int zaehler[6];
wobei dann zaehler[0] für A steht, zaehler[1] für B usw.

So, wie du A, B... am Anfang auf 0 setzt muss das auch für die Arrayvariablen passieren.
Das könnte man natürlich in 6 einzelne Anweisungen setzen, geht aber bequemer per Schleife:
C++:
for(k=0;k<=5;k++)
{
    zaehler[k] = 0;
}

Und beim
C++:
if(k==0) A++;
if(k==1) B++;
...
kann man dann einfach schreiben
C++:
zaehler[k]++;

Noch was zum zweiten Programmteil (Falsche Zeichen zählen):
Das könnte man auch einfach per Minusrechnung machen.
Die Länge minus die Anzahl der "guten" Zeichen.
Man braucht zwar noch immer eine Schleife,
da in zaehler 6 Gute-Zeichen-Anzahlen sind...
aber man muss nicht den ganzen String nocheinmal durchgehen.
 
Also erstmal vielen dank an euch beide für die umfangreichen Antowroten.
Mir ist aufgefallen, dass ich dummmerweise cpp angegeben hab, anstatt c. Hab bei faqs gelesen, dass man seine codierung mit [code=cpp] angeben kann und war nicht schlau genug, dass mit c zu versuchen :rolleyes:
Zu der Frage in welchem Semester ich bin: Ich bin im ersten Semester und zwar in dem Fach Elektrotechnik an einer Fh :)

So und jetzt wieder zum Wesentlichen:
Ich habs jetzt so gemacht, wie Sheel es eklärt hatte. Hab dazu noch ne verständniss Frage.
C:
zaehler[k]++;
Bedeutet doch, dass der Wert meines arrays an der k-ten Stelle um jeweil 1 erhöht wird oder?

Hab jetzt noch ein anderes, ähnliches Problem. In der Aufgabe ist außerdem verlangt, die Zeichenkette alphabetisch zu ordnen.
Ursprünglich hatte ich wieder für jeden Buchstaben eine eigene Schleife.
C:
    for(i=0;i<A;i++)
    printf("%c",'A');
    for(i=0;i<B;i++)
    printf("%c",'B');
    for(i=0;i<C;i++)
    printf("%c",'C');
    for(i=0;i<D;i++)
    printf("%c",'D');
    for(i=0;i<E;i++)
    printf("%c",'E');
    for(i=0;i<F;i++)
    printf("%c",'F');
Da ursprünglich jedes mal wenn das Zeichen 'A' vorkommt die Variable A inkrementiert wurde. Hab dann einfach in der Anzahl von A den print befehl durchgeführt. Bin mir nicht sicher ob das zweck der Aufgabe war, aber es hat funktioniert.
Nun wollte ich es nach dem Schema wie bei meinem vorherigen Problem machen, habs aber leider nicht geschafft.

Mein Versuch:
C:
 for(k=0;k<laenge;k++){
      for(i=0;i<zaehler[i];i++){
         printf("%c",65+i);
         }                                           
   
}
Ich hoffe ihr könnt mir wieder helfen - danke an alle die sich die Zeit nehmen.
 
Zur ersten Frage: Genau.
So, wie A++ A um eins erhöht, erhöht das eben zaehler[k]

Zum Problem 2, alte Variante:
Statt
C++:
printf("%c",'A');
hätte man auch einfach
C++:
printf("A");
schreiben können. Wozu umständlicher als nötig?
Für die neue, arraylastige Variante passt %c aber ganz gut.

Und zu den Problemen:
Du willst also
*für alle 6 zaehler[...]
**so oft den Buchstaben ausgeben, wie die Zahl drin ist.

Fehler 1: Die äußere Schleife, für die 6 zaehler,
geht bei dir nicht bis 6, sondern bis zur Stringlänge.

Fehler 2, in der inneren Schleife:
Jetzt hast du die Nummer des zaehler also in k.
zahler[k].
Und mit i willst du von 0 bis dorthin zählen.
Merkst was?
Du zählst mit i von 0 bis zaehler[i].
Ist 0 kleiner als zaehler[0]
Ist 1 kleiner als zaehler[1]
Ist 2 kleiner als zaehler[2]
...


Statt
C++:
printf("%c",65+i);
könnte man übrigens auch
C++:
printf("%c", 'A' + i);
nehmen, also direkt den Buchstaben rein.
Dann ist der Sinn vllt. leichter ersichtlich.

C++:
for(k = 0; k < 6; k++) {
    for(i = 0; i < zaehler[k]; i++) {
        printf("%c", 'A' + i);
    }
}
 
Vielen dank für deine Antwort. Hast meine Fehler wirklich sehr schön und simpel eklärt, da frage ich mich, wie ich die nur machen konnte :)

Habs jetzt zwar verbesset, aber richtig funktionieren tuts immer noch nicht.
Ich kann nicht mal erkennen, nach welchem "Muster" die Ausgabe erfolgt...

Beispiel:
Eingabe:FFFF
Ausgabe:ABCD

Eingabe:EBDCAF
Ausgabe:AAAAAA
 
C:
#include <stdio.h>
#include <conio.h>
#include <string.h>
 
int main(){
    int k, i, j, hilf, laenge, vorgesehene_laenge, Fehler=0;
    int zaehler[6];
    char Kette[101];
    printf("Die Buchstaben A-F eingeben:");
    gets(Kette);
    printf("s = %s", Kette);
    laenge = strlen(Kette); 
    
    for(k=0;k<=5;k++)    {
    zaehler[k] = 0;
    }
    for(k=0;k<=5;k++){
        for(i=0;i<laenge;i++){
            if(Kette[i] == 'A'+k){
            zaehler[k]++;
            }
        }
    }
    for(i=0;i<laenge;i++){ //läuft die Zeichenkette ab
        for(j=65;j<71;j++){ //läuft in der Ascii-Tabelle A_F ab
            if(Kette[i]==j){     
            break;
            }
    if(j==70){
    Fehler++;
            }  
        }
    }
    if(Fehler>0)
    printf("\nFalsche Zeiche kommen %i mal vor",Fehler);
    printf("\nSie haben %i Zeichen eingegeben", laenge);                         
    printf("\nIn s richtig vorkommende Zeichen und deren Anzahl:\n");
    printf("A(%i), B(%i), C(%i), D(%i), E(%i), F(%i)\nz = ",
           zaehler[0],zaehler[1],zaehler[2],zaehler[3],zaehler[4],zaehler[5]);

for(k = 0; k < 6; k++) {
    for(i = 0; i <zaehler[k]; i++) {
        printf("%c", 'A' + i);
    }
}
    getch();
    return 0;
}
Ich hoffe du kommst zu recht
 
Sorry, das hätte mir früher auffallen sollen:
C++:
for(k = 0; k < 6; k++) {
    for(i = 0; i <zaehler[k]; i++) {
        printf("%c", 'A' + i);
    }
}
k=0 bedeutet, es geht gerade um 'A', k=1 ist 'B'...
bei der Ausgabe sollte also 'A' korrekterweise mit k addiert werden, nicht mit i.
Sonst ist der ausgegebene Buchstabe ja von der Anzahl des gedachten Buchstaben abhängig.

Sonst noch:
Die Variablen vorgesehene_laenge und hilf brauchst du nirgends, können eigentlich weg.

Und das hatte ich auch noch nicht angesprochen:
Und bei gets(Kette); am Anfang könnte der Benutzer mehr als die 100 Zeichen von Kette eingeben.
gets würde das schlucken -> Problem im Programm.
Bestenfalls Absturz mit Fehler, sonst irgendwas Unvorhersehbares.
Folgende Variante beachtet die Maximallänge und schneidet den Rest ggf. ab:
C++:
fgets(Kette, 101, stdin);
 
Ja es klappt! Wirklich vielen dank für deine mühe - echt super!

Ahja hab vergessen vorgesehene_laenge zu löschen, nach dem ich mein code geändert hatte, danke dass du mich drauf aufmerksam gemacht hast.
 

Neue Beiträge

Zurück