how to detect duplicates in arrays & print non duplicates? - c

void main ()
{
int x[19]={0}, i=0, y=0, u=0, p;
while (i<=19)
{
scanf("%d",&x[i]);
i=i+1;
}
for (i=u;i<=19;i++)
{
if (x[y]!=x[i+1])
p=x[y];
else
{
u++;
y++;
}
}
printf("%d",p);
}
So I used this to check for duplicates & it should print non duplicates, but as you can see this works if all are duplicates but one, as in
x[0]=1 x[1]=1 x[3]=9 x[4]=1 ... x[19]=1;
prints
9
So how to print non duplicates ? Any help ?

This would be the easiest solution, simply nest an additional for-loop. However, this takes O(n^2). Depending on the size of the array, it could be beneficial to look at a fast sort.
void main() {
int x[4] = { 1, 3, 2, 1 };
size_t i, j;
for (i = 0; i < sizeof(x) / sizeof(int); i ++) {
// Note that we only have to go to the last value before i.
for (j = 0; j < i; j ++) {
// We break if the value is a duplicate.
if (x[i] == x[j])
break;
}
// Check if the inner loop was break'ed (j < i) or not (j == i).
if (j == i)
printf("Unique: %i\n", x[i]);
}
}
One more thing: only use sizeof(x) / sizeof(int) if the size of x is known during compilation. This is the case here, but don't use it with malloc.

One of the simplest ways is to sort the array to group the duplicates together. Then, as you go through the array you only print a number if its different from the number that came before.
// Print the unique elements of a sorted array:
for(int i=0; i<N; i++){
if (i-1 >= 0 && arr[i] == arr[i-1]) { continue; }
if (i+1 < N && arr[i] == arr[i+1]) { continue; }
printf("%d\n", arr[i]);
}
To sort the array you can use the qsort function

void main ()
{
int num[20]={0}, i=0, n=0, index_num=0, init_incr=0, unique=0, n_uniq=1, temp, check=0;
while (i<=19)
{
printf("%02d- ",i+1);
scanf("%d",&num[i]);
i=i+1;
}
for (index_num=0;index_num<19;index_num++)
{
for (n=init_incr+index_num;n<19;n++)
{
if (num[index_num]!=num[index_num+1] && num[index_num]!=num[index_num-1])
{
check++;
temp=num[index_num];
unique=temp;
for (;n_uniq<=check;n_uniq++)
printf("\tunique %02d = %d\n", n_uniq, unique);
break;
}
}
}
}

Related

Remove the last comma from c loop

i have the belowo loop in c that print the prime number
for(int i = 2; i<=arraySize; i++)
{
//If arraySize is not 0 then it is prime
if (numbers[i]!=0)
printf("%d,",numbers[i]);
}
the out put after enter 50 for example is
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,
i want to to not print the last comma how i can do it
i tried this code but not working
printf("%d%s", numbers[i], (i !=arraySize-1) ? "," : "");
Instead of printing a comma after each number, print it before. Then you can use a variable to tell if this is the first number being printed, and not print the comma.
first=true;
for(int i = 2; i<=arraySize; i++)
{
//If numbers[i] is not 0 then it is prime
if (numbers[i]!=0) {
printf("%s%d", (first ? "" : ","), numbers[i]);
first = false;
}
}
I like both the other answers but just want to throw in this error prone variant on the same theme.
_Bool first = true;
for (int i = 2; i <= arraySize; i++) {
if (numbers[i] != 0) {
printf(",%d" + first, numbers[i]);
first = false;
}
}
If first is true the actual formatting string will become "%d". If it's false it'll become ",%d".
Simple: Use a pointer to the "prefix" string, printed AHEAD of the next value:
char *sep = "";
for(int i = 2; i <= arraySize; i++ ) {
if( numbers[i] ) {
printf( "%s%d", sep, numbers[i] );
sep = ", "; // I added a SP, too
}
}
Here's an alternative that uses a "limited scope" variable to index a static string. For clarity in this example, the array boundaries have been adjusted.
int main( void ) {
int numbers[] = { 1, 1, 4, 8, 9, 0, 7 };
int arraySize = sizeof numbers/sizeof numbers[0];
for( int i = 0, out = 0; i < arraySize; i++ )
if( numbers[i] )
printf("%s%d", &","[!out++], numbers[i] );
return 0;
}
The negated boolean post-incrementing value of out provides the address of the '\0' to the first instance, then the address of "," in subsequent instances.
1,1,4,8,9,7
The answers already here are fine, but I'd like to add a "simpler" solution. Simpler in that it doesn't require any further logic or extra variables. It does, however, require that you know that the first number is non-zero.
printf("%d", numbers[2]);
for (int i = 3; i < arraySize; i++)
{
if (numbers[i] != 0)
printf(",%d", numbers[i]);
}
I think the other answers overcomplicates things. I don't see any reason to have a test for every iteration in the loop. Instead, I'd simply do the special case first:
printf("%d", numbers[2]);
for (int i = 3; i <= arraySize; i++) {
if (numbers[i]!=0)
printf(",%d", numbers[i]);
}
This will however need some additional code to correctly handle the case where arraySize is lower than 3.
But I would choose another approach from the beginning, and that is writing a good function for printing an array. Could look like this:
void printArray(const int *array, int size) {
putchar('['); // Of course this is optional
if(size > 0) {
printf("%d", array[0]);
for(int i=1; i<size; i++)
printf(",%d", array[i]);
}
putchar(']'); // And this too
}
and then something like this:
int convertArray(const int *numbers, int *array, int size) {
int ret = 0;
for(int i=0; i<size; i++) {
if(number[i] != 0) {
array[ret] = numbers[i];
ret++;
}
}
return ret;
}

"If statement" is not working properly in c

I have written a program with a function that looks at a two dimensional array ir_data[60][768].
The While loop should call the "Hotspotberechnung" function only when there is a value that equals or is over 30 in a given row.
"Hotspotberechnung" should store the given row in an array[24][32] and then print the array.
The problem is that the program prints an array without any values equal or over 30.
Unfortunately, I cannot find the mistake on my own.
The While Loop:
int8_t Temperatur[768] = {0};
while (get_ir_data( &Temperatur[0], sizeof(Temperatur)/sizeof(Temperatur[0])) == 0)
{
for(int k=0; k<768; k++)
{
if(Temperatur[k] >= 30)
{
Hotspotberechnung(Temperatur,bild);
}
}
}
The function :
bool Hotspotberechnung(int8_t tabelle1[768],int8_t tabelle2[24][32])
{
int i=0, j=0, x=0, y=0;
for(j=0; j<24; j++) //Tabellen werden gefüllt
{
for(i=0; i<32; i++)
{
tabelle2[j][i] = tabelle1[(j*24)+i];
}
}
for(j=0; j<24; j++)
{
for(i=0; i<32; i++)
{
printf("%d.%d=%d\n",j,i,tabelle2[j][i]);
}
}
get_ir_data :
int8_t get_ir_data(int8_t* data, int n)
{
static uint8_t idx = 0;
if (n != 24 * 32) {
printf("Invalid size of array data!\n");
return -1;
}
memcpy(data, ir_data[idx], n);
idx++;
if (idx >= sizeof(ir_data) / sizeof(*ir_data))
return -2;
return 0;
}
tabelle1[(j*24)+i]
This index calculation is wrong. You need
tabelle1[(j*32)+i]
To verify, calculate the maximal value of (j*24)+i, given the ranges of j (0 to 23) and j (0 to 31). Is it 767?

Why I can't assign a function return to a matrix element?

Ok, so I need to input a matrix of n elements and to replace each composite number with the closest prime number. I made functions for reading the matrix, showing the matrix, finding if a number is prime or not and finding the closest prime number to a number and they work.
Here is what I did and the problem is that the replacement does not work and I get the error: Process terminated with status -1073741510 (0 minute(s), 18 second(s))
#include <stdio.h>
#include <stdlib.h>
int n;
int readMatrix(int **matrix)
{
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
printf("matrix[%d][%d]=", i, j);
scanf("%d", &matrix[i][j]);
}
}
return matrix;
}
void showMatrix(int **matrix)
{
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
}
int prime(int a)
{
int c = 0;
for (int i=1; i<a; i++) {
if (a % i == 0) {
c++;
}
}
if (c == 1) {
return 1;
} else return 0;
}
int nearPrime(int b)
{
int lp, bp, ok = 0, p;
lp = b - 1;
bp = b + 1;
while (ok != 1) {
if (prime(lp) == 1) {
ok = 1; break;
}
lp--;
}
ok = 0;
while (ok != 1) {
if (prime(bp) == 1) {
ok = 1; break;
}
bp++;
}
if ((b-lp) < (bp-b)) {
p = lp;
} else p = bp;
return p;
}
int main()
{
int **matrix, aux;
printf("n=");
scanf("%d", &n);
matrix = malloc(n*sizeof(int *));
if (matrix == NULL) exit(1);
for (int i=0; i<n; i++) {
matrix[i] = malloc(n*sizeof(int));
if (matrix[i] == NULL) exit(1);
}
readMatrix(matrix);
showMatrix(matrix);
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (prime(matrix[i][j]) == 0 && matrix[i][j] != 1) {
matrix[i][j] = nearPrime(matrix[i][j]);
}
}
}
showMatrix(matrix);
for (int i=0; i<n; i++) free(matrix[i]);
free(matrix);
return 0;
}
Can you tell me why it is not working?
UPDATE
I think I solved it. When checking if a matrix number is prime I also added the condition that it needs to be different than 1 because the program will return 0 when checking if 1 is prime number and it needs to return 1 since 1 is actually a prime number.
Thanks for all the tips!
I think I may have found the issue in your code. The problem lies in your nearPrime function. It will work for most numbers that it takes in as an argument but that is not the case if you input the number 1 for this function. Consider what will happen if it does take in the number 1.
Then, your variable lp = (1 - 1) = 0. When you then further input this into the prime function, it will not return 1 because of the way it is implemented. You then keep on decreasing this number if no prime is found and since the number is now negative, it will never even enter in the for loop in the prime function and the prime function will then always return 0. Thus, you will get stuck in the while(ok != 1) loop for a really long time and that is why your process terminates. To fix this, make sure you check that lp != 0 before proceeding to enter the loop. Since you are also checking for the nearest prime, you also need to check if lp is 0 before returning a value. In short, make the following change to your code.
int nearPrime(int b)
{
int lp, bp, ok = 0, p;
lp = b - 1;
bp = b + 1;
if (lp != 0)
{
while (ok != 1) {
if (prime(lp) == 1) {
ok = 1; break;
}
lp--;
}
}
ok = 0;
while (ok != 1) {
if (prime(bp) == 1) {
ok = 1; break;
}
bp++;
}
if (((b - lp) < (bp - b)) && lp != 0) {
p = lp;
}
else p = bp;
return p;
}
One other thing: your readMatrix function seems to expect a return type of int but you are returning the argument matrix, which is of type int**. Furthermore, in your main code, you are not actually doing anything with your returned value so probably change the return type of your readMatrix function to void (and don't return matrix, of course).

Counting Comparisions in Quicksort: Wrong answer

I have written code to compute the number of comparisons done in QuickSort.
The algorithm increases the count of comparisons by m-1 whenever a quicksort is performed on an array of length m (Since pivot will be compared with everything other than itself).
The choice of the pivot is always the first element of the array.
When I try to use it on an array of 10000 entries, it is giving me a wrong answer.
A correct answer is supposed to be 162085.
The link to the dataset is given below:
https://drive.google.com/file/d/0B0D_kFnzj_RrYm9NT0lrM3JfN2c/view?usp=sharing
The total comparisons are stored in x.
#include<stdio.h>
long long x=0;
int size=10000;
int A[10000];
int B[10000];
void quicksort(int A[],int begin,int end)
{
if(begin<end){
int i=begin;
int j=end;
int k;
int pivot=begin;
for(k=begin+1;k<=end;k++)
{
if(A[k]>A[pivot])
{
x++;
B[j]=A[k];
j--;
}
else
{
x++;
B[i]=A[k];
i++;
}
}
B[i]=A[pivot];
for(k=begin;k<=end;k++)
{
A[k]=B[k];
}
quicksort(A,begin,i-1);
quicksort(A,i+1,end);
}
else
{
if((end-begin)==1) x++;
}
}
int main()
{
FILE *myFile;
myFile = fopen("QuickSort.txt", "r");
int i;
for (i = 0; i < 10000; i++)
{
fscanf(myFile, "%d", &A[i]);
}
quicksort(A,0,size-1);
for(i=0;i<size;i++)
{
printf("%d\n",A[i]);
}
printf("%lld",x);
}
this part is wrong:
for(k=begin+1;k<=end;k++)
{
if(A[k]>A[pivot])
{
x++;
B[j]=A[k];
j--;
}
else
{
x++;
B[i]=A[k];
i++;
}
}
you don't have to go from begin till end. you only should go from begin till i>j.
see link: https://en.wikipedia.org/wiki/Quicksort
there the interesting lines are:
do
i := i + 1
while A[i] < pivot
do
j := j – 1
while A[j] > pivot
if i >= j then
return j
swap A[i] with A[j]
c / c++
i = begin;
j = end;
while(true)
{
while(i< end && A[i] < A[pivot])
{
i++;
}
while(j> begin && A[j] >= A[pivot])
{
j--;
}
if(i<j)
{
int temp = A[i]; //std::swap(A[i],A[j]);
A[i] = A[j];
A[j] = temp;
else
{
break;
}
}
In this code I don't use B because quicksort is an "inplace" algorithm and because of that we don't need to save the result into a different array

Comparing numbers inside of an array

Values are entered into an array by the user and then i have this For Loop to compare the numbers once they have all been entered. What i'm trying to do is find the first larger number in the array.
i = 0;
next = a[++i];
for (i = 0; i < len; i++)
{
if (a[i] > a[next])
{
++next;
if (a[i] < a[next])
{
printf("%d is the first larger number.", a[i]);
}
}
}
When I debug my program I see that when "i" is being compared to a[next] its not taking the value of the number inside that position "i" of the array. i've attempted using "i" instead of a[i] when starting my If statements but that doesn't seem to fix the issue.
Here is my Corrected code. made a few more minor changes just for practice
#include <stdio.h>
int main(int argc, const char * argv[])
{
const int len = 4;
int a[len];
int i;
int j = a[i-1];
for (i = 0; i < len; i++) {
printf("Enter a number:");
scanf("%d", &a[i]);
}
i = 0;
for (i = 1; i < len; i++) {
if (a[i] > a[j])
{
printf("%d is the first larger number.", a[i]);
break;
}
}
}
I think you're looking for the first place where the array is not decreasing; i.e., the index of the first element i such that a[i] > a[i-1].
for (i = 1; i < len; i++) {
if (a[i] > a[i-1]) {
printf("%d is the first larger number", a[i]);
break;
}
}
A new version, printing out the first part of the sequence:
for (i = 1; i < len; i++) {
if (a[i] > a[i-1]) {
printf("\n%d is the first larger number", a[i]);
break;
}
printf("%d ", a[i]);
}
Whatever what you are trying to achieve!! you never say:
next = a[++i];
than
a[i] > a[next] !! a[next] can be beyond the size of your array
EX:
A[] = {0, 7, 2, 3, 1}
next = A[1] = 7
A[next] = A[7] = !! //what u think it is?
Assuming that you are looking for the first local maximum, one solution is to declare a variable called best to keep track of the largest number seen so far. Set best to the first element of the array a[0]. Then check for the first element of the array that is less than best.
best = a[0];
for ( i = 1; i < len; i++ )
{
if ( a[i] > best )
best = a[i];
else if ( a[i] < best )
break;
}
printf( "%d is the first larger number.\n", best );

Resources