【问题标题】:Finding and deleting words in a string sentence在字符串句子中查找和删除单词
【发布时间】:2020-01-13 22:00:58
【问题描述】:

作为一个作业,我必须用 C++ 编写一个函数来删除句子中的一个单词。我们将句子本身作为字符串 std::string sentence 和要删除的单词的编号 int place

单词之间可以有多个空格,句子可以以空格结尾和开头。

例如:DeleteWord("Fox jumped over lazy dog", 2)
应该返回:"Fox over lazy dog"

问题是我只能使用 std::string size() 和 resize()。

我也应该只删除单词,而不是它周围的空格。

我已经写了一些代码,但输出不正确:我将所有单词放在一个数组中,然后在参数中删除一个,但是空格是一个大问题,因为它们也被放入数组中,因此我无法正确删除和打印它们。

您对如何解决这个问题有任何想法吗?谢谢!

到目前为止我的代码:

std::string DeleteWord(std::string sentence, int place){

    std::string retvalue;

    long long wordcounter = 0;
    long long spacecounter = 0;
    long long spacescounter = 0;

    int i = 0;
    int index = 0;

    for(int i=0; i<sentence.size(); i++){
        if((sentence[i]==' ') && (sentence[i+1]!=' ')) spacecounter++;
    }

    for(int i=0; i<sentence.size(); i++){
        if(sentence[i]==' ') spacescounter++;
    }

    std::string words[spacescounter+1];

    while(i<sentence.size()){
        if(sentence[i]!=' '){
            words[index] += sentence[i];
            i++;
        }
        else{
            index++;
            i++;
        }
    }

    sentence[place-1] = ' ';

    for(int i=0; i<=index; i++){
        retvalue+=words[i] + ' ';
    }

    return retvalue;
}

【问题讨论】:

标签: c++ string


【解决方案1】:

您不必计算空格或单词。您不必将单词存储在数组中。

如果前一个元素是空格而当前元素是非空格,则遍历句子并递减 place。如果place 为 0,则必须跳过该单词。否则将字符串复制到返回的字符串中。正如我在 cmets 中所说,它就像一个循环、一个变量、3 个 if 条件一样简单:

#include <iostream>
#include <string>

std::string DeleteWord(const std::string &sentence, int place){
    if (sentence.empty()) {
        return std::string();
    }

    auto isPreviousSpace = std::isspace(sentence[0]);
    if (!isPreviousSpace) {
        --place;
    }

    std::string retvalue;    
    for (const auto &c : sentence) {
        if (isPreviousSpace && !std::isspace(c)) {
            --place;
        }
        if (place != 0 || std::isspace(c)) {
            retvalue += c;
        }
        isPreviousSpace = std::isspace(c);
    }

    return retvalue;
}

int main()
{
    std::cout << DeleteWord("Fox   jumped  over lazy dog", 2);
    // Output is: "Fox     over lazy dog"
    return 0;
}

不带std::isspace 且不带 const ref 参数的 C++98 解决方案:

#include <iostream>
#include <string>

std::string DeleteWord(std::string sentence, int place){
    if (sentence.empty()) {
        return std::string();
    }

    bool isPreviousSpace = sentence[0] == ' ';
    if (!isPreviousSpace) {
        --place;
    }

    std::string retvalue;    
    for (unsigned int index = 0; index < sentence.size(); ++index) {
        if (isPreviousSpace && sentence[index] != ' ') {
            --place;
        }
        if (place != 0 || sentence[index] == ' ') {
            retvalue += sentence[index];
        }
        isPreviousSpace = sentence[index] == ' ';
    }

    return retvalue;
}

int main()
{
    std::cout << DeleteWord("Fox   jumped  over lazy dog", 2);
    // Output is: "Fox     over lazy dog"
    return 0;
}

【讨论】:

  • 您好,感谢您的回复。有什么办法可以交换“auto”和“const auto &c : sentence”?我正在使用 C++98 进行编码,并且希望有更简单的解决方案,因为我不理解它并且它根本无法编译。
  • 我添加了一个没有std::isspace的C++98解决方案
【解决方案2】:

我通过检查空格检查了 char 数组中的单词,并通过改变 '\0'(结束字符串)位置 o 通过移动数组来删除单词

#include <string>
#include <iostream>
#include <string.h>
//#include <stdio.h>

using namespace std;
string DeleteWord(string a,int index)
{
    int length=a.size();
    int pos;
    int word=1;
    char* s;
    s=new char[length];
    strcpy(s,a.c_str());
    for(int i=0; i<length; i++)
    {
        if(s[i]==' ' and i!=0 and s[i-1]!=' ')
            word++;
    }
    if(index>word)
    {
      delete [] s;
        return "error";
     }
    else
    {
        if(index==word)
        {
            pos=0;
            for(int i=length-1; i>=0; i--)
            {
                if(s[i]==' ')
                {
                    pos=i+1;
                    break;
                }
            }
            s[pos]='\0';
        }
        else
        {
            int wl=0;
            char pre=' ';
            word=0;
            pos=-1;
            bool found=false;
            for(int i=0; i<length; i++)
            {
                if(pre==' ' and s[i]!=' ')
                {
                    word++;
                    if(word==index){
                        found=true;
                        pos=i;
                    }
                }
                if(found==true)
                {
                    if(s[i]==' '){
                        break;
                        }
                    else
                        wl++;
                }

                pre=s[i];
            }
            for(int i=pos; i<length; i++)
                s[i]=s[i+wl];
        }
        string f=string (s);
        delete[] s;
        return string(f);
    }

}
int main()
{
    string str="Fox   jumped  over  lazy dog";
    cout<<DeleteWord(str,4)<<endl;
    return 0;
}

【讨论】:

  • 感谢您的回复。该函数必须返回字符串,因此它必须是 std::string 类型。此外,第一个参数也必须是 std::string,而不是字符。这些是任务的规则。
  • 我更改了代码。这应该尊重您的限制。
  • 我已编辑代码以删除可变长度数组
  • @ThomasSablik 现在代码应该适用于每个输入。
  • 但是当函数结束时变量应该被销毁。
【解决方案3】:

查找需要删除的单词的起始索引和结束索引,我分别称其为se,结果为:sentence[0:s-1] + sentence[e+1-&gt;sentence.size()-1]。我假设 place 的输入值是有效的(大于零并且等于或小于句子中的单词数)。你可以试试我的代码:

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

pair<int,int> startAndEndIndexOfWord(string sentence, int place){
    pair<int,int> startAndEnd;

    int currentWordIndex = 0;
    int startIndex = 0;
    int endIndex = 0;
    for(int i=0;i<sentence.size();i++){
        //meet a word
        if(sentence[i]!=' '){
            currentWordIndex += 1;
            if(currentWordIndex==place){//if it is the word need to be delete
                startIndex = i;
                //find ending index
                endIndex = sentence.size()-1; //just a default value
                for(int j=i+1;j<sentence.size();j++){
                    if(sentence[j]==' '){
                        endIndex = j-1;
                        break;
                    }
                }
                startAndEnd.first = startIndex;
                startAndEnd.second = endIndex;
                return startAndEnd;
            }
            else{
                i+=1;
                while(sentence[i]!=' ') i++; //ignore the current word
            }
        }
    }
}
string deleteWord(string sentence, int place){
    string result;
    pair<int,int> startAndEndIndex = startAndEndIndexOfWord(sentence,place);
    for(int i=0;i<startAndEndIndex.first;i++){
        result+=sentence[i];
    }
    for(int i=startAndEndIndex.second+1;i<sentence.size();i++){
        result+=sentence[i];
    }
    return result;
}
int main() {
    int place = 5;
    string sentence = "Fox   jumped  over lazy dog";
    string result = deleteWord(sentence,place);

    cout<<result;
    return 0;
}

【讨论】:

  • 您好,感谢您的回复。我不能使用除 之外的任何其他头文件,因此 无法使用。
猜你喜欢
  • 1970-01-01
  • 2013-03-09
  • 2021-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多