C++:如何正确堆叠循环迭代

C++: How to stack for loop iterations properly

本文关键字:循环 迭代 何正确 C++      更新时间:2023-10-16

我正在编写教科书"使用C++的原则和实践,第二版"。我在关于向量的部分中,并且在堆叠 for 循环以获取我正在寻找的输出时遇到问题。

// simple dictionary: list of sorted words
int main() {
  vector < string > words;
  for (string temp; cin >> temp;) // read whitespace-separated words
    words.push_back(temp); // put into vector
  cout << "nNumber of words: " << words.size() << 'n';
  sort(words); // sort the words
  vector < string > disliked = {"Test", "Set"};
  for (int i = 0; i < words.size(); ++i)
    if (i == 0 || words[i - 1] != words[i]) {
      for (int b = 0; b < disliked.size(); ++b)
        if (i == 0 || words[i] == disliked[b])
          cout << words[i] << "n";
    }
}

这意味着跳过打印重复的单词,并将不喜欢的向量视为过滤的单词并排除它们。我肯定我正在用我的 for 循环做一些奇怪的事情,我已经以多种方式重新排列了它,但似乎无法弄清楚如何正确调整它。我已经让它只跳过重复的单词,并且我已经能够让它跳过单个字符串,但不能跳过带有字符串的向量。

这是我输入时给我的输出

是 测试 否 设置 设置 测试 哈哈 如果这有效

字数:12设置设置测试程序以退出代码结束:0

这是循环中的最小更改:

  bool ok;
  for (int i = 0; i < words.size(); ++i)
    if (i == 0 || words[i - 1] != words[i]) {
        ok = true;
        for (int b = 0; b < disliked.size(); ++b)
            if (words[i] == disliked[b]) ok = false;
        if (ok) cout << words[i] << "n";
    }

然后输出是(我注释掉了排序...

yes
no
lol
if
this
works

众多方法之一:

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
int main() {
    // simulates reading from standard input
    const vector<string> input_words = { "the", "quick", "brown", "mega", "fox", "jumps", "over", "the", "lazy", "brown", "dog" };
    // the set of disliked words
    const set<string> disliked_words = { "the", "mega" };
    // all containers can be constructed with any compatible iterator range
    // sets are automatically sorted and de-duplicated        
    set<string> filtered_words { input_words.begin(), input_words.end() };
    // c++11 range-based for loop. If you're using c++03 use the equivalent
    // for(it = disliked_words.begin() ; it != disliked_words.end() ; ++it) ...
    for (const auto& not_liked : disliked_words) {
        filtered_words.erase(not_liked);
    }
    // copy each filtered word to standard out with a newline separator        
    copy(filtered_words.begin(), filtered_words.end(), ostream_iterator<string>(cout, "n"));
    return 0;
}

如果你想保持输入单词的相对顺序,你需要一个稳定的过滤函数:

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <iterator>
using namespace std;
// make a copy of the vector, removing duplicates and disliked words.
// relative order of remaining words is maintained.
vector<string> deduplicated_and_filtered_copy_stable(const vector<string>& input, const set<string>& disliked)
{
    vector<string> result;
    set<string> seen;
    copy_if(begin(input),
            end(input),
            back_inserter(result),
            [&](const string& s) {
                return (!disliked.count(s)) && seen.insert(s).second;
            });
    return result;
}
int main() {
    const vector<string> input_words = { "the", "quick", "brown", "mega", "fox", "jumps", "over", "the", "lazy", "brown", "dog" };
    const set<string> disliked_words = { "the", "mega" };
    auto filtered_words = deduplicated_and_filtered_copy_stable(input_words, disliked_words);
    copy(filtered_words.begin(), filtered_words.end(), ostream_iterator<string>(cout, "n"));
    return 0;
}