C++ 我需要一个std函数来检查向量中有多少元素恰好出现一次

C++ 我需要一个std函数来检查向量中有多少元素恰好出现一次,c++,vector,stl,C++,Vector,Stl,有什么STL函数可以做到这一点吗? 对于矢量: 4 4 5 5 6 7 预期输出应为2,因为有一个6和7 如果没有STL函数,您能帮我算一下经典版本吗?如果性能和内存对您来说无关紧要,请使用std::map(或无序版本)执行此任务: size_t count(const std::vector<int>& vec){ std::map<int,unsigned int> occurenceMap; for (auto i : vec){

有什么STL函数可以做到这一点吗? 对于矢量:

4 4 5 5 6 7
预期输出应为
2
,因为有一个
6和7


如果没有STL函数,您能帮我算一下经典版本吗?

如果性能和内存对您来说无关紧要,请使用
std::map
(或无序版本)执行此任务:

size_t count(const std::vector<int>& vec){
    std::map<int,unsigned int> occurenceMap;
    for (auto i : vec){
        occurenceMap[i]++;
    }

    size_t count = 0U;
    for (const auto& pair : occurenceMap){
        if (pair.second == 1U){
            count++;
        }
    }

    return count;
} 
size\u t计数(const std::vector&vec){
地图发生地图;
用于(自动i:vec){
发生图[i]++;
}
大小\u t计数=0U;
用于(常数自动和配对:发生映射){
如果(对秒==1U){
计数++;
}
}
返回计数;
} 

通过模板,它可以推广到任何容器类型和任何容器对象类型。

使用std::unique对唯一条目(ct_)进行计数,然后对原始条目(ct_)进行用户向量计数。差分ct_-ct_会给出答案


注意:只有在原始向量中相同的条目在一起时,这才有效。如果没有,您可能希望首先对向量进行排序。

我认为STL中没有用于排序的算法。您可以复制到
multimap
中,或者按照建议使用频率的
map
,但它会做额外的工作,这是不必要的,因为您的数组恰好被排序了。下面是一个简单的算法,它计算单个元素的数量,即在排序序列中只出现一次的元素

int previous = v.front();
int current_count = 0;
int total_singular = 0;
for(auto n : v) {
    if(previous == n)          // check if same as last iteration
        current_count++;       // count the elements equal to current value
    else {
        if(current_count == 1) // count only those that have one copy for total
            total_singular++;
        previous = n;
        current_count = 1;     // reset counter, because current changed
    }
}
if(current_count == 1)         // check the last number
    total_singular++;
如果使用有状态lambda,也可以使用
count\u,但我认为这不会使算法变得更简单。

使用算法:

std::size_t count_unique(const std::vector<int>& v)
{
    std::size_t count = 0;

    for (auto it = v.begin(); it != v.end(); )
    {
        auto it2 = std::find_if(it + 1, v.end(), [&](int e) { return e != *it; });
        count += (it2 - it == 1);
        it = it2;
    }
    return count;
}
std::size\u t count\u unique(const std::vector&v)
{
标准::大小\u t计数=0;
对于(自动it=v.begin();it!=v.end();)
{
auto it2=std::find_if(it+1,v.end(),[&](int e){returne!=*it;});
计数+=(it2-it==1);
it=it2;
}
返回计数;
}

问题不太清楚。您想计算向量中出现一次的元素数,对吗?“一个元素中有多少个”也可以计算有多少个
4
s…那么你的标题是错误的,你可能是指“有多少个元素恰好出现一次”。你是向量排序的吗?一种方法是std::sort,然后是std::unique,然后计算剩余的元素。可能有一个更快的C++标准库方法:但是,你可以把元素塞进一个集合并计算元素的数量。你期望输出应该是3,4,4,5,5,5,6,7?问题有点不清楚。选择一个:内存或速度,它们通常是正交的。@user5058813即使速度和内存很重要,最好还是使用您现有的,并且只有在真正需要时才进行优化。老实说,我怀疑这是您程序中的瓶颈。@tobi303不要过早地对代码感到悲观也很重要。该解决方案在内存占用、速度和所需代码行数方面都很差。现代CPU的瓶颈是内存速度,而不是指令吞吐量,因此使用的内存越多,代码运行越慢。红黑树也是对缓存最不友好的数据结构之一。@MaximeGroushkin自己不要太过相似。您可以配置map allocator从堆栈中分配块,从映射中逐渐删除非唯一节点。这样,解决方案就变得非常高效。如果
vec
是常量,则无法对其进行排序,如果它是巨大的数组,则复制它将造成巨大的内存影响。所以每种解决方案都有其利弊。@DavidHaim不要告诉成年人该做什么,那样会给你带来麻烦。你的逻辑是错误的。红黑树是对缓存最不友好的数据结构之一,因为它涉及到跟踪指针,从而导致缓存未命中。如果向量无法更改,复制和排序要比创建红黑树便宜。很抱歉,我错过了这一点。我删除了我的评论,因为我不认为我的示例输入有错误的结果<代码>{1,2,2,2}
是一个不适用于此的示例。