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

时间:2014-12-10 17:05:11

标签: c++

我正在使用教科书,"原理与实践使用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 for循环中做了一些奇怪的事情,而且我已经用几种方式重新安排了它,但似乎无法弄清楚如何恰到好处地调整它。我已经让它只是跳过重复的单词,我已经能够跳过单个字符串而不是带字符串的向量。

如果我输入

,这是它给我的输出

是是测试否设置设置测试lol,如果这样做

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

2 个答案:

答案 0 :(得分:0)

许多方法之一:

#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;
}

答案 1 :(得分: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