c++中的重复计数

counting duplicates in c++

本文关键字:c++      更新时间:2023-10-16

假设我有一个int数组{100,80,90,100,80,60}

所以我想要计算这些重复并保存这些计数器以供以后使用。因为每个重复的数字都应该除以计数器

就像100被重复了2次,所以它们应该是50。

查找重复项,我使用sort。

std::sort(array, array + number);
for(int i = 0; i < number; i++) {
  if(array[i] == array[i+1])
    counter++;
}

和我已经尝试做计数器数组来保存它们在数组的每个num。但这并没有奏效。请给我一些更好的主意。

方法1

最简单的方法是不排序数组,而增加map的元素:

unordered_map<int, size_t> count;  // holds count of each encountered number 
for (int i=0; i<number; i++)        
    count[array[i]]++;             // magic ! 

然后可以处理映射的内容:

for (auto &e:count)                // display the result 
    cout << e.first <<" : "<<e.second<< "-> "<<e.first/e.second<<endl; 

如果需要,通过从映射中删除它们或在处理过程中忽略它们来过滤掉非重复项。

方法2

如果你不被允许使用地图,那么你必须精心设计你的计数循环,以便重新开始计数每个新数字,并且能够处理连续的dup,如果超过两个:

...
for(int i = 0; i < number; i+=counter) {
    for (counter=1; i+counter<number && array[i+counter]==array[i]; ) 
        counter++;       // count consecutives dups
    if (counter>1) {     // if more than one, process the dups.  
        cout << "dup: " << array[i] << " "<<counter<<endl;   
    }
}

如果需要存储pair以便在第二步处理它们,则需要存储pair(最好存储在vector中,但如果需要则存储在数组中):

pair<int, size_t> result[number];  // a vector would be preferable
int nres=0; 
... 
    if (counter>1) {     // if more than one, process the dups.  
        // cout << "dup: " << array[i] << " "<<counter<<endl; 
        result[nres++] = make_pair(array[i], counter);  
    }
...

两种方法的在线演示

使用std::map<int,int>std::unordered_map来计算出现次数

然后遍历映射,并将每个值替换为键除以原始值(计数器)。

最后遍历原始数组并将每个数字替换为其映射值

如果使用std::unordered_map,则算法为O(n)。原来的是O(n log n)因为要排序。

如果你想直接改变数组的数字,你可以这样做:

for (int i = 0, counter = 1; i < number; i++) {
    if (array[i] == array[i + 1])
        counter++;
    else { //when finished counting duplicates
        for (int j = counter; j > 0; j--) //adjustment for subscripts
            array[i - j + 1] /= counter; //change the values stored in array
        counter = 1;//reinitialize array to 1
    }
}

存储在数组中的排序值将被其对应的计数器除一次。

如果允许修改序列,这里是替换元素的算法:

const auto begin = std::begin( data );
const auto end = std::end( data );
std::sort( begin, end );
for( auto it = begin; it != end; ) {
    auto next = std::upper_bound( std::next( it ), end, *it );
    auto newval = *it / std::distance( it, next );
    std::fill( it, next, newval );
    it = next;
}

demo on ideone

PS修改为可以编译数组

相关文章:
  • 没有找到相关文章