【问题标题】:find the maximum number of words in a sentence from a paragraph with C++用C++从一个段落中找到一个句子中的最大单词数
【发布时间】:2021-11-01 06:05:28
【问题描述】:

我正在尝试从段落中找出句子中的最大单词数(用点分隔)。我完全陷入了如何排序和输出到标准输出。

例如: 给定一个字符串 S: {"Program to split strings. By using custom split function. In C++"};

预期的输出应该是:5

#define max 8 // define the max string  

string strings[max]; // define max string  
string words[max];
int count = 0;

 
void split (string str, char seperator)  // custom split() function 
{  
    int currIndex = 0, i = 0;  
    int startIndex = 0, endIndex = 0;  
    while (i <= str.size())  
    {  
        if (str[i] == seperator || i == str.size())  
        {  
            endIndex = i;  
            string subStr = "";  
            subStr.append(str, startIndex, endIndex - startIndex);  
            strings[currIndex] = subStr;  
            currIndex += 1;  
            startIndex = endIndex + 1;  
        }  
        i++;  
        }     
}  

void countWords(string str) // Count The words 
{
    int count = 0, i; 

    for (i = 0; str[i] != '\0';i++)
    {
        if (str[i] == ' ')
            count++;    
    }
 
    cout << "\n- Number of words in the string are: " << count +1 <<" -";
}

//Sort the array in descending order by the number of words
void sortByWordNumber(int num[30])
{
   /* CODE str::sort? std::*/
}

int main()  
{  
    string str = "Program to split strings. By using custom split function. In C++";  
    char seperator = '.'; // dot  
    int numberOfWords;
    
    split(str, seperator);  
    cout <<" The split string is: ";  
    for (int i = 0; i < max; i++)  
    {  
        cout << "\n initial array index: " << i << " " << strings[i];
        countWords(strings[i]);
        
    }  
    return 0;  
}  

countWords() 中的 Count + 1 仅在第一个结果中正确给出数字,然后将 " " 空格添加到字数统计中。

请先考虑用最容易理解的解决方案来回答。 (std::sort, 创建一个新函数, lambda)

【问题讨论】:

  • 你要排序什么?你的任务是找出句子中的最大单词数。
  • 点之间总是有一个词吗?如果是这样,那么最简单的方法不是计算点数并加1吗?样本测试数据是什么样的?
  • int len(string str) // length of the string - std::string 有一个名为 size() 的成员函数,您可以调用它来获取字符串的长度。还有一个叫length() 返回同样的东西。所以,不要使用len(str),而是使用str.size()
  • 请显示minimal reproducible example 的输入、预期和实际输出
  • @MpcHAG 另外,std::string 数组的用途是什么?除非您想实际存储句子单词以供以后使用,否则解决方案中不需要它们。这可能是让其他人对您想要输出的内容感到困惑的原因,因为您想要输出的只是最大数量,而不是实际使用的单词。请查看使用std::stringstream,您将看到与您现在所拥有的相比,该解决方案实际上会清洁多少。

标签: c++ string sorting max std


【解决方案1】:

您的代码没有意义。比如这个声明的含义

string strings[max];

不清楚。

并且要找到段落中句子中的最大单词数,无需按单词数对句子本身进行排序。

如果我理解正确的话,您需要的是如下内容。

#include <iostream>
#include <sstream>
#include <iterator>

int main() 
{
    std::string s;
    
    std::cout << "Enter a paragraph of sentences: ";
    
    std::getline( std::cin, s );
    
    size_t max_words = 0;
    
    std::istringstream is( s );
    std::string sentence;
    
    while ( std::getline( is, sentence, '.' ) )
    {
        std::istringstream iss( sentence );
    
        auto n = std::distance( std::istream_iterator<std::string>( iss ), 
                                std::istream_iterator<std::string>() );

        if ( max_words < n ) max_words = n;                             
    }
    
    std::cout << "The maximum number of words in sentences is " 
              << max_words <<  '\n';
    
    return 0;
}

如果进入段落

Here is a paragraph. It contains several sentences. For example, how to use string streams.

那么输出将是

The maximum number of words in sentences is 7

如果您还不熟悉字符串流,那么您可以使用成员函数findfind_first_offind_first_not_ofstd::string 类型的对象将字符串拆分为句子并计算句子中的单词.

【讨论】:

  • max_words = std::max(max_words, n); 也应该可以工作。
  • 字符串流暂时不适合我。但正在努力。谢谢,。
  • 很好,+1。不过有一个问题,std::distance 如何与istream_iterator 一起工作。我错过了“为什么”这个操作会返回字数。第二个参数是默认(空)字符串,所以我不知道为什么在这种情况下 ++iter 会从一个单词跳到下一个单词,更不用说为什么空字符串会停止这种“希望”
  • @LorahAttkins 对于流输入迭代器,它意味着输入流的结束。
【解决方案2】:

您的用例听起来像是减少了。本质上,您可以拥有一个状态机(解析器),当它遇到单词和句子分隔符时,它会遍历字符串并更新某些状态(例如计数器)。应特别注意角落情况,例如当有连续的​​多个空格或 >1 个连续的句号时 (.)。处理这些情况的简化如下所示:

int max_words_in(std::string const& str)
{
    // p is the current and max word count.
    auto parser = [in_space = false] (std::pair<int, int> p, char c) mutable {
        switch (c) {
        case '.': // Sentence ends.
            if (!in_space && p.second <= p.first) p.second = p.first + 1;
            p.first = 0;
            in_space = true;
            break;
        case ' ': // Word ends.
            if (!in_space) ++p.first;
            in_space = true;
            break;
        default: // Other character encountered.
            in_space = false;
        }
        return p; // Return the updated accumulation value.
    };

    return std::accumulate(
        str.begin(), str.end(), std::make_pair(0, 0), parser).second;
}

Demo

棘手的部分是决定如何处理退化的情况,例如"This is a , ,tricky .. .. string to count" 的输出应该是什么,其中不同类型的分隔符以任意方式交替出现。拥有解析逻辑的状态机实现允许您轻松调整解决方案(例如,您可以将“忽略列表”传递给解析器并更新默认情况以在 c 属于该列表时不重置 in_space 变量)。

【讨论】:

    【解决方案3】:
    vector<string> split(string str, char seperator)  // custom split() function
    {
        size_t i = 0;
        size_t seperator_pos = 0;
    
        vector<string> sentences;
        int word_count = 0;
    
    
        for (; i < str.size(); i++)
        {
            if (str[i] == seperator)
            {
                i++;
                sentences.push_back(str.substr(seperator_pos, i - seperator_pos));
                seperator_pos = i;
            }
        }
    
    
        if (str[str.size() - 1] != seperator)
        {
            sentences.push_back(str.substr(seperator_pos + 1, str.size() - seperator_pos));
        }
    
        return sentences;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2014-11-10
      • 2020-08-18
      • 1970-01-01
      • 2022-11-27
      • 2013-08-13
      • 1970-01-01
      相关资源
      最近更新 更多