Häufigkeit eines Strings feststellen

M

MrCodeMaster

Hi Leute!

Ich hab ein Problem bei einem Programm. Ich möchte, die Häufigkeit eines Strings in einer Textdatei feststellen.

Hab selber nur die Idee, dass ich die Strings miteinander vergleiche, aber weiter weiß ich leider nicht.

Ich hoffe auf schnelle Antworten.

MfG,
MrCodeMaster
 
Hallo,

Folgendes sollte ungefähr das tun was du willst. Du musst halt vorher den Dateiinhalt in den string strDatei laden:
C++:
char* strDatei;
char* strPattern = "asdf";
int found = 0;

for (int i = 0; i < strlen(strFile); i++)
{
  if (strncmp(strFile+i, strPattern, strlen(strPattern)) == 0)
    found++;
}
 
Zuletzt bearbeitet von einem Moderator:
Danke für die schnelle Antwort!

Das ist aber so wie ich da sehe ein vorgegebener String, und ich möchte dass aber mit einen nicht vorgegeben String machen.

Ich möchte Lottozahlen für ein halbes Jahr eingeben und dann die Häfigkeit der Zahlen überprüfen.
 
Hallo,

Meinst du bei strPattern? Du kannst da alles reinschreiben was du willst. z.B.: halt auch eine Zahl. Du musst sie nur vorher in einen String konvertieren.
 
Ja das ist mir schon klar aber ich will ja dann die Lottozahlen nicht auf eine Zahlenreihenfolge beschränken sonder alle miteinbeziehen.

Hier ein Beispiel:
534126
654782
875390
125678
827568
827568
534126

Das soll er auf Häfigkeit überprüfen und mir dann sagen: 534126 ist 2 mal vorgekommen und 827568 ist 2 mal vorgekommen.
 
OK. Jetzt hab ichs verstanden.

Dann ließ dir alle Zahlen ein, konvertier sie in ints und speicher sie in einen vector. Dann mach folgendes
C++:
std::vector<int> numbers;

while (numbers.size() > 0)
{
  int currentNumber = numbers[0];
  int counter = 0;

  for (int i = 1; i < numbers.size(); i++)
  {
    if (currentNumber == numbers[i])
    {
      counter++;
      numbers.erase(numbers.begin() + i);
      i--;
    }
  }

  number.erase(numbers.begin());

  std::cout << currentNumber << " kommt " << counter << " mal vor" << std::endl;
}
 
Zuletzt bearbeitet von einem Moderator:
Folgendes sollte ungefähr das tun was du willst. Du musst halt vorher den Dateiinhalt in den string strDatei laden:
C++:
char* strDatei;
char* strPattern = "asdf";
int found = 0;

for (int i = 0; i < strlen(strFile); i++)
{
  if (strncmp(strFile+i, strPattern, strlen(strPattern)) == 0)
    found++;
}
So ist das allerdings äußerst ineffizient. Die Abbruchbedingung der Schleife muss jedes mal den kompletten String durchlaufen, um dessen Länge festzustellen. Da sich die Stringlänge in der Schleife aber nicht ändert, kann man die Länge genauso gut auch vorberechnen. Selbiges gilt für das strlen in der Schleife. Und schlussendlich gibt es zum Auffinden eines Strings in einem anderen bereits die Funktion strstr.

Dann ließ dir alle Zahlen ein, konvertier sie in ints und speicher sie in einen vector. Dann mach folgendes
C++:
std::vector<int> numbers;

while (numbers.size() > 0)
{
  int currentNumber = numbers[0];
  int counter = 0;

  for (int i = 1; i < numbers.size(); i++)
  {
    if (currentNumber == numbers[i])
    {
      counter++;
      numbers.erase(numbers.begin() + i);
      i--;
    }
  }

  number.erase(numbers.begin());

  std::cout << currentNumber << " kommt " << counter << " mal vor" << std::endl;
}
Auch wieder nicht sonderlich effizient. erase auf einem std::vector ist extrem langsam, da im schlimmsten Fall sämtliche Elemente kopiert werden müssen. Besser entweder eine std::map<int, int> (oder eine std::unordered_map<int, int>) zum Speichern der Häufigkeiten verwenden oder den std::vector vorher sortieren und einmal durchlaufen. Beispielcode:

Mit std::map<int, int>:
C++:
std::vector<int> numbers;
std::map<int, int> counts;

for (std::vector<int>::const_iterator it = numbers.begin();
     it != numbers.end();
     ++it) {
  ++counts[*it];
}

for (std::map<int, int>::const_iterator it = counts.begin();
     it != counts.end();
     ++it) {
  std::cout << it->first << " kommt " << it->second << " mal vor" << std::endl;
}
Anmerkung: diese Methode könnte man auch ohne vorheriges Zwischenspeichern in den std::vector verwenden.

Mit sortieren:
C++:
std::vector<int> numbers;

std::sort(numbers.begin(), numbers.end());

int currentNumber = numbers.front();
int count = 1;

for (std::vector<int>::const_iterator it = numbers.begin() + 1;
    it != numbers.end();
    ++it) {
  if (*it == currentNumber) {
    ++count;
  } else {
    std::cout << currentNumber << " kommt " << count << " mal vor" << std::endl;
    currentNumber = *it;    
    count = 1;
  }
}

std::cout << currentNumber << " kommt " << count << " mal vor" << std::endl;

Grüße,
Matthias
 
Zuletzt bearbeitet von einem Moderator:
Zurück