【问题标题】:C++ Usage of set, iterator, find line where duplicate was foundC++ 使用集合、迭代器、查找重复项的行
【发布时间】:2015-08-05 16:37:44
【问题描述】:

程序将不同的字符串添加到集合中。迭代器检查某个字符串的集合,我想要实现的是获取迭代器找到这个特定字符串的行。是否有可能用一组来获得这个,还是我必须创建一个向量?我使用集合的原因是因为我也不想最后有重复。我知道这有点令人困惑,希望你能理解。

编辑:如果发现重复,我想获取集合中已经存在的原始元素的行号

#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <atlstr.h>
#include <sstream>

using namespace std;  

int _tmain(int argc, _TCHAR* argv[])
{
set<string> test;
set<string>::iterator it;
vector<int> crossproduct(9, 0);

for (int i = 0; i < 6; i++)
{
    crossproduct[i] = i+1;
}

crossproduct[6] = 1;
crossproduct[7] = 2;
crossproduct[8] = 3;


for (int i = 0; i < 3; i++)
{
    ostringstream cp; cp.precision(1); cp << fixed;
    ostringstream cp1; cp1.precision(1); cp1 << fixed;
    ostringstream cp2; cp2.precision(1); cp2 << fixed;

    cp << crossproduct[i*3];
    cp1 << crossproduct[i*3+1];
    cp2 << crossproduct[i*3+2];

    string cps(cp.str());
    string cps1(cp1.str());
    string cps2(cp2.str());

    string cpstot = cps + " " + cps1 + " " + cps2;

    cout << "cpstot: " << cpstot << endl;

    it = test.find(cpstot);     

    if (it != test.end())
        {
            //Display here the line where "1 2 3" was found
            cout << "i: " << i << endl;
        }


    test.insert(cpstot);
}

set<string>::iterator it2;

for (it2 = test.begin(); it2 != test.end(); ++it2)
{
    cout << *it2 << endl;
}

cin.get();

return 0;
}

【问题讨论】:

  • 你到底想做什么。您的问题不清楚。
  • 顺便说一句:insert 返回一个对,其中包含 first= 对插入元素的迭代器和 second= bool 如果元素已插入则为 true,如果已存在则为 false。所以if (test.insert(cpstot).second){cout &lt;&lt; "i: " &lt;&lt; i &lt;&lt; endl;} 将替换test.findit != test.end()
  • 问题:你要原件的行号还是找到的重复件的行号?
  • 我想要集合中已经存在的原始元素的行号(这里应该是第 0 行,因为第 0 行是“1 2 3”,第 1 行是“4 5 6”并且然后第 3 行再次 "1 2 3")

标签: c++ iterator set


【解决方案1】:

“行号”对于std::set&lt;string&gt;来说意义不大, 因为当您向集合中添加更多字符串时,您可能会更改 迭代现有字符串的顺序 (与set::set 模板一样多的“行号” 自己会给你)。

这里有一个可能效果更好的替代方案: std::map&lt;std::string, int&gt; test。 您使用它的方式是在某处保留一个“线路计数器”n。 每次你需要在你的集合中加入一个新的字符串cpstot, 你有这样的代码:

  std::map<std::string>::iterator it = test.find(cpstot);
  if (it == test.end())
  {
    test[cpstot] = n;
    // alternatively, test.insert(std::pair<std::string, int>(cpstot, n))
    ++n;
  }
  else
  {
    // this prints out the integer that was associated with cpstot in the map
    std::cout << "i: " << it->second;

    // Notice that we don't try to insert cpstot into the map in this case.
    // It's already there, and we don't want to change its "line number",
    // so there is nothing good we can accomplish by an insertion.
    // It's a waste of effort to even try.
  }

如果您在开始将任何字符串放入test 之前设置了n = 0,那么 (并且不要以任何其他方式混淆n 的值) 那么你最终会在“行号”0、1、2等处得到字符串。 在testn 中将是存储在test 中的字符串数。

顺便说一句,std::map&lt;std::string, int&gt;::iteratorstd::set&lt;std::string&gt;::iterator 保证会遍历 首次插入它们的顺序中的字符串。 相反,您将得到的是以任何顺序排列的字符串 模板的比较对象放置字符串值。 (我认为默认情况下您会按字典顺序将它们取回, 即“字母化”。) 但是当您将每个字符串的原始“行号”存储在 std::map&lt;std::string, int&gt; test,当你准备好了 打印出可以复制字符串-整数对的字符串列表 从test 到一个新对象std::map&lt;int, std::string&gt; output_sequence, 现在(假设您不覆盖默认比较对象) 当你遍历output_sequence 你会得到它 内容按行号排序。 (然后您可能想要获取字符串 来自迭代器的second 字段。)

【讨论】:

    猜你喜欢
    • 2012-07-03
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 2012-04-19
    • 2018-01-30
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    相关资源
    最近更新 更多