简体   繁体   中英

Count different element of an array

I'm an IT stutend an we will have a programing exam where a test program will test our program. One of the particle examp is that we get ages and salaries of peoples, we have to count how many differet age people have

My code looks like this The struc:

struct input
{
    int emp_age, emp_paid;
};

And this is the code, n is represent the number of all people

int diff_sum (int n, input* t)
{
    int uniq_num = n;

    for(int i = 0; i < n; i++)
        {
            for(int j = i; j < n; j++)
                {
                    if((t[j].emp_age == t[i].emp_age) && (i!=j))
                        {
                            uniq_num = uniq_num - 1;
                        }
                }
        }
    cout << uniq_num << endl;
    return 0;
}

The program test 10 times, and some of said the out put is good but for some test it said it's wrong out put. I don't know how the test engine works, and i also dont know what the problem coud be.

Consider this: 10 10 10 . Think of i and j as pointing at elements:

uniq_num = 3
10 10 10
 i  j    => uniq_num = 2

10 10 10
 i     j => uniq_num = 1

10 10 10
    i  j => uniq_num = 0!!!!

So we see that in the second outer iteration, we compare two numbers that we already known are the same. They have already been indirectly compared.

Assuming you are not allowed to use any standard library facilities (if you are, why aren't you? This would be trivial with a std::set !), I would work in sort of the opposite order.

  • Start with unique=0 .
  • Look at the first element. Increment count.
  • Look at the next element. Compare it with all the previous elements. If none match, increment count.
  • Repeat.

(Be aware that this isn't the best algorithm, and is not what I would do for large inputs, but it's pretty simple to explain and implement using the most basic C++ concepts.)

One possibility would be to add all elements to an STL container with unique values:

int diff_sum (int n, input* t)
{
    std::set<int> ages;
    for(int i = 0; i < n; i++)
        ages.insert(t[i].emp_age);

    return ages.size();
}

Algorithm:

  1. Find the minimum and maximum ages (let's call them min_age and max_age)

  2. Allocate an array with max_age-min_age+1 entries (let's call it age_arr)

  3. Set all entries in age_arr to 0

  4. For each structure x, set 1 in entry # x.emp_age-min_age

  5. Sum all the values (0s or 1s) in age_arr, delete age_arr and return the result

Implementation:

//Phase 1
int min_age = 1000; // Assumption!!!
int max_age =    0; // Assumption!!!
for(int i=0; i<n; i++)
{
    if (min_age > t[i].emp_age)
        min_age = t[i].emp_age;
    if (max_age < t[i].emp_age)
        max_age = t[i].emp_age;
}

//Phase 2
int age_arr_size = max_age-min_age+1;
int age_arr[] = new int[age_arr_size];

//Phase 3
for(int age=0; age<age_arr_size; age++)
    age_arr[age] = 0;

//Phase 4
for(int i=0; i<n; i++)
    age_arr[t[i].emp_age-min_age] = 1;

//Phase 5
int age_count = 0;
for(int age=0; age<age_arr_size; age++)
    age_count += age_arr[age];
delete[] age_arr;
return age_count;

The problem is that your code will underestimate the number of unique ages:

eg say the ages are {1,2,3,4,1,5,6,1,7}

Clearly there are 7 unique ages here, and n = 9.

In your code, the only time uniq_num will get reduced is when i = 0 (when uniq_num is reduced by 2) and i = 4 (when uniq_num is reduced by another 1).

The latter case is double-counting, so your algorithm gives an answer of 6 instead of 7.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM