好吧,我一直在撞墙。有时当代码运行时,我遇到错误“Expression:vector erase iterator outside range”。这是一个间歇性的问题。假设它与随机生成到向量中的数字有关。要获得错误,代码可能必须运行多次。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
template <class T> class set
{
public:
void add(T newElement);
void remove(set<T> newElement, int pos);
friend set<T> operator-(set<T> set1, const set<T> set2){
set<T> result;
result = set1;
for (int i = 0; i < set1.setVec.size(); i++){
for (int j = 0; j < set2.setVec.size(); j++){
if (set1.setVec[i] == set2.setVec[j]){
result.remove(set1, i);
}
}
}
return result;
}
friend set<T> operator&(const set<T>& set1, const set<T> set2){
set<T> result;
for (int i = 0; i < set1.setVec.size(); i++){
for (int j = 0; j < set2.setVec.size(); j++){
if (set1.setVec[i] == set2.setVec[j]){
result.add(set1.setVec[i]);
}
}
}
return result;
}
friend set<T> operator|(const set<T>& set1, const set<T> set2){
set<T> result;
result = set1;
for (int i = 0; i < set2.setVec.size(); i++){
result.add(set2.setVec[i]);
}
return result;
}
friend ostream& operator<< (ostream &output, const set<T> setOut){
output << endl;
for (int i = 0; i < setOut.setVec.size(); i++){
output << setOut.setVec[i] << endl;
}
return output;
}
private:
vector<T> setVec;
};
template <class T>
void set<T>::add(T newElement){
setVec.push_back(newElement);
}
template <class T>
void set<T>::remove(set<T> newElement, int pos){
vector<T>::iterator it;
it = setVec.begin();
this->setVec.erase(it+3);
}
int main(){
srand(time(NULL));
cout << "=====INTEGERS=====" << endl;
set<int> s;
s.add(rand() % 10 + 1);
s.add(rand() % 10 + 1);
s.add(rand() % 10 + 1);
s.add(rand() % 10 + 1);
s.add(rand() % 10 + 1);
s.add(rand() % 10 + 1);
cout << "Set 1: " << s << endl;
set<int> s2;
s2.add(rand() % 10 + 1);
s2.add(rand() % 10 + 1);
s2.add(rand() % 10 + 1);
s2.add(rand() % 10 + 1);
s2.add(rand() % 10 + 1);
s2.add(rand() % 10 + 1);
cout << "Set 2: " << s2 << endl;
set<int> s3;
s3 = s | s2;
cout << "Set 1 Union Set 2: " << s3 << endl;
s3 = s & s2;
cout << "Set 1 Intersect Set 2: " << s3 << endl;
s3 = s - s2;
cout << "Set 1 Difference Set 2: " << s3 << endl;
system("PAUSE");
return 0;
}
基本上,我只是尝试在c ++中为模板化类重新创建集合符号。我已经在这约6个小时。任何帮助将不胜感激。
答案 0 :(得分:2)
您的remove
看起来错了:
template <class T>
void set<T>::remove(set<T> newElement, int pos){
vector<T>::iterator it;
it = setVec.begin();
this->setVec.erase(it+3); // <--------------- maybe (it+pos) ??
}
在删除元素时,您必须注意在删除元素时大小会发生变化,即:
friend set<T> operator-(set<T> set1, const set<T> set2){
set<T> result;
result = set1; // here result.size == set1.size
for (int i = 0; i < set1.setVec.size(); i++){
for (int j = 0; j < set2.setVec.size(); j++){
if (set1.setVec[i] == set2.setVec[j]){
result.remove(set1, i); // now result.size is smaller
}
}
}
return result;
}
使用迭代器可能更容易。类似的东西:
friend set<T> operator-(set<T> set1, const set<T> set2){
set<T> result;
result = set1;
for (auto result::iterator it = result.first();it != result.end();/*empty*/){
if (hasToBeRemoved(it)){
result.remove();
} else {
++it;
}
}
你也可以在没有迭代器的情况下做同样的事情,但你必须考虑,如果你在第3位搜索元素,那么下一个元素实际上是在第3位(而不是4)。