如何从字符串向量 c++ 而不是新向量过滤

How to filter from string vector c++ instead of new vector

本文关键字:向量 新向量 过滤 字符串 c++      更新时间:2023-10-16

在C++中,我从向量匹配FirstAndLast开始,它充满了与某些条件匹配的单词(基于userInput)。平均而言,它非常大,所以我对其应用过滤器并创建一个向量来存储过滤的内容。我觉得这并不优雅;我想过滤(如 F# 列表)而不是制作新向量。

换句话说,我希望有一个向量被一遍又一遍地过滤而不创建新的向量。

My code's data flow :: matchingFirstAndLast |> sequenced |> appropriateLength |> finalSuggestions`

我的代码(如果需要)

vector<finalwords> compute      (string userInput,
                                 vector<string>dictionary,
                                 vector<string>popular,
                                 vector<string>keyboard_layout)
{
  //matchingFirstAndLast will hold words with the same first and last letter as the input string
  vector<string>matchingFirstAndLast;
  int inputLength = userInput.length();
  //for every word in the big dictionary vector, look for first and last letter similarites
  for (string &x : dictionary)
    if (userInput[0] == x.front() && userInput[inputLength - 1] == x.back())
      matchingFirstAndLast.push_back (x);
  //sequenced will hold words whose letters are found in sequence in the userInput string
  vector<string>sequenced;
  for (string &x : matchingFirstAndLast)
    if (FoundInSequence (userInput, x))
      sequenced.push_back (x);
  //determine the minimum word length based on the number of times the string changes
  //rows on the keyboard.
  int minLength = GetMinWordLength (userInput, keyboard_layout);
  //appropriateLength will hold all words longer than the minLength
  vector<string>appropriateLength;
  for (auto &x : sequenced)
    if (x.length() > minLength || minLength < 0)
      appropriateLength.push_back (x);
  vector<finalwords> finalSuggestions;
  for (string &x : appropriateLength)
    if (find (popular.begin(), popular.end(), x) != popular.end()) //word found in popular.txt
      finalSuggestions.push_back (finalwords (x, true, true, edit_distance (userInput, x)));
    else
      finalSuggestions.push_back (finalwords (x, false, true, edit_distance (userInput, x)));
  //sort the returned vector by most popular first
  sortResults (finalSuggestions);
  return finalSuggestions;
}//end compute(...)

例如,在python中,这是可能的

suggestions = filter(lambda x: x[0] == path[0] and x[-1] == path[-1], WORDS)
suggestions = filter(lambda x: match(path, x), suggestions)
suggestions = filter(lambda x: len(x) > min_length, suggestions)

这永远不会将"筛选"的数据存储到新容器中。

就像python示例^一样,我想在C++中做到这一点

"

过滤器"有点模棱两可。 从我的角度来看,当你说你试图"过滤"一个vector对我来说,这意味着你想创建另一个vector,只使用原始列表中的一些元素。 但是你的帖子文本清楚地表明这不是你想要的。 所以我的结论是,你真正追求的是vector中元素的选择性迭代。 换句话说,您希望循环访问列表中的元素,但只对其中一些元素执行操作。

如果是这样的话,那么我建议使用虚构的 Std Lib 算法,for_each_if . 我说虚构是因为没有这样的算法,但我过去已经实现过它,这并不难。

沿着这些思路应该做一些事情(未经测试):

template <typename InIt, typename Predicate, typename UnaryFunction>
UnaryFunction for_each_if (InIt first, InIt last, UnaryFunction fn, Predicate pr)
{
  for (; first != last; ++first)
  {
    if (pr (*first))
      fn (*first);
  }
  return fn;
}

使用它类似于使用 std::for_each ,除了您还像使用 copy_if 一样指定谓词。 假设 C++11,您可以使用 lambda 完成所有这些操作。

考虑实现您自己的迭代器类型,该迭代器将返回与一组谓词对应的字符串。伪代码示例:

struct iter {
    std::vector<Predicate> predicates;
    std::vector<string>&   values;
    int currentValue = 0;
    string nextValue() {
        return values[currentValue++];
    }
    bool hasValue() {
        while (currentValue < values.count() {
            bool found = true;
            for (auto& pred : predicates)
                if (!pred(values[currentValue])) {
                    ++currentValue; found = false; break;
                }
            if (found) return true;
        }
        return false;
    }
};

另一方面,您可以搜索 LINQ for C++ 的某些实现。我自己灌输了一个:github 它不用于生产用途,但您可能会发现一些有趣的想法。