Program to remove the duplicate elements from an array in c - c

I've tried to write a program that removes the duplicate values from an array. I've partly managed to do so since my program is able to remove any ONE of the numbers which are repeated TWICE in the array. So the problem is that if a number is repeated thrice only one of the number is removed, i.e. the other two is still left in the array, also if more than one number is repeated even then only the number which comes first in the array is removed. I really cannot understand what's wrong with my code and why is it unable to remove numbers that are repeated more than two times. I've already surfed through the internet regarding this issue and though I got different ways to remove the duplicate elements, I still don't know what's wrong with my code.
#include <stdio.h>
#include <stdlib.h>
int dup(int [],int);
int main()
{
int i,n,index,a[20];
printf("Enter n value \n");
scanf("%d",&n);
printf("Enter array values \n");
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(i=index;i<n;i++)
a[i]=a[i+1];
n-=1;
}
}
printf("Output: \n");
for(i=0;i<n;++i)
printf("%d\n",a[i]);
return (EXIT_SUCCESS);
}
int dup(int a[],int size)
{
int i,j,pos=-1;
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
pos=j;
return pos;
}
}
}
if(pos==-1)
return pos;
}
OUTPUT
Enter n value
5
Enter array values
12
24
3
12
24
Output:
12
24
3
24
It clearly fails to remove the other repeated element "24". Also if a number was repeated thrice only one of the number would be removed.

for(i=0;i<n;++i) // <-------------------------------------- for i
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(i=index;i<n;i++) // <--------------------------- for i
a[i]=a[i+1];
n-=1;
}
}
You are using the same loop variable for two loops, one nested inside the other. This cannot work. Use different variables. Live demo.

The Problem seem to lie in the if condition in second loop.
for (k = j; k < size; k++) {
arr[k] = arr[k + 1];
}
Simply put this piece of code after your if condition
if(a[i]==a[j])
and it will work.

My mistake, at first glence I thought you had problem with n after running this it worked.
#include <stdio.h>
#include <stdlib.h>
int dup(int [],int);
int main()
{
int i,n,index,a[20], count;
printf("Enter n value \n");
scanf("%d",&n);
count = n;
int j;
printf("Enter array values \n");
for(i=0;i<n;++i)
scanf("%d",&a[i]);
for(i=0;i<n;++i)
{
index=dup(a,n);
if(index==-1)
{
printf("No duplicate elements");
break;
}
else
{
a[index]=0;
for(j=index;j<n;j++)
a[j]=a[j+1];
n-=1;
}
}
printf("Output: \n");
for(i=0;i<n;++i)
printf("%d\n",a[i]);
return (EXIT_SUCCESS);
}
int dup(int a[],int size)
{
int i,j,pos=-1;
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
pos=j;
return pos;
}
}
}
if(pos==-1)
return pos;
}
OUTPUT
Enter n value
5
Enter array values
12
24
3
12
24
Output:
12
24
3

You should name your iterator variables better so you might not confuse them in nested loops, or as you do, use the same twice in a nested loop.
This skips all variables after your first removal.
and you don't have to do this
if(pos==-1)
return pos;
skip the if as it is not necessary and if at this position posis not -1then you would have no return which would be UB I think.

Related

Removing Duplicate values and adding 0 on their place

I have written a code to remove duplicate values and add 0 on there place .
But i feel like my code should be much better than this,if anybody can give a better idea of developing this code.
Please suggest me and advice me.
Input--2,3,4,3,6
output--2,3,4,0,6
Here is my code:
#include<stdio.h>
int main()
{
int a[100],b[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
for(i=0;i<size;i++)
{
b[i]=a[i];
}
for(i=0;i<size;i++)
{
for(j=i+1;j<size;j++)
{
if(a[i]==a[j])
{
b[j]=0;
}
}
}
for(i=0;i<size;i++)
printf("%d\n",b[i]);
return 0;
}
Clear duplicates as they are entered as follows, comparing with the values entered so far:
#include<stdio.h>
int main() {
int a[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
for(j=0;j<i;j++){
if(a[j]==a[i]) {
a[i]=0; /* found duplicate among previous entries! */
break;
}
}
}
for(i=0;i<size;i++)
printf("%d\n",a[i]);
return 0;
}
Here is some of my idea:
Solution 1:
Use bit to indicate whether a number occurred yet.
e.g On 32bit machine, 1 int has 32bit, if your number range is 1 ~ 1000, then you need 32 int, you can change it range when you met a larger number, by realloc().
If your number range is small, then it's quite suitable.
Solution 2:
Store sorted numbers in a binary tree, so that you can search quicker.
You can use the single array itself, and mark at the positions where you find a duplicate in it. Something like this.
#include<stdio.h>
int main() {
int a[100];
int i,j,size;
scanf("%d",&size);
for(i=0;i<size;i++) {
scanf("%d",&a[i]);
}
for(i=1; i<size; i++) {
for(j=i-1; j>=0; j--) {
if(a[i]==a[j]) {
a[i]=0;
break;
}
}
}
for(i=0;i<size;i++)
printf("%d ",a[i]);
return 0;
}
Here's an improvement, but I agree it feels like it can be significantly better (Maybe I'll get back to this later...):
#include<stdio.h>
int main()
{
int a[100];
int i,j,size,left;
scanf("%d",&size);
for(i=0;i<size;i++)
{
scanf("%d",&a[i]);
}
left = size;
for(i=0;i<size&&left>1;i++) // If there's only 1 left, it's not a duplicate
{
if(a[i] == 0) // No need to test these, already done
continue;
for(j=i+1,left=0;j<size;j++)
{
if(a[i]==a[j])
{
a[j]=0;
}
if(a[j]!=0)
left++; // If we don't get here, there's nothing left to test
}
}
for(i=0;i<size;i++)
printf("%d\n",a[i]);
return 0;
}
So basically, don't search for 0's ahead of current position, and when searching for anything else count (mark actually) if there is anything left to test.

Odd-Even Sort using cuda Programming

I'm trying to implement odd-even sort program in cuda-c language. But, whenever I give a 0 as one of the elements in the input array, the resulted array is not properly sorted.In other cases, however, it is working for other input.I don't understand what is the problem with the code.Here is my code:
#include<stdio.h>
#include<cuda.h>
#define N 5
__global__ void sort(int *c,int *count)
{
int l;
if(*count%2==0)
l=*count/2;
else
l=(*count/2)+1;
for(int i=0;i<l;i++)
{
if(threadIdx.x%2==0) //even phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
{
int temp=c[threadIdx.x];
c[threadIdx.x]=c[threadIdx.x+1];
c[threadIdx.x+1]=temp;
}
__syncthreads();
}
else //odd phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
{
int temp=c[threadIdx.x];
c[threadIdx.x]=c[threadIdx.x+1];
c[threadIdx.x+1]=temp;
}
__syncthreads();
}
}//for
}
int main()
{int a[N],b[N],n;
printf("enter size of array");
scanf("%d",&n);
print("enter the elements of array");
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("ORIGINAL ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
}
int *c,*count;
cudaMalloc((void**)&c,sizeof(int)*N);
cudaMalloc((void**)&count,sizeof(int));
cudaMemcpy(c,&a,sizeof(int)*N,cudaMemcpyHostToDevice);
cudaMemcpy(count,&n,sizeof(int),cudaMemcpyHostToDevice);
sort<<< 1,n >>>(c,count);
cudaMemcpy(&b,c,sizeof(int)*N,cudaMemcpyDeviceToHost);
printf("\nSORTED ARRAY : \n");
for(int i=1;i<=n;i++)
{
printf("%d ",b[i]);
}
}
Your kernel code had two main errors that I could see:
On the odd phase (for even length array, or even phase for odd length array), your last thread will index out of bounds at c[threadIdx.x+1]. For example, for 4 threads, they are numbered 0,1,2,3. Thread 3 is odd, but if you access c[3+1], that is not a defined element in your array. We can fix this by restricting each phase to work on all threads but the last one.
You were using __syncthreads() inside a conditional statement that would not allow all threads to reach the barrier. This is a coding error. Read the documentation. We can fix this by adjusting what code is inside the conditional regions.
In the main code, your final printout statements were indexing incorrectly:
for(int i=1;i<=n;i++)
that should be:
for(int i=0;i<n;i++)
You also have typo here:
print("enter the elements of array");
I assume that should be printf.
The following code has the above errors fixed, and seems to run correctly for me for arrays up to length 5 (your hardcoded limit on N). Even if you increased N, I'm not sure this would work beyond the size of a warp and certainly would not work beyond the threadblock size, but hopefully you are aware of that already(if not, read the doc link about __syncthreads()).
"Fixed" code:
#include<stdio.h>
#include<cuda.h>
#define N 5
#define intswap(A,B) {int temp=A;A=B;B=temp;}
__global__ void sort(int *c,int *count)
{
int l;
if(*count%2==0)
l=*count/2;
else
l=(*count/2)+1;
for(int i=0;i<l;i++)
{
if((!(threadIdx.x&1)) && (threadIdx.x<(*count-1))) //even phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
intswap(c[threadIdx.x], c[threadIdx.x+1]);
}
__syncthreads();
if((threadIdx.x&1) && (threadIdx.x<(*count-1))) //odd phase
{
if(c[threadIdx.x]>c[threadIdx.x+1])
intswap(c[threadIdx.x], c[threadIdx.x+1]);
}
__syncthreads();
}//for
}
int main()
{int a[N],b[N],n;
printf("enter size of array");
scanf("%d",&n);
if (n > N) {printf("too large!\n"); return 1;}
printf("enter the elements of array");
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("ORIGINAL ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",a[i]);
}
int *c,*count;
cudaMalloc((void**)&c,sizeof(int)*N);
cudaMalloc((void**)&count,sizeof(int));
cudaMemcpy(c,&a,sizeof(int)*N,cudaMemcpyHostToDevice);
cudaMemcpy(count,&n,sizeof(int),cudaMemcpyHostToDevice);
sort<<< 1,n >>>(c,count);
cudaMemcpy(&b,c,sizeof(int)*N,cudaMemcpyDeviceToHost);
printf("\nSORTED ARRAY : \n");
for(int i=0;i<n;i++)
{
printf("%d ",b[i]);
}
printf("\n");
}
The usual recital about proper cuda error checking belongs here.

how to find array element from user input

friend i am new in c ,so i face problem in a ,code, plz if there is any wrong in my logic,take it as a pardon eye,
I am trying to find the element in a two dimensional array, so i have declare a two dimensional array in my code, i will take a user input, the input will compare with data in an full array a column index of two dimensional array, if any data found similar of that column index then it will give the same row data of another column of array. if i give a input in my code it is giving output of the number is not in array index, though the number is in the array index, so i dont understand where is my fault.
plz help me to fix the problem.
here is my code :
#include<stdio.h>
int main()
{
int arr[10][3]={{1,5},
{2,8},
{3,27},
{ 4,64},
{5,125},
{6,216},
{ 7,343},
{8,512},
{ 9,729},
{ 10,1000}};
int i, num;
printf("Enter a number\n");
scanf("%d",&num);
for(i=0;i<10;i++)
{
if (num==arr[i][0])
printf("%d",arr[i][1]);
break;
}
if (num==10)
printf("the number is not there");
return 0;
}
You have an errant semi-colon:
if (num==10);
printf("the number is not there");
That call to printf will run each time because there is no body for the if statement. With better formatting:
if (num==10);
printf("the number is not there");
As #zoska points out, you also have the same bug here:
if (num==arr[i][0]);
I would do the following three changes at the minimum:
Change int arr[10][3] to int arr[10][2]
Change
if (num==arr[i][0]);
printf("%d",arr[i][1]);
to
if (num == arr[i][0]) {
printf("%d",arr[i][1]);
}
Change
if (num==10);
printf("the number is not there");
to
if (i == 10) { // note: 'num' changed to 'i'
printf("the number is not there");
}
Your code should look like this in the future
#include <stdio.h>
int main(void)
{
int arr[10][2] = {
{1,5},
{2,8},
{3,27},
{4,64},
{5,125},
{6,216},
{7,343},
{8,512},
{9,729},
{10,1000}
};
int i, num;
printf("Enter a number\n");
scanf("%d", &num);
for(i = 0; i < 10; i++)
{
if (num==arr[i][0]) {
printf("%d", arr[i][1]);
break;
}
}
if (i == 10) {
printf("the number is not there");
}
return 0;
}

Getting Runtime Error in competitive algo challenge (SPOJ MAJOR)

According to the problem we have to find whether an element occurs more than n/2 times or not and then print Yes or No accordingly.
The numbers can vary from 10^-3 to 10^3.
I took an array count[2005] and then adding 1000 to each input to make 10^-3 equal to 0 i.e, -1000+1000=0 and then storing no.of occurrences of -1000 in count[0] and same for the rest elements. Therefore:
lower limit= -1000+1000=0;
higher limit= 1000+1000=2000;
But still I am getting memory access violation. Here is the link to the original problem: http://www.spoj.com/problems/MAJOR/
#include<stdio.h>
int main()
{
int t,n,a,count[2005],max,check,temp;
scanf("%d",&t);
while(t--)
{
check=0;
scanf("%d",&n);
for(int i=0;i<2005;i++)
count[i]=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a);
temp=a+1000;
count[temp]++;
if(count[temp]>(n/2))
{
check=1;
max=temp-1000;
break;
}
}
if(check==1)
printf("YES %d\n",max);
else
printf("NO\n");
}
return 0;
}
Problem to your code is you are not reading input fully - SPOJ demands that your program should read input fully, not break in middle.
Solution to your problem: Just take an arr of size (10^6+1) and first read all inputs and then apply algorithm. Remember this if you break while reading input too, it will always be SIGSEGV. So, always read input fully on every programming website.
Here is your modified code and it is ready to get AC:
#include<stdio.h>
int arr[1000002]; // Array of Size (10^6+2)
int main()
{
int t,n,a,count[2005],max,check,temp,i;
scanf("%d",&t);
while(t--)
{
check=0;
scanf("%d",&n);
for(int i=0;i<2005;i++)
count[i]=0;
for(i=0;i<n;i++)
scanf("%d",&arr[i]); // READING INPUT FULLY IN AN ARRAY
for(i=0;i<n;i++)
{
a=arr[i]; // Now, a=arr[i] and previous algorithm applies now
temp=a+1000;
count[temp]++;
if(count[temp]>(n/2))
{
check=1;
max=temp-1000;
break;
}
}
if(check==1)
printf("YES %d\n",max);
else
printf("NO\n");
}
return 0;
}

Please help me debug my Insertion Sort Program

I can't figure out what is going wrong with it.
If input: 4,56,5,2 then output shown is: 2,4,0,1304.
If input: 27,54,43,26,2 then output shown is: 2,26,0,1304,0
If input: 34,87,54,4,34 then output shown is: 4,34,0,1304,0
Basically, only first two sorted nos are being shown in output and on other places either 1304 or 0 is showing for any set of input.
#include <conio.h>
#include <stdio.h>
void main()
{
int a[10],b[10];
int i,size,j,k;
clrscr();
printf("please tell how many nos you want to enter");
scanf("%d",&size);
printf("Enter the nos");
for (i=0;i<size;i++) scanf("%d",&a[i]);
b[0]=a[0];
//insertionSort algo ---->
for (j=1;j<size;j++)
{
for (k=j-1;k>=0;k--)
//handling comparision with b[0]
if (k==0&&(a[j]<b[0])) {
b[1]=b[0];
b[0]=a[j];
}
//handling comparison with b[1:size-1]
if (k>0&&(a[j]<b[k])) { b[k+1]=b[k]; }
if (k>=0&&(a[j]>=b[k])) { b[k+1]=b[k]; break; }
}
for (i=0;i<size;i++) printf("%d\n",b[i]);
getch();
}
Use a algorithm that's more simple:
After reading the numbers, copy array A to B to keep the original input.
For ascending sort, set i = 0, j = i + 1
loop j until end of array, if B[j] < B[i] then exchange the two numbers.
Increase i, set j = i + 1, go to step 3. unless i >= size.
print arrays A and B
The algorithm can be optimized later.
Here are the minimal changes with /* comments */ to make your program work:
#include <conio.h>
#include <stdio.h>
void main()
{
int a[10],b[10];
int i,size,j,k;
clrscr();
printf("please tell how many nos you want to enter");
scanf("%d",&size);
printf("Enter the nos");
for (i=0;i<size;i++) scanf("%d",&a[i]);
b[0]=a[0];
//insertionSort algo ---->
for (j=1;j<size;j++)
for (k=j-1;k>=0;k--)
{ /* the inner loop must contain all the if statements */
//handling comparision with b[0]
if (k==0&&(a[j]<b[0])) {
b[1]=b[0];
b[0]=a[j];
break; /* done; don't mess with b[0+1] below */
}
//handling comparison with b[1:size-1]
if (k>0&&(a[j]<b[k])) { b[k+1]=b[k]; }
if (k>=0&&(a[j]>=b[k])) { b[k+1]=a[j]; break; } /* =a[j] */
}
for (i=0;i<size;i++) printf("%d\n",b[i]);
getch();
}

Resources