2

I Have to find the occurrences of every element in array. So far My code is this

void Occurrences()
{
    int numers[10], count = 0, i;
    for (i = 0; i < 10; i++)
    {
        cout << "Enter Number";
        cin >> numers[i];
    }
    for (i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            if (numers[i] == numers[j])
            {
                count++;
            }
        }
        cout << numers[i] << " is Occur " << count << " Time in Array" << endl;
        count = 0;
    }
}
int main()
{
    Occurrences();
}

Output is coming multiply same numbers i.e If I entered six 1 and 4 2's. Output is

1 is occur 6 time in array.
1 is occur 6 time in array.
1 is occur 6 time in array.
1 is occur 6 time in array.
1 is occur 6 time in array.
1 is occur 6 time in array.
2 is occur 4 time in array.
2 is occur 4 time in array.
2 is occur 4 time in array.
2 is occur 4 time in array.

But I want output like this:

1 is occur 6 time in array.
2 is occur 4 time in array.

How do I do this?

David G
  • 94,763
  • 41
  • 167
  • 253
Abdul Majeed
  • 27
  • 2
  • 7
  • @Brandon It is only for practice. – Abdul Majeed Jan 31 '15 at 21:11
  • @AbdulMajeed Part of being a good C++ programmer is knowing what are the right tools for the job. The obvious "right tool" is a map of some type `std::map`, `std::unordered_map`, etc. not an array or vector (even though you can use them, but clumsily). – PaulMcKenzie Jan 31 '15 at 21:15

4 Answers4

2

Since you tagged this C++11, I would use std::unordered_map:

void Occurrences()
{
    std::unordered_map<int, int> occurrences;

    // enter 10 numbers
    for (int i = 0; i < 10; ++i) {
        cout << "Enter Number";
        int x;
        cin >> x;
        ++occurrences[x]; // increment the count for x
    }

    // print results
    for (const auto& pr : occurrences) {
        std::cout << pr.first << " appears " << pr.second << " times." << std::endl;
    }
}
Barry
  • 286,269
  • 29
  • 621
  • 977
2

Your problem is you're searching for items you've already output. you can skip those items if you sort the array first.

Just to be different, I'm going to tell you how to do this with your existing code, an array, and not a map.

  • read the values in the array.
  • sort the array.
  • enumerate the array, and ignore (but count) any elements matching the previous element. reset the counter when you discover a new element.
  • thats it.

Example:

#include <iostream>
#include <algorithm>

void Occurrences()
{
    int numers[10], i;
    for (i = 0; i < 10; ++i)
    {
        std::cout << "Enter Number";
        if (!(std::cin >> numers[i]))
            break;
    }

    // sort the array in ascending order , O(NlogN)
    std::sort(numers, numers+i);

    for (const int* it = numers; it != numers+i;)
    {
        unsigned int count = 1;
        int value = *it;
        for (++it; (it != numers+i) && *it == value; ++count, ++it);
        std::cout << value << " occurs " << count << " times." << std::endl;
    }
}

int main()
{
    Occurrences();
}

Your Sample Run

Enter Number1
Enter Number1
Enter Number1
Enter Number1
Enter Number1
Enter Number1
Enter Number2
Enter Number2
Enter Number2
Enter Number2
1 occurs 6 times.
2 occurs 4 times.

No map required. if you choose to use a map, consider an unordered map (hash table) as it may produce better performance.

Best of luck.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Stealth down-voting FTL. I'm keeping this answer only because it addresses *precisely* that which was asked by the OP; how to do this with the given array. It is not for me to decide whether they need a different container, and the only one that would make sense regardless is an unordered map hash table, which I prop dutifully, as a regular map will offer no better overall performance improvement than sorting. I've justified my answer; feel free to justify you down vote. – WhozCraig Jan 31 '15 at 21:25
-1

Better store it in a map and display everything later.

    void Occurrences()
    {
        int numers[10],count = 0,i;
        std::map<int,int> mapCnt;
        for(i =0;i<10;i++)
        {
            cout<<"Enter Number";
            cin>>numers[i];
        }
        for( i = 0;i<10;i++)
        {
           for(int j = 0;j<10;j++)
           {
               if(numers[i] == numers[j])
               {
                   count++;
               }
           }

           mapCnt[numers[i]]=count;
               count = 0;

        }

    // Print the map Here
  typedef std::map<int,int>::iterator it_type;
  for(it_type iterator = mapCnt.begin(); iterator != mapCnt.end(); iterator++) {

     cout << iterator->first << " is Occur " << iterator->second << " Time in Array" << endl;

    }

}

Looping through map https://stackoverflow.com/a/4844904/2466168

Community
  • 1
  • 1
Srinath Mandava
  • 3,384
  • 2
  • 24
  • 37
  • The idea is correct, but you can accumulate counts directly into the map while you're reading values (which you can store in the array regardless). `++mapCnt[numers[i]];` during the read loop eliminates the follow-up nested for-loops entirely. An initial insertion caused by invoking `operator[]` on the map will add a value-initialized `int`, which means it starts as zero, precisely what you want for the initial count before the first `++`. – WhozCraig Jan 31 '15 at 21:43
-1

A variation from maandoo's code if you can process as your read the numbers in:

void Occurrences()
{
    int i;
    std::map<int,int> mapCnt;
    for(i =0;i<10;i++)
    {
        int num;
        cout<<"Enter Number";
        cin>>num;
        std::map< int, int >::iterator iter( mapCnt.find( num ) );
        if( iter != mapCnt.end() )
            mapCnt[num] = 1;
        else
            ++( iter->second );
    }

    // Print the map Here
    for( i = 0; i < mapCnt.size(); ++i )
        std::cout << mapCnt[i].first << " occurs " << mapCnt[i].second << " times in array\n";
}
George Houpis
  • 1,729
  • 1
  • 9
  • 5