Finding duplicate values in array in c - c

I am trying to find the duplicate values in an array. When a number is duplicated once like (25,25) program correctly prints 25 once but when a number duplicated twice like (12,12,12) program prints 12 three times while it should print it once.
#include<stdio.h>
int main()
{
int numbers[15]={1,1,2,2,2,3,4,5,6,6,7,7,7,8,9},i,j;
for(i=0;i<15;i++)
{
for(j=i;j<14;j++)
{
if(numbers[i]==numbers[j+1])
{
printf("Number %d has duplicate values\n",numbers[i]);
}
}
}
return 0;
}
Output:
Number 1 has duplicate values
Number 2 has duplicate values
Number 2 has duplicate values
Number 2 has duplicate values
Number 6 has duplicate values
Number 7 has duplicate values
Number 7 has duplicate values
Number 7 has duplicate values
The arrays cannot be assumed to be ordered so the program should work even with {1,2,1,2,3,4,2,5,6,6,7,7,7,8,9}.

The problem at hand is essentially simple. There is no need for any complicated code fragments. All it takes is just a little modification to the limits of the for loops and how you check for duplicates.
The solution:
Just introduce another array which is going to store the elements which are repeated in the array. Start filling this array from the 0th index as and when you find a NEWLY REPEATED element. This can easily be done iterating through this new array and checking if the currently encountered repeated element is already present or not. If it is not present there, then insert into the new array, which in the code I have given below is arr2[].
Hence whatever elements will be held by this new array are the unique repeated elements. I have attached the code and corresponding output below.
CODE:
#include<stdio.h>
int main()
{
int numbers[15] = {1,1,2,2,2,3,4,5,6,6,7,7,7,8,9}, i, j;
int arr2[15], k = 0, k1 = 0;
int flag = 0;
for(i = 0; i < 15; i++)
{
for(j = 0; j < 15; j++)
{
flag = 0;
if(i != j && numbers[i] == numbers[j])
{
for(k1 = 0; k1 < k; k1++)
if(arr2[k1] == numbers[j])
flag = 1;
if(flag != 1)
arr2[k++] = numbers[j];
}
}
}
for(i = 0; i < k; i++)
printf("Number %d has duplicate values\n",arr2[i]);
return 0;
}
OUTPUT:
Number 1 has duplicate values
Number 2 has duplicate values
Number 6 has duplicate values
Number 7 has duplicate values
Hope this helps.

A solution which doesn't introduce additional memory requirements and finds unique duplicates in a worst case of O(N²):
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
// macro that evaluates to the number of elements in an array:
#define SIZEOF_ARRAY(arr) sizeof(arr) / sizeof(*arr)
// contains() returns true if [values, values + size) contains value
bool contains(int *values, size_t size, int value)
{
for (size_t i = 0; i < size; ++i)
if (values[i] == value)
return true;
return false;
}
int main(void)
{
int numbers[] = { 1, 1, 2, 2, 2, 3, 4, 5, 6, 6, 7, 7, 7, 8, 9 };
for (size_t i = 0; i < SIZEOF_ARRAY(numbers) - 1; ++i)
{
if (contains(numbers, i, numbers[i])) // if we already encountered numbers[i]
continue; // it was already identified as dup.
if(contains(numbers + i + 1, SIZEOF_ARRAY(numbers) - i , numbers[i]))
printf("Number %d has duplicate values\n", numbers[i]);
}
}
Output:
Number 1 has duplicate values
Number 2 has duplicate values
Number 6 has duplicate values
Number 7 has duplicate values

If you deal with low numbers, you can always go via index table
#include <stdio.h>
int main() {
int index[256] = {0};
int table[15] = {1, 2, 3, 5, 5, 6, 1, 2, 9, 10, 11, 2, 3, 4, 5 };
for(int i=0; i<15; i++) {
index[table[i]] ++;
}
for(int i=0; i<256; i++) {
index[i] > 1 ? printf("%d\n",i) : 0;
}
}

In your example consider the indexes of the 7: they are 10, 11, 12.
The first print happens when i=10 and j=10 because your are indexing numbers[10] and numbers[11].
At the next iteration of the inner loop you have i=10 and j=11 and the condition is verified again by the elements numbers[10] and numbers[12].
Finally the third condition happens when i=11 and j=11 because you are referring to numbers[11] and numbers[12].
All this becomes clear if you print your indexes when the condition happens. For example you can substitute your printf with this:
printf("Number %d has duplicate values with indexes i=%d, j=%d\n",numbers[i], i,j);
which prints:
Number 1 has duplicate values with indexes i=0, j=0
Number 2 has duplicate values with indexes i=2, j=2
Number 2 has duplicate values with indexes i=2, j=3
Number 2 has duplicate values with indexes i=3, j=3
Number 6 has duplicate values with indexes i=8, j=8
Number 7 has duplicate values with indexes i=10, j=10
Number 7 has duplicate values with indexes i=10, j=11
Number 7 has duplicate values with indexes i=11, j=11
If your values are ordered you can do something like this:
#include<stdio.h>
int main()
{
int numbers[15]={1,1,2,2,2,3,4,5,6,6,7,7,7,8,9},i,j;
int last_dup = -1;
for(i=0;i<15;i++)
{
for(j=i+1;j<14;j++)
{
if(numbers[i]==numbers[j] && numbers[i]!=last_dup)
{
printf("Number %d has duplicate values with indexes i=%d, j=%d\n",numbers[i], i,j);
last_dup = numbers[i];
break;
}
}
}
return 0;
}
I initialized to -1 assuming your numbers are all positive. If not you can save the index of the last duplicate and reference using in the check numbers[last_dup_idx] (be careful to initialize the value properly and not go out the length of the array). I also added a break: since you already found a duplicate there is no need to continue the second loop.
If your array is not ordered, you can create an additional array saving the duplicates elements every time you find one and then iterate through this array to check.
FOR NOT ORDERED ARRAYS
#include<stdio.h>
int main()
{
int numbers[15]={1,1,2,2,2,3,4,5,6,6,7,7,7,8,9},i,j;
int dups [7];//at most 15/2 duplicates
char dup_idx=0;
char found_new_duplicate; //initialized later
for(i=0;i<15;i++)
{
for(j=i+1;j<14;j++)
{
if(numbers[i]==numbers[j])
{
found_new_duplicate = 1;
//check in the duplicates array
for (int kk=0; kk<=dup_idx; kk++)
{
if (dups[kk]==numbers[i] && !(i==0 && j==1))
{
found_new_duplicate = 0;
break;
}
}
if (found_new_duplicate)
{
dups[dup_idx] = numbers[i]; //insert the new duplicate in the duplicates array
printf("Number %d has duplicate values with indexes i=%d, j=%d\n",numbers[i], i,j);
printf("New duplicate %d\n", dups[dup_idx]);
dup_idx++;//increase the index
break;
}
}
}
}
for (int kk=0; kk< dup_idx; kk++)
printf("%d\n", dups[kk]);
return 0;
}

Related

How would i do first and second parts?

Consider we have to choose a Leader from n people. For this purpose, we create an
array of size n. We assign every candidate a number (1, 2, 3, 4, 5,….,n) and store it in array in
ascending order. We apply dancing chair (People struggle to get the chair!!! After stopping the
music, in each iteration one chair and one man is eliminated. The Final remaining one is the
winner) method. Suppose we start from index 0 then we have to skip 3 indexes and we will reach
at index 3. Set its value to zero and start again from index 4 and skip 3 indexes and we will reach at index 7. Repeat the same step and so on.
(1) When we reach at last index we will proceed to index 0 again (for example the last index is 19, we start the count from index 18 and skip 3 indexes then we will reach at 1 and set it to zero).
(2) If the reached element value is already 0 than set the next element to zero. Do the same process till only one element remaining?
We implement it by using array and function. Write a function SelectLeader () which takes array
as input and return the Leader.
#include <stdio.h>
int SelectLeader() {
int n, i;
int leader = 0;
printf("Enter total number of people to choose a Leader from: ");
scanf("%d", &n);
int array[n];
for (i = 0; i < n; i++) {
array[i] = i + 1;
}
for (i = 0; i <= n; i = (i + 3) % n) {
if (array[i] == 0) {
array[(i + 1) % n] = 0;
} else
array[i] = 0;
}
for (i = 0; i < n; i++) {
if (array[i] != 0) {
leader = i;
}
}
return leader;
}
int main() {
int L;
L = SelectLeader();
printf("Leader is the candidate with the index number %d\n", L);
}
You can use the following pesudo code
Suppose n= 10 , for easy understanding
I am creating a boolean flag array to check whether number is selected or not.
jump = 3
i = 0
for (int cnt=0;cnt<10;) {
if(flag[i%10] === false) {
flag[i%10]=true;
cnt+=1;
i+=jump;
}
else {
i+=1;
}
}
The index element remaining with flag false is ans.
However this approach is both space and time expensive.

Why doesn't my nested for / do-while loop to sort through an array not output my final prints in C?

Why can't I get this loop to stop? My tracker is an array filled with a random number of elements in the range of 1 to 10. Lets say the size of this array is 50. I want to check all values 1 to 10 are in the array by checking the entry of when the number appears first in the array. I also want to keep track of the biggest value for the entry and store it as numberOfHops and so if all numbers are in the array, the output should be numberOfHops.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, k, m, entry = 0, numberOfHops = 0;
const int L = 10;
int tracker[50] ={1, 2, 3, 2, 1, 10, 9, 8, 7 , 6 //etc etc//};
int sitesVisited = 0;
for (k =1; k<=L; k++ )
{ do {
m=0;
if (k == tracker[m])
{
sitesVisited += 1;
entry = m;
}
if (entry > numberOfHops)
{
numberOfHops = entry;
}
m++;
} while (sitesVisited < k);
}
if (sitesVisited == L) {
printf("Particle took %d hops to explore environment.\n", numberOfHops);
}
else {
printf("Particle did not explore entire environment.");
}
}
The problem is in m=0; line. You should declare it before do { cycle start.
Every loop you initialize it with 0 instead of increasing.

How to see if numbers have same digits in array?

I'm a bit stuck on one of my problems not because I don't know, but because I can't use more complex operations.(functions and multiple arrays)
So I need to make a program in C that ask for an input of an array(max 100 elements) and then program needs to sort that matrix by numbers with same digits.
So I made everything that I know, I tested my program with sorting algorithm from minimum to maximum values and it works, only thing that I can't understand is how should I test if the number have same digits inside the loop? (I can't use functions.)
So I know the method of finding if the number have the same digits but I don't know how to compare them. Here is an example of what I need.
This is what I have for now this sorts numbers from min to max.
#include <stdio.h>
int main() {
int matrix[100];
int i,j;
int temp,min;
int elements_number=0;
printf("Enter the values of matrix-max 100 elements-type -1 to end: ");
for(i=0;i<100;i++){
scanf("%d",&matrix[i]);
elements_number++;
if(matrix[i]==-1){
elements_number--;
break;
}
}
for (i=0; i<elements_number; i++) {
min=i;
for (j=i+1; j<elements_number; j++) {
if (matrix[j] < matrix[min])
min = j;
}
temp = matrix[i];
matrix[i] = matrix[min];
matrix[min] = temp;
}
for(i=0;i<elements_number;i++){
if(i!=elements_number-1){
printf("%d,",matrix[i]); }
else printf("%d.",matrix[i]);
}
return 0;
}
I need this output for these numbers:
INPUT :
1 22 43 444 51 16 7 8888 90 11 -1
OUTPUT:
1,22,444,7,8888,11,43,51,16,90.
Integers with 1 digit count as "numbers with same number of digits" like 7 and 1 in this example.
Hope that you can help.
After processing the array, the single-digit numbers should all be in the left part of the array, the other numbers in the right part. Within each part, the original order of the elements should be preserved. This is called a stable partition. It is different from sorting, because the elements are only classified into two groups. Sorting means that there is a clear relationship between any two elements in the array.
This can be done by "filtering" the array for single-digit numbers and storing the other numbers that were filtered out in a temporary second array. Then append the contents of that second array to the (now shorter) first array.
Here's how that could work:
#include <stdlib.h>
#include <stdio.h>
void print(const int *arr, int n)
{
for (int i = 0; i < 10; i++) {
if (i) printf(", ");
printf("%d", arr[i]);
}
puts(".");
}
int is_rep_digit(int n)
{
int q = n % 10;
n /= 10;
while (n) {
if (n % 10 != q) return 0;
n /= 10;
}
return 1;
}
int main()
{
int arr[10] = {1, 22, 43, 444, 51, 16, 7, 8888, 90, 11};
int aux[10]; // auxliary array for numbers with several digits
int i, j, k;
print(arr, 10);
j = 0; // number of single-digit numbers
k = 0; // number of other numbers
for (i = 0; i < 10; i++) {
if (is_rep_digit(arr[i])) {
arr[j++] = arr[i]; // pick single-digit number
} else {
aux[k++] = arr[i]; // copy other numbers to aux
}
}
k = 0;
while (j < 10) { // copy aux to end of array
arr[j++] = aux[k++];
}
print(arr, 10);
return 0;
}
Edit: I've just seen your requirement that you can't use functions. You could use Barmar's suggestion to test divisibility by 1, 11, 111 and so on. The tricky part is to find the correct divisor, however.
Anyway, the point I wanted to make here is that you don't need a full sorting algorithm here.

How to find number of pairs which have maximum difference in their values among all other pairs?

I calculated difference between each pair and then stored the maximum difference pertaining to that element in the same array at that location only , for instance array is 1 2 3 , so a[0]=2 , a[1]=1 , since difference of 1 is maximum with 3 and difference of 2 is maximum with 3 , Now whatever manipulations I do I perform with the array size reduced by 1 , so Now I calculate the maximum difference value and place it in 0th index and after that I run a loop till the size of reduced array and count the no of times this maximum value appears , but this approach takes too long , can someone suggest some simple logic .Input is of the form
No of test cases is for e.g 2
no of elements in first array
maximum no of pairs in 1st array
no of elements in 2nd array
maximum no of elements in 2nd array
#include <stdio.h>
#include<math.h>
int max=0;
int main()
{
int test_no, n1,n2,i,j,a,b,count1=1,count2=1;
scanf("%d",&test_no);
printf("\n");
scanf("%d",&n1);
printf("\n");
int arr1[n1];
for(i=0;i<n1;i++)
{
scanf("%d ",&arr1[i]);
}
for(i=0;i<n1-1;i++)
{
for(j=i+1;j<=n1-1;j++)
{
a=abs(arr1[i]-arr1[j]);
if(max<=a)
max=a;
}
arr1[i]=max;
max=0;
}
int temp;
max=arr1[0];
for(i=1;i<n1-1;i++)
{
if(max<arr1[i])
{
temp=max;
max=arr1[i];
arr1[i]=temp;
arr1[0]=max;
}
}
for(i=1;i<n1-1;i++)
{
if(arr1[i]==arr1[0])
{
count1++;
}
}
printf("\n");
scanf("%d",&n2);
int arr2[n2];
max=0;
for(i=0;i<n2;i++)
{
scanf("%d ",&arr2[i]);
}
for(i=0;i<n2-1;i++)
{
for(j=i+1;j<=n2-1;j++)
{
a=abs(arr2[i]-arr2[j]);
if(max<=a)
max=a;
}
arr2[i]=max;
max=0;
}
temp=0;
max=arr2[0];
for(i=1;i<n2-1;i++)
{
if(max<arr2[i])
{
temp=max;
max=arr2[i];
arr2[i]=temp;
arr2[0]=max;
}
}
for(i=1;i<n2-1;i++)
{
if(arr2[i]==arr2[0])
{
count2++;
}
}
printf("%d \n",count1);
printf("%d",count2);
return 0;
}
Sort the array (this takes n log n time).
The maximum difference is now obviously the value of the last element minus that of the first.
To get that same difference, you need the same first element and the same end element*, so that you only need to count how many elements are equal to the first (say 4), how many elements are equal to the last (say 3), and take the lesser of the two values (here 3).
size_t i;
for (i = 1; i < arrayLength/2; i++) {
if ((sortedArray[i] != sortedArray[0])
||
(sortedArray[n-1-i] != sortedArray[n-1])) {
break;
}
}
// i is now the number you need.
To sort an array in C you also have a ready-made library function.
Or you can do this in O(N) time, by simply scanning the array:
int minVal = INT_MIN;
int maxVal = INT_MAX;
int cntMin = 0;
int cntMax = 0;
for (i = 0; i < n; i++) {
if (arr[i] < minVal) {
minVal = arr[i];
}
if (arr[i] > maxVal) {
maxVal = arr[i];
}
if (arr[i] == minVal) { cntMin++; }
if (arr[i] == maxVal) { cntMax++; }
}
if (minVal == maxVal) {
return n/2;
}
return min(cntMin, cntMax);
Example:
0 0 0 0 1 2 3 4 5 6 6 6
Maximum difference is 6 and is to be found 3 times.
0 1 2 3 4 5 6 6 6
Maximum difference is still 6, and is to be found once only.
If you want to count all possible pairs (e.g. in [ 01, 02, 61, 62, 63 ] you want to have (01,61) ... (02, 63) ), even if your note about removing elements seems to indicate otherwise, then instead of returning the minimum of cntMin and cntMax, just return their product. If they are equal, return N*(N-1) ).
--
(*) to get the same difference with two different numbers, one of them has to be either less than the minimum, or more than the maximum, of the initial range, which is contradictory. E.g. to get 6 other than from 6 and 0, you would need 7 and 1, or 5 and -1. But 7 is more than 6, and -1 is less than 0. So your array's maximum difference once it includes either 7 or -1 is no longer 6.
All you need to do is count how many times the smallest and the largest number are present in the array. When you have done that the number of pairs is found by a simple multiplications.
This can be done like:
#include <stdio.h>
#include <limits.h>
#define N 7
int main(void) {
int arr[N] = {1, 2, 1, 4, 1, 5, 5};
int max = INT_MIN;
int min = INT_MAX;
int i;
int countmax = 0;
int countmin = 0;
for (i=0; i < N; ++i)
{
if (arr[i] > max)
{
// Found new max value --> reset counter to 1
countmax = 1;
max = arr[i];
}
else if (arr[i] == max)
{
// Found same max value --> increment counter
countmax++;
}
if (arr[i] < min)
{
countmin = 1;
min = arr[i];
}
else if (arr[i] == min)
{
countmin++;
}
}
if (max == min)
{
// Special case: All elements are the same
printf("%d pairs with difference 0 found\n", N*(N-1)/2);
else
{
printf("%d pairs with difference %d found\n", countmin * countmax, abs(max-min));
}
return 0;
}
Output:
6 pairs with difference 4 found

How to get indexes alone from an array

I have the following array and index
0 1 2 3 4 5 6 7 8 <-indexes -- n values
7 7 8 8 6 9 8 7 9 <-values -- array x
I have another array with the indices
0 1 2 3 4 5 6 7 8 <-indexes -- m values
7 8 9 9 8 7 7 8 9 <-values -- array y
what I want is to obtain all the index(in reverse order of array x):
6: 4
7: 7 1 0
8: 6 3 2
9: 8 5
And then, for each element in the y array, I want to make another array index[ ] have the values. So, index[6] = 4, index[7] = 7, 1, 0 etc.
I have done:
for (i=n-1; i>=0; i--) {
index[y[i]] = index[y[i]]+i;
}
for (i=0; i<m; i++) {
strings[i] = strings[i] + index[x[i]];
}
for (i=0; i<m; i++) {
printf("%d",strings[i]);
}
The desired output is to print a sequence like 710632858563271071063285 but this is not printing the desired output.
int i;
int j;
// Assuming 9 is the highest integer possible
for(j=0;j<=9;j++){
int k=0;
for(i=n-1;i>=0;i--){
if(x[i]==j){
index[j][k]=i;
k++;
}
}
// Adding a -1 to denote that no more indices were found
index[j][k]=-1;
}
PS: Make sure that index is big enough...
#include <stdio.h>
#include <string.h>
int main(void) {
int x[] = {7, 7, 8, 8, 6, 9, 8, 7, 9};
int n = sizeof(x)/sizeof(*x);
int y[] = {7, 8, 9, 9, 8, 7, 7, 8, 9};
int m = sizeof(y)/sizeof(*y);
int index[10][10];
memset(index, -1, sizeof(index));
for(int i = n -1; i >= 0; --i){
int j = 0;
while(index[x[i]][j] >= 0)
++j;
index[x[i]][j] = i;
}
for(int i = 0; i < m; ++i){
for(int j = 0; j < 10 && index[y[i]][j] >= 0; ++j){
printf("%d", index[y[i]][j]);
}
}
return 0;
}
I'd say that array is not the best for this purpose as you have to iterate multiple times over it every time you want to know what numbers are at what indexes. If memory isn't an issue you will do much better with combination of data structures to efficiently perform this task.
An array is fine for matching index with value. What I suggest is to keep numbers in linked list. Every node would also keep linked list of indexes that number appears on. This way you'd do much better because of search time.
Adding value would mean that you:
1) check if there is already value at given index in an array. If there is - you remove this index from linked list of indexes for given number.
2) Then you put new value at given index and if this is first appearance of this value, else you add new index to list of indexes this value appears.
If you implement adding to the linked list of indexes in descending order to get all the numbers and indexes you just need to iterate over list of values and print list of indexes.
This might look like an overkill but I don't know a thing about the actual problem at hand. Your array might be thousands indexes long. That would set you up for handling these more efficiently.
try this one:
#include <stdio.h>
int main()
{
int A[]={7,7,8,8,6,9,8,7,9};
for(int i=0;i<=9;i++)
{
int flag=0;
for(int j=8;j>=0;j--)
{
if(A[j]==i)
{
if(flag==0)
printf("%d:",i);
flag=1;
printf(" %d",j);
}
}
if(flag==1)
printf("\n");
}
return 0;
}
This should work as expected. Note, that the main loop is simpler than the output loop.
#include <stdio.h>
int idx[9][9] = {{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1},
{-1,-1,-1,-1,-1,-1,-1,-1,-1}};
int x[9] = {7, 7, 8, 8, 6, 9, 8, 7, 9};
void buildIndex(int maxval, int idx_len, int x_len) {
assert(maxval >= x_len);
for(int i = 0; i < x_len; i++)
for(int j = idx_len - 1; j >= 0; j--)
if(idx[x[i]-1][j] == -1) {
idx[x[i]-1][j] = i;
break;
}
}
int main() {
buildIndex(9, 9, 9);
/* output the idx */
for(int k = 0; k < 9; k++)
if(idx[k][8] != -1) { /* ignore empty idx lines */
printf("%d: ", k+1);
for(int l = 0; l < 9; l++)
if(idx[k][l] != -1) /* write all valid numbers */
printf("%d ", idx[k][l]);
printf("\n");
}
}
This program outputs:
6: 4
7: 7 1 0
8: 6 3 2
9: 8 5
I am sure, you can adapt the output to your needs yourself. The "big" idea in this code is to fill the arrays in idx backwards and in the output just ignore the unset values at the beginning.

Resources