Reputation: 327
Let's say I have an array like this:
int array[]={1, 2, 2, 1, 2, 4, 4, 5};
I want to display all duplicate elements only once, display their corresponding frequency and count total duplicate elements. I searched about it a lot but every solution is for an array that has only 2 duplicate elements.
void non_unique_numbers(int arr[], int size){
int i,j;
int frequency[Frequency_size]={0};
for(i=0; i<size; i++){
for(j=0; j<size; j++){
if(arr[i]==arr[j] && i!=j){
++frequency[arr[j]];
printf("Number: %d , Frequency: %d\n", arr[j], frequency[j]);
}
}
}
}
When I run this my output is:
Number: 1 , Frequency: 3
Number: 2 , Frequency: 1
Number: 2 , Frequency: 1
Number: 2 , Frequency: 1
Number: 2 , Frequency: 2
Number: 1 , Frequency: 0
Number: 2 , Frequency: 2
Number: 2 , Frequency: 6
Number: 4 , Frequency: 0
which is meaningless. How can I display every duplicate element once and find out their corresponding frequency?
Upvotes: 0
Views: 479
Reputation: 33631
Rather than nested loops, you need two loops.
One to calculate the frequency. And, another that displays the frequencies and calculates the total number of duplicate numbers.
Here is the refactored code:
Edit: I've removed my broken original code during the second update.
UPDATE:
Yes but it still displays the same element more than once – goku
Oops, my bad ... Here is one that indexes into the frequency table on the second loop:
#include <stdio.h>
#define Frequency_size 10000
void
non_unique_numbers(int arr[], int size)
{
int i;
int freq;
int totdup = 0;
int frequency[Frequency_size] = { 0 };
// calculate freqency
for (i = 0; i < size; i++)
++frequency[arr[i]];
for (i = 0; i < Frequency_size; i++) {
freq = frequency[i];
if (freq <= 0)
continue;
printf("Number: %d , Frequency: %d\n", i, freq);
if (freq >= 2)
++totdup;
}
printf("The number of duplicated numbers is: %d\n",totdup);
}
UPDATE #2:
Can we make it work for also negative elements?
for (i = 0; i < Frequency_size; i++) { freq = frequency[i]; if (freq <= 0) continue; printf("Number: %d , Frequency: %d\n", i, freq);
Because of this part it is not working for negative integers – goku
Yes, we just need to use a second array for the negative number frequencies and index it by the negative of the negative number. (i.e.) we use a corresponding positive index.
Also, some have commented about doing range checks, so I've added that along with some statistics on the out of range values [if any]. I've also updated the if
test so that only duplicate numbers are printed.
Once again, I've compiled this but not tested it, but it should be okay:
#include <stdio.h>
#include <string.h>
#define Frequency_size 10000
void
non_unique_numbers(const int *arr, int size)
{
int i;
int freq;
int val;
int totdup = 0;
int pos_badcnt = 0;
int pos_badmax = 0;
int neg_badcnt = 0;
int neg_badmax = 0;
static int freq_pos[Frequency_size];
static int freq_neg[Frequency_size];
// set frequency counts to zero
memset(freq_pos,0,sizeof(freq_pos));
memset(freq_neg,0,sizeof(freq_neg));
// calculate freqency
for (i = 0; i < size; i++) {
val = arr[i];
// handle positive number(s)
if (val >= 0) {
if (val >= Frequency_size) {
++pos_badcnt;
if (val > pos_badmax)
pos_badmax = val;
}
else
++freq_pos[val];
}
// handle negative number(s)
else {
// index frequency array with positive index -- that's the trick
val = -val;
if (val >= Frequency_size) {
++neg_badcnt;
if (val > neg_badmax)
neg_badmax = val;
}
else
++freq_neg[val];
}
}
// for negative numbers, skip 0 and show lowest (most negative) first
for (i = Frequency_size - 1; i >= 1; --i) {
freq = freq_neg[i];
if (freq <= 1)
continue;
printf("Number: %d , Frequency: %d\n", -i, freq);
++totdup;
}
// show positive number frequencies
for (i = 0; i < Frequency_size; i++) {
freq = freq_pos[i];
if (freq <= 1)
continue;
printf("Number: %d , Frequency: %d\n", i, freq);
++totdup;
}
printf("The number of duplicated numbers is: %d\n",totdup);
// show out of range negative number stats
if (neg_badcnt > 0) {
printf("There were %d out of range negative numbers\n",neg_badcnt);
printf("Smallest out of range negative number was %d\n",-neg_badmax);
}
// show out of range positive number stats
if (pos_badcnt > 0) {
printf("There were %d out of range positive numbers\n",pos_badcnt);
printf("Largest out of range positive number was %d\n",pos_badmax);
}
}
Upvotes: 2
Reputation: 470
You can try this.
void non_unique_numbers(int arr[], int size){
int i,j;
for(i=0; i<size; i++)
{
int frequency=0;
bool wasFoundEarlier=false;
for(j=i; j<size; j++)
{
if(arr[i]==arr[j])
{
frequency++;
}
}
for(int x=0;x<i;x++)
{
if(arr[x]==arr[i])
{
wasFoundEarlier=true;
}
}
if(!wasFoundEarlier)
{
printf("Number: %d , Frequency: %d\n", arr[i], frequency);
}
}
}
This will print the frequency of all the elements.
If you want to print the frequency of only duplicate ones, just change the inner loop
for(j=i+1; j<size; j++)
Upvotes: 0