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

时间:2015-04-20 16:37:24

标签: c++ vector

在C ++中,我从一个vectorFirstAndLast开始,它填充了符合某些条件的单词(基于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 ++中使用某种方法

2 个答案:

答案 0 :(得分:1)

&#39;过滤器&#39;有点暧昧。从我的角度来看,当你说你正试图过滤&#39;一个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,您可以使用lambdas完成所有这些操作。

答案 1 :(得分:1)

考虑实现自己的迭代器类型,它将返回与某些谓词集相对应的字符串。 示例伪代码:

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这不是生产用途,但你可能会发现一些有趣的想法。