我希望能够清除输入中的所有非唯一值。删除重复项后的子集应与输入相同。某些字符仍然留在输入中,未能将所有字符删除。看起来谓词内部的std::map大小也在减少。
我正在使用的std::remove_if()谓词是:
template<class T>
class RemovePredicate {
public:
RemovePredicate() : m_oldsize(0) {}
bool operator()(const T& value)
{
//
bool retval;
m_uniques[value] ='a'; // 'a' could be any value
cout << m_uniques.size() << endl;
retval = m_uniques.size() == m_oldsize;
m_oldsize = m_uniques.size();
return retval;
}
private:
std::map<T, char> m_uniques;
unsigned m_oldsize;
};
我设计了谓词,使得当我看到大小增加时,就没有遇到输入。因此,当大小不同时,我不会删除输入。当大小保持不变时,我又遇到了那个输入值,然后我会将其删除。
测试代码如下:
template<class T>
void print(T iterable)
{
for (auto c : iterable)
cout << c;
cout << endl;
}
int main(int argc, char** argv){
if (argc != 2)
return 1;
char * str= argv[1];
vector <char> charvec (str, str + strlen(str));
print(charvec);
auto itend = std::remove_if(charvec.begin(),
charvec.end(),
RemovePredicate<char>()
);
print(charvec);
// apply erase remove idiom
charvec.erase(itend, charvec.end());
print(charvec);
return 0;
}
一个示例输入是:
./remove_duplicates deadbeef
输出结果为
deabef
但是你可以看到输出结果中仍然有双重 'e'。 不过好消息是原始顺序得以保留。
我做错了什么?
RemovePredicate
中使用std::set<T>
而不是std::map
。您只需检查set<T>::insert
的返回值即可查看要插入的值是否已存在于集合中。 - Steve Lorimerunordered_set<T>
。 - Ben Voigtremove_if
本质上首先调用find_if
查找要删除的第一个元素,传递谓词的副本,然后从那里开始进行。此外,remove_if
不能保证按顺序处理输入范围。 - T.C.