【问题标题】:Unable to print the elements of a set of vector in STL无法在 STL 中打印一组向量的元素
【发布时间】:2018-07-24 11:39:13
【问题描述】:

我是 STL 地图和矢量的新手。我正在尝试打印向量集中存在的元素。最后一个 for 循环用于打印元素。代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
    int arr[]={2,0,2,1,4,3,1,0};

    vector<int> v;
    set< vector<int> > st;
    //set<int> temp;
    int init=0,fin=0;
    for(int i=0;i<8;++i){
        if(find(v.begin(),v.end(),arr[i])==v.end()){//if(temp.find(arr[i])==temp.end()){
            v.push_back(arr[i]);//temp.insert(arr[i]);

        }
        else{
            st.insert(v);
            v.clear();//temp.clear();
            v.push_back(arr[i]);//temp.insert(arr[i]);
        }

    }
    set<vector<int> >::iterator itr;
    vector<int>::iterator str;
    for(itr=st.begin();itr!=st.end();++itr){
        for(str=itr->begin();str!=itr->end();++str){
            cout<<*str<<" ";
        }
        cout<<endl;
    }
    return 0;

}

错误是:

a.cpp:26:11: error: no viable overloaded '='
                        for(str=itr->begin();str!=itr->end();++str){
                            ~~~^~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/iterator:1258:7: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from '__wrap_iter<const_pointer>'
      to 'const __wrap_iter<int *>' for 1st argument
class __wrap_iter
      ^
a.cpp:34:2: error: unknown type name 'a'
        a.cpp:26:10: error: no viable overloaded '='
        ^
a.cpp:34:3: error: cannot use dot operator on a type
        a.cpp:26:10: error: no viable overloaded '='

【问题讨论】:

  • 宣扬 using namespace std; 的网站,尤其是 typedef long long ll;#include&lt;bits/stdc++.h&gt; 是应该避免的网站。
  • 可以说这些只是浪费时间。请阅读这些C++ books。更好的投资回报率。
  • 查找“基于范围的 for 循环”。
  • @Jacob 因为它什么也没教你。它所教的东西,是以错误的方式来做的。没有竞争性编程这样的东西。
  • @Jacob 这是浪费时间,因为节省几次击键完全无关紧要 - 打字不是编写代码时花费时间的地方 - 思考才是。而且您会失去可读性 - 这重要。

标签: c++ vector stl set


【解决方案1】:

您的 str 迭代器必须是 const,因为不可能改变集合的元素。

vector<int>::const_iterator str;

我不是auto 的忠实拥护者,但这是一个使用它的场合,你不需要知道迭代器类型是什么

for (auto str = itr->begin(); str != itr->end(); ++str)

【讨论】:

  • 为什么?我如何知道何时使用 const 何时不使用?
  • @Jacob : std::set iterators are constant iterators,因此不能用于改变元素。
  • @Jacob :阅读我发布的链接中的 Notes 部分。不,这并非适用于所有容器 - std::set 的特殊之处在于该值也是键(用于排序),因此无法修改。
  • @Jacob 删除原始文件并插入新文件。只有通过insert 才能知道集合是否已经包含该元素。
  • @Jacob :你不能(除非你使用mutable)。也许您需要的是一个不同的容器 - 例如。 std::map.
【解决方案2】:

如果你的编译器是 C++ 11 兼容的,而不是 set&lt;vector&lt;int&gt; &gt;::iterator itr;...,试试这个 - 它更干净:

  for ( const auto& v : st )
    for ( const auto& i : v )
      cout << i << " ";

阅读here 了解autohere 了解愤怒。

[编辑]

“那么,这是否会使元素暂时在循环内部而不是稍后成为 const?”

set元素在任何时候都是常量,否则唯一性不成立。

* 集合迭代器的操作符被定义为一个返回 常量引用 到迭代器当前元素的函数;这就是您不能修改元素的原因。并以这种方式进行保护,否则无法保证唯一性约束。

设置{1, 2, 3} 并假设您正在将1 更改为2。结果集 {2, 2, 3} 不再是 2 的集,它不是唯一的。

相反,如果您先删除元素{1, 2, 3} - {1} = {2, 3},然后尝试插入修改后的元素{2, 3} + {2},您将得到正确的集合:{2, 3} for 2 is not inserted,因为它已经存在.

【讨论】:

  • 这里需要 const 吗?如果我删除它怎么办?
  • @Jacob "set 是一个关联容器,其中包含一组有序的 Key 类型的唯一对象" 如何更改集合中的元素并保证唯一性同时?正确的做法是:移除元素并尝试重新插入修改后的元素。毕竟set 的目的是唯一性。
  • @Jacob 您是否想学习如何编程或如何打代码高尔夫?最小特权原则意味着一切都应该是 const 除非你需要改变它。
  • @Jacob 如果你删除const,什么都不会发生。这只是一种习惯:“我无意修改vi。您仍然无法更改元素,因为 vi 迭代器的类型是 const 迭代器。也许你对const 对象和const_iterators 感到困惑。常量对象不能被修改,但常量迭代器不是常量对象:它们是常量对象的迭代器
  • 那么,这是否会使元素暂时在循环内而不是以后成为 const ?
猜你喜欢
  • 1970-01-01
  • 2021-01-12
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2023-04-10
  • 2018-06-26
  • 2016-10-11
  • 2010-09-20
相关资源
最近更新 更多