在C 中的数组中滤除重复值

Filter out duplicate values in array in C++

本文关键字:数组      更新时间:2023-10-16

我有一个十个数字的行:

5 5 6 7 5 9 4 2 2 7

现在,我想要一个程序,可以找到所有重复项,并在控制台中像3次5、2倍2、2乘以7一样在控制台中散发出它们。尽管我做了一种编码算法,该算法可以排在数字的数字中,但我无法如上所述在控制台中透露它们。我的程序将输出:

3 times 5
2 times 5
2 times 7
2 times 2

我该如何解决这个问题?

#include <iostream>
using namespace std;
int main()
{
  int arr[10];
  int i,j;
  int z = 1;
    for(i = 0; i < 10; i++) {
        cin >> arr[i];
    }
    for(i = 0; i < 10; i++){
        for(j = i+1; j < 10; j++){
            if(arr[i] == arr[j]){
                z++;
            }
        }
        if(z >= 2){
        cout << z << " times " << arr[i] << endl;
        z = 1;
        }
    }

    return 0;
}

您可以在此处使用STL(C 11):

int arr[10];
std::map<int, int> counters;
for (auto item : arr)
{
    cin >> item;
    ++counters[item];
}
std::for_each(counters.begin(), counters.end(), [](const std::pair<int,int>& item)
{
    if(item.second > 1) std::cout << item.second << " times " << item.first << std::endl;
});

您需要检查是否尚未找到arr[i],例如:

if(z >= 2) {
    int found_before = 0;
    for(j = 0; j < i; ++j)
        if(arr[i] == arr[j])
            found_before = 1;
    if(!found_before)
        cout << z << " times " << arr[i] << endl;
    z = 1;
}

将要打印:

3 times 5
2 times 7
2 times 2

这样,您不再打印5

使用您的代码,它将打印出3次(在您的数组中的前5个),然后当它移至您的数组中的第二个5时,它将忘记您的数组中的前5个并报告它发现了5个两次(本身和数组的第五个数字)。

为什么不使用stl?

std::map<int, int> counter;
for (i = 0; i < 10; i++)
        counter[arr[i]] ++;
for (i = 0; i < 10; i++) {
    if (counter.count(arr[i]) > 0){
        std::cout << counter[arr[i]] << " times "<< arr[i] << std::endl;
        counter.erase(arr[i]);
    }
}

std::map是该作业的便捷工具。您可以轻松地计算特定数字的出现。计数后,您可以打印每个数组元素的计数。使用counter.erase,可以保证您不会多次打印相同的元素。

为什么要保持算法想法,我建议创建sub方法:

std::size_t count(const int* arr, std::size_t start, std::size_t end, int value)
{
    std::size_t res = 0;
    for (std::size_t i = start; i != end; ++i) {
        if (arr[i] == value) {
            ++res;
        }
    }
    return res;
}

然后您的固定算法将是:

for (std::size_t i = 0; i != 10; ++i) {
    if (count(arr, 0, i, arr[i]) != 0) {
        continue; // Already visited
    }
    auto total = count(arr, i, 10, arr[i]);
    if(total >= 2){
        std::cout << z << " times " << arr[i] << std::endl;
    }
}

一种简单的方法是为其制作另一个数组,特别是如果数字不那么大。

说您已经像这样初始化了您的数组:int nums[10] = { 5, 5, 6, 7, 5, 9, 4, 2, 2, 7 }

int result[max(nums)]; //Fill with zeroes, max(nums) is the highest number in the array
for(int i = 0; i < 10; i++) {
    result[nums[i]]++;
}
for(int i = 0; i < max(nums); i++) {
    if (result[i] > 1) cout << result[i];
}

请注意,这不是为内存优化。对于较大的数字内容,您可能需要考虑哈希图。

如果您不需要性能,而是紧凑的代码,则具有std :: upper_bound的std :: MultiSet是一种替代方法:

#include<set>
#include<iostream>
#include<algorithm>
int main(int a, char** b)
{
  int array[] = {5, 5, 6, 7, 5, 9, 4, 2, 2, 7};
  std::multiset<int> a(std::begin(array), std::end(array));
  for(auto it = a.begin(); it != a.end(); it = std::upper_bound(a.begin(), a.end(), *it))
  {
    if(a.count(*it) > 1)
        std::cout << *it << " times " << a.count(*it) << std::endl;
  }
  return 0;
}