2

テキストの段落を文字列ベクトルに読み込んでから、各単語の出現回数をカウントする辞書を作成しようとしています。これまでのところ、テキストの最初の単語しか読み込まれておらず、どうすればよいかわかりません。これらのメンバー関数を適切に使用する方法が少しわかりません。

int main()
    {
        ifstream input1;
        input1.open("Base_text.txt");

    vector<string> base_file;
    vector<int> base_count;


    if (input1.fail())
    {
        cout<<"Input file 1 opening failed."<<endl;
        exit(1);
    }

    make_dictionary(input1, base_file, base_count);


}

void make_dictionary(istream& file, vector<string>& words, vector<int>& count)
{


    string line;


    while (file>>line)
    {
        words.push_back(line);
    }

    cout<<words[0];



}

期待される出力:

This is some simple base text to use for comparison with other files.
You may use your own if you so choose; your program shouldn't actually care.
For getting interesting results, longer passages of text may be useful.
In theory, a full novel might work, although it will likely be somewhat slow.

実際の出力:

This 
4

4 に答える 4

1

Well, you print only the first word: (The idea ist to show you why yuo have to love STL)

cout<<words[0];

You could

for(string& word : words)             cout<<word;

or

for(size_t i=0; i<words.size(); ++i)  cout<<words[i];

To print all of then. A very simple solution to count the words is to use a map in place of vector:

map<string,size_t> words;
...
string word;
while (file>>word)           ++words[word];
...
for(const auto& w : words)  cout<<endl<<w.first<<":"<<w.second;

WhozCraig proposed a challenge. To order the word by frequency:

multimap<int,string,greater<int>> byFreq;
for(const auto& w : words)  byFreq.insert( make_pair(w.second, w.first));
for(const auto& w : byFreq) cout<<endl<<w.second <<":"<<w.first;

All will (ideone):

#include <iostream>
#include <map>
#include <functional> 
#include <utility>
#include <cctype>
using namespace std;

int main() 
{
   map<string,size_t> words;
   string word;

   while (cin>>word)  
   { 
       for(char&c:word)c=tolower(c);
       ++words[word];
   }
   cout<<"  ----- By word: ------" ;
   for(const auto& w : words)  cout<<endl<<w.first<<":"<<w.second;
   cout<<endl<<endl<<" ----- By frequency: ------";
   multimap<size_t,string,greater<int>> byFreq;
   for(const auto& w : words)  byFreq.insert( make_pair(w.second, w.first) );
   for(const auto& w : byFreq) cout<<endl<<w.second <<":"<<w.first;
   return 0;
}
于 2013-04-26T19:42:36.053 に答える
1

テキスト ファイルから文字列ベクトルへの単語コンテンツの読み取りは、かなり簡単です。以下のコードは、解析されるファイル名が最初のコマンドライン引数であると想定しています。

#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
#include <string>
#include <map>
using namespace std;

int main(int argc, char *argv[])
{
    if (argc < 2)
        return EXIT_FAILURE;

    // open file and read all words into the vector.
    ifstream inf(argv[1]);
    istream_iterator<string> inf_it(inf), inf_eof;
    vector<string> words(inf_it, inf_eof);

    // for populating a word-count dictionary:
    map<string, unsigned int> dict;
    for (auto &it : words)
        ++dict[it];

    // print the dictionary
    for (auto &it : dict)
        cout << it.first << ':' << it.second << endl;

    return EXIT_SUCCESS;
}

ただし、両方の操作を単一のループに結合し、中間ベクトルを完全に回避する必要があります (可能です)。

#include <iostream>
#include <fstream>
#include <string>
#include <map>
using namespace std;

int main(int argc, char *argv[])
{
    if (argc < 2)
        return EXIT_FAILURE;

    // open file and read all words into the vector.
    ifstream inf(argv[1]);
    map<string, unsigned int> dict;
    string str;
    while (inf >> str)
        ++dict[str];

    // print the dictionary
    for (auto &it : dict)
        cout << it.first << ':' << it.second << endl;

    return EXIT_SUCCESS;
}

出現頻度の高い順に並べ替えるのは簡単ではありませんが、並べ替えベッド ベクトルと を使用して実行できstd::sort()ます。さらに、先頭と末尾の非アルファベット文字 (句読点) のストライピングも機能強化です。もう 1 つの方法は、単語をマップに挿入する前にすべて小文字にすることです。これにより、Ball と ball が 2 つのカウントで 1 つのディクショナリ スロットを占有できます。

于 2013-04-26T21:03:37.860 に答える
1

ループ内に移動する必要があると思います。cout << words[0]そうしないと、ループが終了したときに一度だけ呼び出されます。ただし、繰り返しごとに最初の単語のみが出力されます。したがって、毎回最後の単語を出力します。

while (file>>line)
{
     words.push_back(line);
     cout<<words.back(); // or cout << line, same thing really
}

最後に-while(file >> line)変数の名前が示すように、行ごとではなく、単語ごとに読み取ります。それが必要な場合は、を使用してwhile (getline(file, line))ください。

于 2013-04-26T19:43:41.470 に答える