删除具有特定字符要求的字符串向量的元素

时间:2018-03-18 08:41:22

标签: c++ string vector char

我目前正在编写一个程序,该程序由一个字符串向量组成,这些字符向量中包含一些字母,所有字母都在同一位置。

例如,我的矢量可能如下所示:

vector<string> v = { "CRYPT", "CYSTS", "WRYLY", "TRYST" };

这个想法是猜到了一封信,即&#34; Y&#34;在这种情况下,程序选择向量中的第一个字符串,遍历字符串向量并保留Y中与向量中第一个字相同位置的字。在这种情况下,程序会选择&#34; CRYPT&#34;。现在,我需要程序通过字符串向量并删除与第一个单词&#34; CRYPT&#34;相比在某个附加位置具有该字母重复的任何单词。同时保留有&#34; Y&#34;在相同的确切位置,除了第一个单词之外,其他地方没有其他地方#Y; Y&#34; s。因此,在删除任何其他重复项并保持其他单词位于相同位置后,我需要向量的输出看起来像这样。

vector<string> v = { "CRYPT", "TRYST" };

我正在考虑循环遍历向量并循环遍历每个字符串以遍历每个字符并检查但是当循环遍历它时我无法从向量中移除元素或者它将导致问题。也许对vector使用remove_if但不确定如何编写谓词。任何帮助表示赞赏!谢谢!

2 个答案:

答案 0 :(得分:1)

一种方法是定义一个函子,用于评估给定字符串是否与复制到结果向量的条件匹配。然后,仿函数与copy_if一起使用。

类似的东西:

#include <iostream>
#include <vector>
#include <algorithm>

struct do_copy
{
    do_copy(char m) : match(m) {}
    char match;
    size_t pos;
    bool found {false};

    bool operator()(const std::string& s)
    {
        if (found)
        {
            return s.size() > pos && 
                   s[pos] == match && 
                   std::count(s.begin(), s.end(), match) == 1;
        }

        for (int p = 0; p < s.size(); ++p)
        {
            if (s[p] == match)
            {
                pos = p;
                found = true;
                return true;
            }
        }
        return false;
    }
};

int main() {
    std::vector<std::string> v = { "CRYPT", "CYSTS", "WRYLY", "TRYST" };
    std::vector<std::string> r;
    char guess = 'Y';

    std::copy_if(v.begin(), 
                 v.end(), 
                 std::back_inserter(r), 
                 do_copy(guess));

    // Print the result
    std::cout << r.size() << " elements found:" << std::endl;
    for (auto& s : r) 
    {
        std::cout << s << std::endl;
    }

    return 0;
}

输出:

2 elements found:
CRYPT
TRYST

答案 1 :(得分:0)

让我们从您的向量开始,跟随猜测的角色和您的&#34; main&#34;串

vector<string> v = { "CRYPT", "CYSTS", "WRYLY", "TRYST" };
string mainStr = v[0];
char guessed = 'Y';

正如你所说,如果他们不遵守我们的规则,我们需要迭代所有字符串并删除它们。所以就这样做,但我们不会用#34; for_each&#34;迭代,我们将使用简单的循环

for (size_t i = 1; i < v.size(); ++i) {
    for (size_t j = 0; j < v[i].size(); ++j) {
        if (v[i][j] == guessed && (j >= mainStr.size() || mainStr[j] != guessed) 
           || j < mainStr.size() && mainStr[j] == guessed && v[i][j] != guessed) {
            v.erase(find(v.begin(), v.end(), v[i]));
            --i;
            break;
        }
    }
}

在内循环中,正如您所看到的,当我们删除我们不想在集合中看到的字符串时,我们只需退回我们的&#34; iterator&#34;,所以我们不要破坏任何向量条件,我们可以继续遍历字符串。

最后你可以简单地看到,我们做得对

for (auto& str : v) {
    cout << str << '\n';
}