在输入中我想删除所有非唯一值。我希望删除双项后的子集与输入相同。不知何故,某些字符保留在输入中,但并非所有字符都被删除。谓词内的 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;
};
Run Code Online (Sandbox Code Playgroud)
我设计谓词的方式是,当我看到大小增加时,我还没有遇到输入。因此,当大小不同时,我不会删除输入。当大小保持不变时,我再次遇到该输入值,然后我将其删除。
测试这个的代码是:
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;
}
Run Code Online (Sandbox Code Playgroud)
输入示例是:
./remove_duplicates 死牛肉
输出给出
德阿贝夫
但正如您所看到的,输出中仍然有一个双“e”。但好的一面是,原来的顺序被保留了。
我究竟做错了什么?
无法保证对谓词的每次调用都是在函数对象的同一副本上进行的。
您需要安排副本共享单个map(或set或unordered_set),例如通过在更广泛的范围内声明map并保留引用,或者通过使用shared_ptr(因此函数对象作为一个组仍然拥有它)。