how to count same numbers once in an array

iam trying to count the same numbers in an array just once like
38
38
40
38
40
37
the output should be 2 since 38 is repeated and 40 too
but for my code the output is 3 thats an example of how it should be
in a nutshell i want same number to be counted just once in the whole array
thanks in advance

and here's my code :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>

using namespace std;

int main(){
	int N, M[500], count = 0;
	bool active;
	while (cin >> N){
		for (int i = 0; i < N; i++){
			cin >> M[i];
		}
		for (int i = 0; i < N - 1; i++){
			active = false;
			for (int j = i + 1; j < N; j++){
				if (M[i] == M[j] && active == false){
					count++;
					active = true;
				}
			}
		}
		cout << count << endl;
		count = 0;
	}
	return 0;
}
Last edited on
First, please use code tags http://www.cplusplus.com/articles/jEywvCM9/
(You can edit your posts.)

You want to count unique values.

One trivial way is to sort the values first. Then we know that repeating values are in consecutive elements.

The other way is to use a "set".
When you get a new value from array, you check whether it is already in the set.
If it is, you skip forward.
If it is not, you add the value to the set.
When done, the set contains only unique values.
and how to sort the values first ? O.o

and for the other way i know that but cant do it as a code

and i used code tags
you can use array container in c++.

#include <iostream>
#include <algorithm>
#include<array>
using namespace std;

int main(){
array<int,6> ca{38,38,40,38,40,37};
cout<<count(ca.begin(),ca.end(),40);
return 0;
}
the 38 38 40 38 40 37 is just an example
if u see my code u will see cin>>M[i]; which i want the user to put the input
// see your complete code

#include <iostream>
#include <algorithm>
#include<vector>
#include<set>
using namespace std;


int main(){
vector<int> ca{};
int inp;
cout<<"enter no:";
while(cin>>inp ){
ca.push_back(inp);
cout<<"enter no:";
}
set<int> st1(ca.begin(),ca.end());

for(auto i:st1){
cout<<"no of"<<i<<" is "<<count(ca.begin(),ca.end(),i)<<endl;}
return 0;
}
Are you familiar with counting sort algorithm?

The general idea is to have a counter array (int[]) with lenght = maxValue - minValu; where you would keep count of how many times does which number occur. (and then you would print that many copies of that number back into your array and end up wit sorted array, but you don't need this)

pseudo code:
1
2
3
4
5
6
7
8
9
10
11
first populate your counter array with zeros;
then
foreach num in inputArray
    counterArray[num - minValu] ++; //we are using minValu as offset, 
    //because array indexes start at 0 but our minimal value can be positive or negative
then //now we know how many times does which number occur
int maxRepeat = 0;
foreach num in counterArray
    if (num > maxRepeat )
        maxRepeat  = num
end //and now you found your answer 


This is generally the fastest way to find the answer, but since you need additional space for the counterArray (whos lenght depends from range of vlues) it makes it unpractical to use with extremely big ranges of numbers. for example if the range is one milion long and you use int32 you'll need 4mb of space, it's not much on today's computers, but still unpractical for short inputArray-s.
At least it's fast and doesn't require any libraries :)
Last edited on
Sigh.

Option 1:
(Already suggested)
Sort the data.

Option 2:
Use a std::map (or std::unordered_map).

Unless you know the range of values is small enough to manage in an array (use a std::vector), then use the map. Either way the code that actually does the counting is identical.

The purpose is to create what is called a histogram -- a graph that tells you the number of times a particular value occurs.

If h is a map, just make sure it is empty first.
1
2
3
  while (first != last)
    h[ *first++ ] += 1;
  // Now h[value] == number of times value appears in first..last. 

If h is a vector, make sure to size it with enough zero elements first.
1
2
3
4
5
  h.clear();
  h.resize( range_of_values, 0 );
  while (first != last)
    h[ *first++ - min_value ] += 1;
  // Now h[index] == number of times value==index+min_value appears in first..last. 

Once you have your histogram, you can easily find out which value appears most.

Hope this helps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <algorithm>
using namespace std;

int main(){

	int arr[9] = {1,5,9,3,0,3,2,3,5};
	std::sort(arr, arr+9);
	
	int counT =1; // arr[0]
	
	for(int i=1; i<9; i++) {
		if(arr[i]>arr[i-1]) 
			counT++;
	}	
	cout << counT; //6
		
return 0;		
}
Wait! Did we interpret this correctly:
the output should be 2 since 38 is repeated and 40 too

The input had three unique values: 37, 38, and 40.
The input had 1*37, 3*38 and 2*40, a total of six values.
Only two unique values occur more than once: 38 and 40.

Is it actually the last detail that you seek?


@sujitnag:
std::set contains only the unique values and thus your count is "1" every time.


MartinMorcos wrote:
how to sort the values first ? O.o

and for the other way i know that but cant do it as a code

You grasp the principle but not the syntax of the language. There are still two levels in the syntax of the language.

1. To "use C++" you would exploit the standard library. For example:
1
2
3
// The count of unique values in array M
std::set<int> st1( M, M+N );
std::cout << st1.size() << '\n';


For sorting, there is std::sort.

For histogram, there is that std::map. If we just want to know whether a value repeats, but do not care how many times, then I would use std::map<bool>:
IF map does not have key V, then insert (V,false)
ELSE map has key V and we update map[V] to true

Count the elements of map that have value true



2. "Learn". Rather than using the library data structures and algorithms, you implement them with more primitive constructs and train logical thinking while doing it.

For example, you had:
1
2
3
4
5
6
7
int N;
int M[500]; // This may be too much or not enough
if ( cin >> N ) { // N is a number, but is it within [0,500]?
  for (int i = 0; i < N; i++){
    cin >> M[i]; // Does the read succeed?
  }
}

sujitnag had:
1
2
3
4
5
6
std::vector<int> ca;
int inp;
// no size of data is asked first, but one needs EOF or non-integer to indicate the end of data.
while( cin>>inp ) { // success of each input is checked
  ca.push_back(inp);
}

The versions do differ in details.

The plain array is static and sets limits at compile-time. "primitive"

The vector dynamically resizes in order to be big enough for the data and has methods like vector::size() to check how many elements it has, i.e. the N is within the vector object, not as separate variable.
it can be calculated number of occurrences of each element without sorting:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// number of occurence of each letter in Array (non-sorted)
// by anup 23.01.2015
#include <iostream>

int main(){

	char ch[11] = "abcdbhbhab"; // 10 chars
	
	for(int i=0; i<10; i++ ){
		int n=0;
		for(int j=0; j<10; j++){
			if(ch[i]==ch[j]) {
				if(i>j)	break;
				n++;
			}					
		}
		if(n) std::cout << ch[i] << " " << n << " times\n";	
	}
		
return 0;		
}


output:
a 2 times
b 4 times
c 1 times
d 1 times
h 2 times



same method can be applied to integer array.
@keskiverto

before commend you should run my program first.
it work nicely.

you miss out some code. set for unique data in the vector and count function work on vector veritable ca.

1
2
3
4
5
for(auto i:st1){
cout<<"no of"<<i<<" is "<<count(ca.begin(),ca.end(),i)<<endl;}
return 0;
}


output is:

enter no:6
enter no:8
enter no:6
enter no:7
enter no:6
enter no:8
enter no:7
enter no:8
enter no:6
enter no:a
no of6 is 4
no of7 is 2
no of8 is 3

Process returned 0 (0x0) execution time : 11.331 s
Press any key to continue.

Topic archived. No new replies allowed.