c++ 删除向量中的字符串

gkn4icbw  于 2023-11-19  发布在  其他
关注(0)|答案(7)|浏览(97)

我有一个充满字符串的向量
向量consistentWords包含4个字符串
1.德国国防军

  1. eedf
  2. fedf
    1.海德夫
    现在我想删除所有单词不以字母d开头的字符串
    然而,它最终只是删除了eedf和hedf,我留下的结果是
    1.德国国防军
  3. fedf
    我的代码:
for(int q=0; q<consistentWords.size(); q++)
    {
        string theCurrentWord = consistentWords[q];
        if(theCurrentWord[0] != 'd')
        {
            consistentWords.erase(consistentWords.begin()+q);
        }
    }

字符串
有什么想法吗?我只是不明白为什么它没有删除所有不以d开头的字符串。

vddsk6oq

vddsk6oq1#

首先,字符串对应于这些索引:

dedf 0
eedf 1
fedf 2
hedf 3

字符串
假设你删除了eedf(所以q == 1。删除后,向量看起来像

dedf 0
fedf 1
hedf 2


但是q会递增到2,完全跳过fedf。修复方法是稍微改变for循环:

for(int q=0; q<consistentWords.size();)
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        consistentWords.erase(consistentWords.begin()+q);
    }
    else
    {
        q++;
    }
}


或者类似的东西

rdrgkggo

rdrgkggo2#

您正在跳过元素。假设您需要删除元素5,6:当您删除元素5时,元素6变为元素5 -并且您跳过它,因为q增加到6,
更好的方法是仅在不删除元素时手动增加q

hiz5n14c

hiz5n14c3#

问题是你在同一次迭代中从vector中删除元素并增加索引q。所以在for循环的第二次迭代中,你从vector中删除"eedf",那么你的vector是["dedf", "fedf", "hedf"]q = 1。但是当你循环回for循环的开始时,q递增到2,所以接下来你会看到"hedf",跳过"fedf"。为了解决这个问题,你可以在从数组中删除一个元素时递减q,如下所示:

for(int q=0; q<consistentWords.size(); q++)
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        consistentWords.erase(consistentWords.begin()+q);
        --q;
    }
}

字符串
或者你可以使用迭代器:

vector<string>::iterator it = consistentWords.begin()
while(it != consistentWord.end())
{
    string theCurrentWord = consistentWords[q];
    if(theCurrentWord[0] != 'd')
    {
        it = consistentWords.erase(it);
    }
    else
    {
        ++it;
    }
}


注意,erase返回一个迭代器到你删除的元素之后。你必须重新分配it,因为当向量调整大小时它会失效。

8iwquhpp

8iwquhpp4#

当你擦除的时候,你不应该做q++,这样你就少了一个元素。

ykejflvf

ykejflvf5#

这个问题已经得到了回答,但你应该看看Erase-remove idiom
范例:

consistentWords.erase(
    std::remove_if(consistentWords.begin(), consistentWords.end(), 
    [](const std::string& s) -> bool { return (s[0] == 'd'); }),
    consistentWords.end());

字符串

nkcskrwz

nkcskrwz6#

删除该词:

consistentWords.erase(
    std::remove(consistentWords.begin(), consistentWords.end(), theCurrentWord),
    consistentWords.end()
);

字符串

ttcibm8c

ttcibm8c7#

如果你不能理解所有其他关于索引和跳过一个的答案,那么你真的可以创建一个新的向量,然后复制回来,或者只是使用一个双端队列。

新向量方法:

你遍历原始向量中的每个字符串。如果它以'd '开头,那么将其添加到新的向量中。你的答案就是新的向量。如果你希望原始向量包含数据,那么只需将其复制回来。

vector <string> newVec;
    for (int q = 0; q < consistentWords.size(); ++q) {
        if (consistentWords[q][0] == 'd') {
            newVec.push_back(consistentWords[q]);
        }
    }
//if needed, copy back with simple code at this point

字符串

Deque方法:

你把向量变成一个双端队列,然后像往常一样遍历每个字符串。如果它以'd '开头,那么把它加到后面,循环直到你完成。你的答案是原始的双端队列。

deque <string> consistentWords;
    bool first = true;
    string firstStr;
    for (int q = 0;;) {
        if (consistentWords[q][0] == 'd') {
            if (consistentWords[q] == firstStr) {
                break;
            }
            if (first == true) {
                first = false;
                firstStr = consistentWords[q];
            }
            consistentWords.push_back(consistentWords[q]);
        }
        else {
            consistentWords.pop_front();
        }
    }

相关问题