How to Check for Array Duplicates in C - c

The aim of my C program is to take two arrays (both comprised of unique numbers) and merge the two of them into a new array, eliminating any numbers that are the same between both of them. However, when I try to merge the two, it instead prints back both arrays combined without eliminating any duplicates.
My program creates "array_C" by first adding in the elements from "array_A". Afterwards, it checks if there are duplicates between "array_B" and "array_C" using a counter variable. For every value in "array_C" that the for loop checks, if the value of "array_B" is not equal to the value in "array_C", the counter decreases by 1. If after all the values in "array_C" are checked, the counter is <= 0, that means there are no duplicates of that value in "array_C", and it should be added to the end of "array_C". I keep track of this using a "position" variable.
//Creation of array_C
int length_C = length_A + length_B;
int array_C[length_C];
//Copying array_A to array_C
for (i = 0; i < length_A; i++) {
array_C[i] = array_A[i];
}
//Checking array_C against array_B for duplicates
counter = length_A;
int position = length_A;
for (i = 0; i < length_B; i++) {
for (j = 0; j < length_C; j++) {
if (array_B[i] != array_C[j]) {
counter--;
} else {
counter++;
}
}
//this is the position tracker to add new value in array_C
if (counter <= 0) {
array_C[position] = array_B[i];
position++;
}
}
If I entered this:
Enter the length of array 1: 6
Enter the elements of the array: 1 2 3 4 5 6
Enter the length of array 2: 6
Enter the elements of the array: 3 4 5 6 7 8
I expect the results should look like this:
Here is the merged array:
1 2 3 4 5 6 7 8
But instead, it looks like this:
1 2 3 4 5 6 3 4 5 6 7 8
So apparently something is going wrong and it is not understanding that it should only add variables that are not duplicates.

Your logic is flawed. That's why you are getting unexpected outcome. See the following revision in your code:
for (i = 0; i < length_B; i++) {
int skip = 0;
for (j = 0; j < length_C; j++) {
if (array_B[i] == array_C[j]) {
skip=1;
break;
}
}
if(skip == 1) continue;
array_C[position++] = array_B[i];
}

the problem is with the logic inside your inner for loop. according to the problem statement if any value of array_c matches with any value of array_b you should get rid of that value otherwise add the value to array_c. so you can simply try doing the following. please make sure you understand the code. if you have any question feel free to ask.
for (i = 0; i < length_B; i++) {
bool isExistInArrayC = false;
for (j = 0; j < length_C; j++) {
if (array_B[i] == array_C[j]) {
isExistInArrayC = true;
break;
}
}
//this is the position tracker to add new value in array_C
if (isExistInArrayC == false) {
array_C[position] = array_B[i];
position++;
}
}

The suggestions will certainly work, but performance (especially with large size arrays) will be very poor. I would maintain a sorted array "C" and do a binary search into it when adding integers from array B.
You'll need a double-linked list for array C of course.

Related

How to loop for a specific amount

I am writing a program that would iterate through a sequence of characters, where every 4 counts would add the iterated 4 characters into a char array which means that it must be able to constantly be updating every 4 counts.
For example,
The sequence:
char sequence[32] = "qRiM1uOtGgXl5yuNPJwKo4+bAdQuPUbr";
I want a loop that would be able to get every four characters, which in this case the first 4 characters is "qRiM".
Then I would want it to be stored in a char array:
char test[4]; (This must be able to print qRiM)
Then when 4 counts has been done then the cycle would repeat where the next 4 characters would be "1uOt"
I've tried to attempt this but it would only print out qRiM and that the test[4] array is not updating.
int count_steps = 0;
for (int i = 0; i < 32; i++) {
// Adds a character from a sequence into the test array until 4
while(count_steps < 4) {
test[i] = sequence[i];
count_steps++;
}
// Checks if four counts has been done
if (count_steps == 4) {
//decoder(test, decoded_test);
// Prints out the four characters
for(int j = 0; j < 4; j++) {
printf("%c\n", test[j]);
}
// Resets back to 0
count_steps = 0;
}
else {
continue;
}
}
With details explaination from torstenvl, you can rewrite code:
for (int i = 0; i < 32; i++) {
test[i%4] = sequence[i];
if ((i+1) % 4 == 0) {
printf("\n");
for(int j = 0; j < 4; j++) {
printf("%c\n", test[j]);
}
}
}
test[i] = sequence[i];
This line assigns the ith entry in test to the ith entry in sequence. But test only has 4 entries, so on the second iteration, you are writing to test[4] throught test[7]. You need to use count_steps as the index in test.
You also need to add count_steps to i when accessing sequence so that the correct index in sequence is set in test.
And since you're adding processing 4 characters in each iteration of the for loop, you need to increment i by 4, not by 1
demo
for (int i = 0; i < 32; i += 4/* increment by 4 */) {
// Adds a character from a sequence into the test array until 4
while(count_steps < 4) {
test[count_steps] = sequence[i + count_steps]; // use count_steps as index in test and offset in sequence
count_steps++;
}
...
}

Group specific array elements together C

Say, you have an array,
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
Is it possible to output the display as such:
[0 6 12, 1 7 13, 2 8 14, 3 9 15, 4 10 16]
Such that each new array element consists of 3 previous array elements in that pattern, where every 6th element is not included.
so far all I can think of is, creating a temporary array, looping over the array elements and copying the respected element across, but I have no idea how to approach that. Sorry I'm having difficulty providing example code, as the whole concept confuses me.
int i,j,adder = 0;
for(i=0;i<5;i++){ //loop over 5 times for new array of size 5
adder += 1;
for(j=i+(i*5);j<i+(5*adder);j++){ //changing between elements and not including 6th value
//stuck here
}
printf("%d", arr[i]);
}
You had the right idea to use nested loops, but the inner loop needs to increment by 6 every time.
printf("[");
for (i = 0; i < 5; i++) {
printf("[");
for (j = i; j < 17; j += 6) {
printf("%d ", arr[j]);
}
printf("]%s", (i < 4 ? ", " : ""));
}
printf("]");

How to find if there is a common difference between integers in an array?

Lets say that the users input is 7 10 12 14 16 20 25. I want the output to be a set of numbers in ascending order whose difference is all the same. So for this case it would be: 12,25,7,20 OR 10,14,16,20. Notice how in both cases their difference is the same and theres at least 4 numbers in the output. How do i do this?
I'm trying to find if there is a common difference between the integers in the array. I first thought that it would be better to sort them in ascending order and then if sorted_array[1] - sorted_array[0] = sorted_array[2] - sorted_array[1] then theres a common difference. But then it doesnt work if the numbers are for example 4 5 12 13 16 20 27 28 where theres a common difference between [12,5], [20,13], [27,20]
int r = 0;
int l = 0;
while (r < n) {
if (arr_days4[r] - arr_days4[l] == arr_days4[r+1] - arr_days4[l+1]) {
sequence_difference++;
r++;
i++;
}
else if(arr_days4[i] - arr_days4[r] > arr_days4[r + 1] - arr_days4[l+1]){
l++;
}
else{
r++;
}
printf("\n%d", sequence_difference);
}
When I try to print sequence_difference it gives me 32767...Can anyone help?
first of all you should clear the requirement or specify the provided input and the output you want.
but seeing your code there's many mistakes i can figure out
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
a = array[i];
array[i] = array[j];
array[j] = a;
}
}
}
the inner loop must iterate n-1 times because of at last pass i will exceed n if you don't do this.
next error is in your while loop you have used i which is having value n becuase of upper for loop.
so try to look at these mistakes.
for more info you can check

What needs to be modified to get desired result in this C code

I have written a small piece of code that would perform Run length encoding kind of stuff on 1-D array but still far from desired result.
main()
{
int a[8]={2,0,0,0,3,0,0,9};
int i,temp,ct=0,flag,m;
int found[90]={0};
for(i=0;i<=7;i++)
{
if(!a[i])
{
ct++;
if(!found[a[i]])
{
flag=i;
found[a[i]]=1;
}
}
}
a[flag]=ct;
m=ct;
for(i=0;i<m;i++)
{
printf("%d",a[i]);
}
}/* end of main*/
Now for above array i would like to have output something below
2 5 0 3 9
But with my piece of code am getting
2 5 0 0 3
Can I have any suggestion on that?
Shouldn't run length encoding turn 2,0,0,0,3,0,0,9 into 2 1 0 3 3 1 2 0 9 1?
1) The first thing I see is wrong is that you aren't looking at the entire array. You're using < to stop before 8, but also stopping at 7, so you only evaluate array items 0 - 6.
2) If ct stands for count it's never reset (ct=0 only on declaration). Also it's assignment is this: a[flag]= ct; which overwrites your original data. It basically tracks the value of i.
This is my version I've just put together:
#define SZ 8
main()
{
int a[SZ]={2,0,0,0,3,0,0,9};
int i; //absolute position
int runningCount = 1; //because we start at array index 1 and not zero
for (i = 1; i <= SZ; i++) {
if (a[i - 1] == a[i]) //value same as one before it...
runningCount++;
else { // new value found. print last one, and the count of the last one.
printf("%d %d ", a[i - 1], runningCount);
runningCount = 1; //reset for next loop
}
}
return 0;
}
The output is 2 1 0 3 3 1 0 2 9 1
Ok based on the comment left below, your algorithm would actually look like this:
#define SZ 8
main()
{
int a[SZ]={2,0,0,0,3,0,0,9};
int i; //absolute position
int zero_count = 0; //target zeros specifically...
for (i = 0; i < SZ; i++) {
if (a[i] == 0)
zero_count++;
}
//now write it out in a bizarre, unparsable format again...
for (i = 0; i < SZ; i++) {
if (a[i] != 0) //write out all non zero values
printf("%d ", a[i]);
if (i == 0) { //this says put the zero count after the first number was printed
printf("%d 0 ", zero_count); //inserting it into a strange place in the array
}
}
return 0;
}
which outputs: 2 5 0 3 9
You need a <= in your for loop:
for(i=0;i<=7;i++)
instead of
for(i=0;i< 7;i++)
Otherwise you miss the last element.
All you appear to be doing is (a) counting the number of times 0 occurs in the array, and (b) replacing the first occurrence of 0 with that count. It's not clear how this is meant to be a useful encoding.
In any case, you're not getting your desired result, at least in part, because you're only modifying one element of the array. I suspect what you want, or at least think you want, is to shift the non-zero elements of the array to the left as you encounter them.
What is the utility of compressing the array in the way you propose? Is some other piece of code going to have to reconstruct the original, and if so how do you expect to do so from your desired result?

how to iterate all array element starting from a random index

I was wondering if is it possible to iterate trough all arrays elements starting from any of its elements without pre-sorting the array.
just to be clearer suppose i have the array of 5 elements:
0 1 2 3 4
i want to read all elements starting from one of their index like:
2 3 4 0 1
or
4 0 1 2 3
the idea is to keep the element order in this way:
n ,n+1 ,..., end ,start, ..., n-1
One solution could be (pseudocode):
int startElement;
int value;
for(startElement;startElement<array.count;startElement++){
value = array[startElement];
}
for(int n = 0; n<startElement;n++){
value = array[n];
}
but I don't know if there's a better one. Any suggestions?
Use the modulus operator:
int start = 3;
for (int i = 0; i < count; i++)
{
value = array[(start + i) % count];
}
Yes it's possible. Try this:
int index = arc4rand() % count; // picks an index 0 to 4 if count is 5
// iterate through total number of elements in array
for (int i = 0; i < count; i++)
{
// if element 4 go back to zero
if (index == count-1) { index = 0; }
//do something here
someValue = yourArray[index];
}
EDIT: When I first answered this I thought you were asking about picking the random index. I probably misunderstood. I also use the modulus operator to iterate arrays as in the first answer, and that's probably the more elegant approach. You can also use the if statement above, so I'll leave my answer here as an alternate.

Resources