独特的台词和单词?如何实现它

  • 本文关键字:何实现 实现 单词 c++
  • 更新时间 :
  • 英文 :


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

问题:

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

    #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;
    }
    

您在循环时将 get line 末尾的计数变量重置为零。 这就是为什么您只能获得一行的结果。 用户可以在您的程序中输入多行,因为现在您只是重置计数。

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

我不想批发给出答案,但这里有一些想法可以帮助您入门。

  1. 函数 getline(( 可以读取整行输入。执行此操作,直到没有更多输入。
  2. 您可以使用像 std::set(或更好的 std::unordered_set(这样的容器来存储读入的行。不是最有效的,但它会跟踪您的所有行,并且只存储唯一的行。
  3. 然后,可以将每一行分解为单词。考虑使用类似 std::stringstream 的东西。
  4. 将单词存储在不同的 std::unordered_set 中。
  5. 唯一行数(字数
  6. (只是存储在容器中的行数(字数(。使用 .size(( 方法获取此值。

行数、单词数和字符数可以在您读取数据时计算,所以我不会在那里详细介绍。

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

获得相当准确的计数非常容易,但要获得所有这些的正确计数可能非常困难。

最大的问题是字符数。如果您以文本模式打开文件(像往常一样(,则您计算的字符数可能与操作系统认为的字符数不匹配。对于显而易见的示例,在 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(的问题,但这可能不是他真正想要的。我的猜测是,他的老师并没有真正要求这种程度的关心来试图获得准确的字符数。

另请注意,如果您遇到比缓冲区长的行,这仍然会产生不准确的行计数 - 它会将每个充满数据的缓冲区计为单独的行,即使它没有找到行分隔符。这也可以修复,但它增加了一个几乎肯定已经比预期更复杂的程序的复杂性。

最新更新