如何计算排序数组中的重复数字

时间:2016-03-21 22:08:58

标签: c++ arrays for-loop

我正在尝试完成一个问题,我将文件读入程序并输出一个文件,其中包含平均值,最小值,最大值以及该数字在程序中出现次数的计数。但是,我无法弄清楚如何为重复数量的"计数"创建一个数组。

如果我尝试读取的文件的值为19 5 26 5 5 19 16 8 1

我需要输出的文件来阅读5---3 times; 8---1 time; 16---1 time; 19--2 times; 26--1 times

我首先将我的数组排序为5 5 5 8 16 19 19 26

下面是我的代码,解释了我想要做的事情:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;

double averageArray(int a[], int length); // user defined function to get average
int maxval(int a[], int length); //user defined function to get max val
int minval(int a[], int length); //user defined function to get min val
void bsort(int arr[], int length);// udf to sort array from min to max
int countArray(int a[], int length); //attempt to create a function to get the number of occurrences of a number that is duplicated

int main()
{
    char infilename[16];
    int nums[50];//newly created array to read in the numbers from the file
    int length(0);//array has a length defined by "length"
    ifstream fin;
    ofstream fout;


    cout << "Please enter an input file name: ";
    cin >> infilename;
    cout << endl;

    fin.open(infilename); 
    if (fin.fail())
    {
        cerr << "The file " << infilename << " can't be open!"<<endl;
        return 1;
    }


    cout<<"The output to the file statistics.txt should be as follows: "<<endl;
    fout.open("statistics.txt");
    fout<<"N"<<"\t"<<"Count"<<endl;
    cout<<"N"<<"\t"<<"Count"<<endl;


    while (fin >> nums[length]) 
        length++;

    bsort(nums, length);
    for (int i=0; i<length; i++) {
        if (nums[i]==nums[i-1]) {
            continue;
        }
        cout<<nums[i]<<"\t"<<countArray(nums,length)<<endl;
        fout<<nums[i]<<"\t"<<endl;
    }

    cout << "\nAverage: " << averageArray(nums,length) << endl;
    cout << "Max: "<< maxval(nums,length)<<endl;
    cout << "Min: "<< minval(nums,length)<<endl;


    fin.close();


    return 0;
}



double averageArray (int a[], int length)
{
    double result(0);

    for (int i = 0; i < length ; i++)
        result += a[i];
    return result/length;
}

int maxval(int a[], int length) 
{

    int max(0);

    for (int i=1; i<length; i++)
    {
        if (a[i]>max)
            max=a[i];
    }
    return max;
}

int minval(int a[], int length) 
{

    int min(100);

    for (int i=1; i<length; i++)
    {
        if (a[i]<min)
            min=a[i];
    }
    return min;
}

void bsort(int a[], int length)
{
    for (int i=length-1; i>0; i--)
        for (int j=0; j<i; j++)
            if (a[j]>a[j+1])
            {
                int temp=a[j+1];
                a[j+1]=a[j];
                a[j]=temp;
            }
}

int countArray(int a[], int length)
{
    int counter(0);
    for (int i=0; i<length; i++){
        if (a[i]==a[i+1]) //loop through array and if the number after is the same as the previous number, then count one
        counter++;
    }
    return counter;
}

虽然它编译,但计数仅显示&#34; 3&#34; s,如下图所示:

output image

4 个答案:

答案 0 :(得分:1)

在我给你解决方案之前,请花一点时间记住,你是用C ++编程,而不是C.因此,你应该使用向量,istream迭代器和std::sort。您还应该使用std::map,这很容易实现此目的:

template <typename It>
std::map<int, int> count_occurrences(It it, It end)
{
  std::map<int, int> output;
  while (it != end) output[*it++]++;
  return output;
}

如何将其与现有代码相结合,留给读者练习。我建议你应该读一下迭代器。

答案 1 :(得分:0)

您的函数int countArray(int a[], int length)没有输入实际数字。它始终计算阵列中相同数字的频率。这种情况在五次发生两次,一次发生在19 => 3次。

解决方案:

int countArray(int a[], int length, int num)
{
    int counter(0);
    for (int i=0; i<length; i++){
        if (a[i]==num) //loop through array and if the number is the one you are looking for
           counter++;
    }
    return counter;
}

并致电您:countArray(nums, length, nums[i]);

答案 2 :(得分:0)

void countArray(int a[], int length)
{
    int counter(1);
    bool flag(false);
    //you take (i+1) index, it can go out of range
    for (int i = 0; i < length - 1; i++){
        if (a[i]==a[i+1]){ //loop through array and if the number after is the same as the previous number, then count one
            flag = true;
            counter++;
        }
        else {
            if (flag){
                cout<<a[i] << counter << endl;
            }
            flag = false;
            counter = 1;
        }
    }
}

我很久没有在C上编码,但我希望它会有所帮助。 此程序将为您打印答案,您只需拨打一次。

答案 3 :(得分:0)

我建议使用std::map这是解决问题的最佳解决方案。我将尝试轻松解释执行此操作的不同步骤:

  1. 我认为您的变量已初始化,例如:

    int length = 9;
    int nums[length] = {19, 5, 26, 5, 5, 19, 16, 8, 1};
    
  2. 创建std::map<int,int>,其中key第一个 int)将是您的号码,value int)密钥​​中此数字存储的出现次数。

    std::map<int,int> listNumber;
    
  3. 填写地图

    // For all numbers read in your file
    for(int i=0; i<length; ++i)
    {
        // Get number value
        int n = nums[i];
    
        // Find number in map
        std::map<int, int>::iterator it = listNumber.find(n);
    
        // Doesn't exists in map, add it with number of occurence set to 1...
        if(it == listNumber.end())
        {
            listNumber.insert(std::pair<int,int>(n,1));
        }
        // ... otherwise add one to the number of occurence of this number
        else
        {
            it->second = it->second+1;
        }
    }
    
  4. 阅读地图

    // Read all numbers and display the number of occurence
    std::cout << "N" << "\t" << "Count" << std::endl;
    for(std::map<int, int>::iterator it = listNumber.begin(); it!=listNumber.end(); ++it)
    {
        std::cout << it->first << "\t" << it->second << std::endl;
    }