如何用句子填充数组?

时间:2019-02-21 15:47:41

标签: c++ algorithm parsing

例如,我有一个句子“ I am Piet”。我想以I [0],am [1] Piet [2]的方式将此句子填充到数组中。以下是我编写的代码。问题在于该句子填充在数组的每个元素中。

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

// function to populate my array
void populateMyArray(string*myArray, string sentence, int size)
{
for (int i = 0; i < size; i++)
{
*myArray = sentence;
    myArray++;
}
}

// function to count works in the sentence
int countWords(string x)
{
int Num = 0;
char prev = ' ';

for (unsigned int i = 0; i < x.size(); i++) {

    if (x[i] != ' ' && prev == ' ') Num++;

    prev = x[i];
}
return Num;
}

int main()
{
string sentence1;

cout << "Please enter a line of text:\n";
getline(cin, sentence1);

int nWords1 = countWords(sentence1);

string *arr1 = new string[nWords1];

populateMyArray(arr1, sentence1, nWords1); //populate array1

for (int i = 0; i < nWords1; i++)
{
    cout << "sentence one: " << arr1[i] << "\n";
}

system("PAUSE");
}

4 个答案:

答案 0 :(得分:0)

您可以使用vector来保存数据,并且每次使用两个单词之间的空格时,会将每种字符串类型存储到vector数组中

private static void GetModifyingUsersFile(DriveService driveService, string fileId)
{
    var revisions = driveService.Revisions.List(fileId).Execute()?.Revisions;

    if (revisions != null)
    {
        foreach (var revision in revisions)
        {
            var requestRevision = driveService.Revisions.Get(fileId, revision.Id);
            requestRevision.Fields = "lastModifyingUser"; // I can get only lastModifyingUser. I need get all users.
            var lastModifyingUser = requestRevision.Execute();

            Console.WriteLine(
                $"Revision: {revision.ModifiedTime}, revisionid: {revision.Id}, user: {lastModifyingUser.LastModifyingUser?.EmailAddress}");
        }
    }
    else
    {
        Console.WriteLine("No Revisions");
    }
}

答案 1 :(得分:0)

代替使用数组,而使用list。这样,您就不必担心单词大小可变或万一单词或句子过长而引起的溢出。相反,您可以执行以下操作:

std::vector

对于#include <iostream> #include <string> #include <vector> #include <sstream> int main() { // Get all words on one line std::cout << "Enter words: " << std::flush; std::string sentence; getline(std::cin, sentence); // Parse words into a vector std::vector<std::string> words; std::string word; std::istringstream iss(sentence); while( iss >> word ) { words.push_back(word); } // Test it out. for(auto const& w : words) { std::cout << w << std::endl; } } 的例句,您将具有:I like cats and dogs equallywords[0] = I,依此类推。

答案 2 :(得分:0)

如何像程序员一样思考

我们需要的第一件事是定义单词的开头或单词和结尾。您可能会认为单词的开头是一个非空格,后跟一个空格,单词的结尾是一个非空格,后跟一个空格。但是这些定义是错误的,因为它们忽略了字符串开头或结尾出现单词的可能性。单词开头的正确定义是字符串开头的非空格或前面带有空格的非空格。同样,单词的末尾是字符串末尾的非空格,或者是非空格后跟空格。

现在我们有了定义,可以通过两个函数捕获它们。将复杂的问题分解成更小的部分非常重要,而做到这一点的方法是编写函数(或类)。

bool beginning_of_word(string str, int index)
{
    return str[index] != ' ' && (index == 0 || str[index - 1] == ' ');
}

bool end_of_word(string str, int index)
{
    return str[index] != ' ' && (index == str.size() - 1 || str[index + 1] == ' ');
}

现在我们越来越近了,但是我们仍然需要找到单词的下一个开头或单词的下一个结尾的想法,因此我们可以遍历句子一次找到每个单词。这是用于查找单词的下一个开始和下一个结束的两个功能。它们从给定的索引开始,然后找到下一个索引,即单词的开头或结尾。如果找不到这样的索引,则它们返回-1。

int next_beginning_of_word(string str, int index)
{
    ++index;
    while (index < str.size())
    {
        if (beginning_of_word(str, index))
            return index; // index is a start of word so return it
        ++index;
    }
    return -1; // no next word found
}

int next_end_of_word(string str, int index)
{
    ++index;
    while (index < str.size())
    {
        if (end_of_word(str, index))
            return index; // index is an end of word so return it
        ++index;
    }
    return -1; // no next word found
}

现在,我们有了一种遍历句子中单词的方式,我们准备编写主循环。我们使用substr将单词从句子中分解出来,substr接受两个参数:单词开头的索引和单词的长度。我们可以通过从开头减去开头再加上一个来获得单词的长度。

int populateMyArray(string* array, string sentence)
{
    // find the first word
    int start = next_beginning_of_word(sentence, -1);
    int end = next_end_of_word(sentence, -1);
    int count = 0;
    while (start >= 0) // did we find it?
    {
        // add to array
        array[count] = sentence.substr(start, end - start + 1);
        ++count;
        // find the next word
        start = next_beginning_of_word(sentence, start);
        end = next_end_of_word(sentence, end);
    }
    return count;
}

现在,为了获得额外的信用,我们可以使用countWords重写next_beginning_of_word

int countWords(string sentence)
{
    int start = next_beginning_of_word(sentence, -1);
    int count = 0;
    while (start >= 0)
    {
        ++count;
        start = next_beginning_of_word(sentence, start);
    }
    return count;
}

请注意countWordspopulateMyArray函数的相似性,循环非常相似。那应该给你信心。

这是程序员的工作方式,当您遇到无法解决的太复杂的问题时,请将其分解为较小的部分。

答案 3 :(得分:0)

如果我理解正确,您正在尝试将输入句子拆分为单词。

您可以这样做:

case 2:
{
    int minVal = 0;
    int maxVal = list.Count - 1;
    int removeGroc = GetIntFromUser($"Enter the item to remove ({minVal} - {maxVal}): ",
        i => i >= minVal && i <= maxVal);
    list.RemoveAt(removeGroc);
    break;
}