独特的线条和单词?怎么实现呢?

时间:2013-09-27 17:26:06

标签: c++

我在使用这个程序时遇到了麻烦。该程序应该告诉用户给定输入中的行数,单词,字符,唯一行和唯一单词。到目前为止,单词和字符都可以。但是,如果用户想要输入多行,我该怎么做?这些函数一次只输出一行的结果,而不是将两行的结果相加。另外,我无法使Unique Lines和Unique Words正常工作。我刚进入C ++,所以我没有多少经验。有人可以帮助我吗?

问题:

  1. 程序一次读取一行,因此当用户多次输入时,程序会单独生成结果,而不是将它们作为一个实体一起添加。
  2. 独特的线条和独特的单词不起作用。任何想法如何使用程序中使用的库来实现它。

    #include <iostream>
    using std::cin;
    using std::cout;
    using std::endl;
    #include <string>
    using std::string;
    #include <set>
    using std::set;
    
    
    // write this function to help you out with the computation.
    
    
    unsigned long countLines()
    {
        return 1;
    }
    
    
    
    unsigned long countWords(const string& s)
    {
        int nw =1;
        for (size_t i = 0; i < s.size(); i++)
        {
            if (s[i] == ' ')  //everytime the function encounters a whitespace, count     increases by 1)//
            {
                nw++;
            }
        }
     return nw;
    }
    
    unsigned long countChars(const string& s)
    {
        int nc = 0;
        for (size_t i = 0; i < s.size(); i++)
        {
            if ( s[i] != ' ') //everytime the function encounters a character other than a whitespace, count increases//
            {
                nc++;
            }
        }
    
        return nc;
    }
    
    
    unsigned long countUnLines(const string& s, set<string>& wl)
    {
       wl.insert(s);
       return wl.size();
    }
    
    
    
    unsigned long countUnWords(const string& s, set<string>& wl)
    {
        int m1 = 0;
        int m2 = 0;
        string substring;
    
        for(m2 = 0; m2 <= s.size(); m2++){
            if (m2 != ' ' )
    
            substring = s.substr(m1,m2);
            wl.insert(substring);
    
            m1 = m2 + 2;}
        }
    
        return wl.size();
    
        int unw = 0;
        wl.insert(s);
        unw++;
        return unw;
    }
    
    int main()
    {
        //stores string
        string s;
    
        //stores stats
        unsigned long Lines = 0;
        unsigned long Words = 0;
        unsigned long Chars = 0;
        unsigned long ULines = 0;
        unsigned long UWords = 0;
    
        //delcare sets
        set<string> wl;
    
        while(getline(cin,s))
        {
    
            Lines += countLines();
            Words += countWords(s);
            Chars += countChars(s);
            ULines += countUnLines(s,wl);
            UWords += countUnWords(s);
    
            cout << Lines << endl;
            cout << Words<< endl;
            cout << Chars << endl;
            cout << ULines << endl;
            cout << UWords << endl;
    
    
            Words = 0;
            Chars = 0;
            ULines = 0;
            UWords = 0;
    
        }
    
        return 0;
    }
    

4 个答案:

答案 0 :(得分:0)

您在getline while循环结束时将计数变量重置为零。这就是为什么你只得到一行的结果。用户可以在程序中输入多行,因为现在您只是重置计数。

答案 1 :(得分:0)

我认为你正朝着正确的方向前进。为了计算独特的行和单词,你必须在某种数据结构中存储每一行​​和单词,我建议使用unordered_map。地图中的每个元素都有一个计数器,用于显示每行/单词的出现次数。

答案 2 :(得分:0)

我不想批发答案,但这里有一些想法让你开始。

  1. 函数getline()可以读入整行输入。这样做直到没有更多的输入。
  2. 您可以使用像std :: set(或更好,std :: unordered_set)这样的容器来存储读入的行。不是最有效的,但它会跟踪所有行,并且只存储唯一的行。
  3. 然后可以将每行分解为单词。考虑使用像std :: stringstream这样的东西。
  4. 将单词存储在不同的std :: unordered_set。
  5. 唯一行(单词)的数量就是存储在容器中的行数(单词)。使用.size()方法获取此信息。
  6. 在读取数据时,可以计算总行数,单词数和字符数,因此我不会详细介绍。

    每个项目都是可谷歌的,你可以选择以不同的方式实现不同的部分(例如,如果你不想使用字符串流,你总是可以迭代读取行。)这应该让你走上正确的轨道

答案 3 :(得分:0)

很容易获得相当准确的计数,但是对于所有这些来说,获得正确计数可能会非常困难。

最大的问题是人物数量。如果在文本模式下打开文件(通常如此),则计算的字符数可能与操作系统认为的不匹配。对于明显的例子,在Windows下,CR / LF对将被转换为单个换行符,因此您通常将每一行计算为比实际更短的一个字符。

从技术上讲,没有办法完全正确处理 - 在文本模式下打开文件时从外部到内部表示的转换在理论上是任意的。至少在理论上,以二进制模式打开也没有多大帮助;在二进制模式下,在写入文件的数据结束后,您可以拥有任意数量的NUL字符。

然而,后者现在几乎是理论上的(主要是因为大多数人早已忘记了CP / M)。

要读取行,但保留行尾分隔符不变,可以使用std::cin.get()代替std::getline(),然后分别从行本身读取分隔符。

这给了我们这样的东西:

#include <iostream>
#include <set>
#include <string>
#include <iterator>
#include <sstream>
#include <fstream>

int main(int argc, char **argv) {
    static char line[4096];
    unsigned long chars = 0;
    unsigned long words = 0;
    unsigned long lines = 0;
    std::set<std::string> unique_words;

    std::ifstream in(argv[1], std::ios::binary);

    while (in.get(line, sizeof(line), '\n')) {
        ++lines;
        chars += strlen(line);

        std::istringstream buffer(line);
        std::string word;
        while (buffer >> word) {
            ++words;
            unique_words.insert(word);
        }
        while (in.peek() == '\n' || in.peek() == '\r') {
            ++chars;
            in.ignore(1);
        }       
    }
    std::cout << "words: " << words << "\n"
              << "lines: " << lines << "\n"
              << "chars: " << chars << "\n"
              << "unique words: " << unique_words.size() << "\n";
}

请注意,虽然这个确实回答了OP实际上至少对大多数典型操作系统(Linux,* BSD,MacOS,Windows)提出的问题,但它可能真的很想要。我的猜测是,他的老师并没有真正要求这种程度的护理来试图获得准确的字符数。

还要注意 if 你应该遇到比缓冲区长的行,这仍然会给出一个不准确的行数 - 它会将每个缓冲区数据作为一个单独的行计算,即使它没有找到行分隔符。这也可以修复,但它增加了一个程序的复杂性,这个程序几乎肯定已经比预期的更复杂了。