Zliczanie słów w pliku - tablice

0

Witam,
mam do wykonania program, mający za zadanie zliczenie częstotliwości występowania słów w dowolnym pliku oraz i ich wypisanie. Całość później ograniczyć do 10 najczęściej występujących.
Dla przykładu mam następujące słowa: "aa ab bb aa bb bb". Wynik powinien być następujący:
aa 2
ab 1
bb 3

U mnie niestety wygląda on tak:
aa 2
aa 2
ab 1
bb 3
bb 3
bb 3
Czyli, każde słowo, które ma więcej powtórzeń zostanie wypisane kilkukrotnie. Przypuszczam, iż błąd leży po stronie porównywania dwóch tablic, ale nie mam obecnie pomysłu na inne rozwiązanie. Poniżej przedstawiam kod całego programu.
Dodam, iż nie mogę korzystać z biblioteki map, vector itp.

#include <iostream>
#include <stdlib.h>
#include <string>
#include <iomanip>
#include <fstream>

using namespace std;
struct wordCount
{       
     string word;       
     int count; 
}; 
class wordFrequency
{
    public:
        int countFile(int counter);
        void openFile(ifstream &inFile, ofstream &outFile);
        void periods(string arr[], int n);
        void bubbleSort(string arr[], int n);    

    private:
        string wordsM[];
};

int main()
{
    wordFrequency word;
    int length;
    int counter;

    length = word.countFile(counter);
    string wordsM[length];
    struct wordCount wordFreq[length];

    ifstream inFile;
    ofstream outFile;

    word.openFile(inFile, outFile);

    while (!inFile.eof())
    {

          for(int i=0; i < length; i++) 
          {
                    inFile >> wordsM[i];
                    word.periods(wordsM, length);

          wordFreq[i].word = wordsM[i];
          wordFreq[i].count = 0;
          }

    }
   word.bubbleSort(wordsM , length);
    for (int i = 0; i < length;i++)
    {
        for (int j = 0; j < length; j++)
        {
            if (wordsM[i] == wordFreq[j].word) 
            {
               wordFreq[i].count++;
            }
        }
        cout << wordsM[i] << " " << wordFreq[i].count <<endl;
    }   

    inFile.close();
    outFile.close();
    system ("Pause");
    return 0;
}
int wordFrequency::countFile(int counter)
{
    ifstream inFile;
    int counts = 0;
    string str;

    inFile.open("input.txt");
    while (!inFile.eof())
    {
          inFile >> str;
          counts++;
    }

     return counts;
}
void wordFrequency::openFile(ifstream &inFile, ofstream &outFile)
{
    inFile.open("input.txt");
}
void wordFrequency::periods(string arr[], int n)
{
    int i;
    size_t found;
    for ( i = 0; i < n; i++)
    {
          found=arr[i].find('.');
          if (found!=string::npos)
          {
          arr[i].replace(arr[i].find('.'),1,"");
          }
          found = arr[i].find(',');
          if (found!=string::npos)
          {
          arr[i].replace(arr[i].find(','),1,"");
          }
                    found = arr[i].find('"');
          if (found!=string::npos)
          {
          arr[i].replace(arr[i].find('"'),1,"");
          }
                    found = arr[i].find('-');
          if (found!=string::npos)
          {
          arr[i].replace(arr[i].find('-'),1,"");
          }
                              found = arr[i].find('!');
          if (found!=string::npos)
          {
          arr[i].replace(arr[i].find('!'),1,"");
          }

     }
} 
void wordFrequency::bubbleSort(string arr[], int n)
{
    int i, j;
    string temp;

    for ( i = 1; i < n; i++)
    {
        for (j = 0; j < n - i; j++)
        {
            if (arr[j] > arr[j+1])
            {
                       temp = arr[j];
                       arr[j] = arr[j+1];
                       arr[j+1] = temp;
            }
        }
     }
}     
0
for(int i=0; i < length; i++) 
{
    inFile >> wordsM[i];
    word.periods(wordsM, length);

    wordFreq[i].word = wordsM[i];
    wordFreq[i].count = 0;
}

Skoro nie przejmujesz się złożonością algorytmiczną to przed stworzeniem kolejnego wordFreq wypadałoby sprawdzić czy nie istnieje już inny z tym samym wyrazem.

0

Zastanów się nad:

    unordered_map<string,size_t> tb;
    ifstream inFile("input.txt");
    string str;
    while(inFile>>str) ++tb[str];
    inFile.close();
    multimap<size_t,string> bycnt;
    for(unordered_map<string,size_t>::iterator i=tb.begin();i!=tb.end();++i)  bycnt.insert(pair<size_t,string>(i->second,i->first));
    map<string,size_t> byname;
    for(multimap<size_t,string::iterator i=bycnt.begin();i!=bycnt.end();++i)  byname[i->second]=i->first;
    cnt=0;
    for(map<string,size_t>::iterator i=byname.begin();(i!=byname.end())&&(++cnt<10);++i) cout<<i->first<<": "<<i->second<<endl;
3

Jak nie map, vector itp. to może Boost.BiMap?

    typedef boost::bimap<
            boost::bimaps::unordered_set_of<string>,
            boost::bimaps::multiset_of<int>
    > map_t;

    map_t counts;

    string word;
    while(cin >> word){
        auto it = counts.left.find(word);

        if(it == end(counts.left)){
            counts.insert(map_t::value_type(word, 1));
        }else{
            counts.left.replace_data(it, it->second + 1);
        }
    }

    int maxDisplay = 10;
    for(auto it = counts.right.rbegin(), e = counts.right.rend(); it != e && maxDisplay--; ++it){
        cout << left << setw(20) << it->second << it->first << endl;
    }

http://melpon.org/wandbox/permlink/KcVwJAH3v3ecim0v

Nie doczytałem, że nie może być kontenerów, a nie chciałem, żeby się marnowało.

0

A jak by tą tablicę słów posortować alfabetycznie , i potem słowo jest takie samo jak następne, to zwiększamy licznik o jeden, a jak inne to znaczy że to nowe słowo (więc do tablicy wypisującej z nim)? Ich oryginalne położenie i tak nie ma znaczenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0