intersection and union of two unsorted arrays - c

This code is meant to find intersection and union of two unsorted arrays which may contain duplicates.
The union works fine, but when trying to access intersection array memory, I get garbage results.
I can't find out where the problem is, tried to debug it but it didn't help me much either.
note: remember[] is an array of flags that saves indices of intersection elements in two arrays.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,n1,n2,j;
int user1[20];
int unionSize;
int intersectionArraySize;
printf("enter array1 size::\n");
scanf("%d",&n1);
printf("array1: ");
for(i=0; i<n1; i++)
{
scanf("%d",&user1[i]);
if (i>0) if(user1[i]==user1[i-1]) user1[i-1]=user1[i];
}
int user2[20];
printf("enter array2 size::\n");
scanf("%d",&n2);
for(i=0; i<n2; i++)
{
scanf("%d",&user2[i]);
if (i>0) if(user2[i]==user2[i-1]) user2[i-1]=user2[i];
}
int unionArray[20];
int remember[20]= {0}; // save index of common elements btn 2 arrays
int intersectionArray[20]={0};
intersectionArraySize=0;
unionSize=n1;
int index=0;
for(i=0; i<n1; i++)
{
for(j=0; j<n2; j++)
{
if (user1[i]==user2[j])
{
remember[j]=1;
intersectionArray[index]==user1[i];
intersectionArraySize++;
index++;
}
else unionArray[i]=user1[i];
}
}
for(i=0; i<n2; i++)
{
if(remember[i]!=1)
{
unionArray[n1]=user2[i];
n1++;
unionSize++;
}
}
printf("Union: ");
for (i=0; i<unionSize; i++)
{
if(i==unionSize-1) printf("%d\n",unionArray[i]);
else printf("%d ,",unionArray[i]);
}
printf("intersection: ");
for (i=0; i<intersectionArraySize; i++)
{
if(i==intersectionArraySize-1) printf("%d\n",intersectionArray[i]);
else printf("%d ,",intersectionArray[i]);
}
return 0;
}

Here's the problem:
intersectionArray[index]==user1[i];
It should be:
intersectionArray[index]=user1[i];
General comments on your code:
It's pretty bad designed. For instance, unless you have a very good reason, do not calculate both at the same time. Have one block that does intersection and only that. Same for union.
You declare the arrays with a fixed size, which is a bit weird since you ask for the sizes. Not a very big deal, but be aware of dangers if you enter a size over 20.
What's worse is that unionArray has a size of 20. It should be 40.
index and intersectionArraySize is practically the same variable. Get rid of one.
This looks messy:
for (i=0; i<unionSize; i++) {
if(i==unionSize-1) printf("%d\n",unionArray[i]);
else printf("%d ,",unionArray[i]);
}
Do like this:
for (i=0; i<unionSize-2; i++) {
printf("%d ,",unionArray[i]);
}
printf("%d\n", unionArray[unionSize-1]);
Also not a very big deal, but why do a conditional check on every single element when you know that it is the last that should be treated specially?

Related

How to insert multiple elements in array in c program?

I can insert an element in an array but I want to know that is this possible to insert multiple(two or three..) element in an array by using c program. I tried a little, there is no problem or eror but it doesn't work.
Here is my code which I had tried to make a program which can insert multiple element in array:
#include<stdio.h>
int main(){
int size,i;
printf("Enter array length - ");
scanf("%d",&size);
int array[size];
printf("Enter array elements : \n");
for(i=0; i<size; i++){
scanf("%d",&array[i]);
}
int el_no; //el_no means elemnet no which user should input
printf("How many element you want to insert - ");
scanf("%d",&el_no);
int element[el_no];
printf("Element value - ");
for(i=0; i<el_no;i++){
scanf("%d",&element[i]);
}
int index[el_no];
printf("Index no - ");
for(i=0; i<el_no;i++){
scanf("%d",&index);
}
for(i=0; i<el_no;i++){
for(i=index[i]; i< size+el_no;i++){
array[i+1]=array[i];
}
}
for(i=0; i<el_no; i++){
array[index[i]]=element[i];
}
for(i=0; i<size+el_no; i++){
printf("%d\t",array[i]);
}
return 0;
}
You can't do what you want (at least, not directly). Once you say
int array[size];
that array can only hold size number of elements, no more.
Your program first stores values into array[0], array[1], ..., up to array[size-1]. That's perfectly fine.
But then when you say
for(i=0; i<el_no;i++){
for(i=index[i]; i< size+el_no;i++){
array[i+1]=array[i];
}
}
you are trying to move some of the array's elements over (to make room for new ones), but you're moving them outside the array, which is never going to work.
One fix (not quite what you want) would be to declare the array bigger than it needs to be. For example, you could say
int array[size+5];
and then later double-check that it will be big enough:
printf("How many element you want to insert - ");
scanf("%d",&el_no);
if(el_no > 5) {
printf("sorry, I can't insert that many\n");
exit(1);
}
The "better" way, although it gets into pointers and dynamic memory allocation perhaps sooner than you're ready to, would be to use a pointer simulating an array, using malloc to allocate space for it to point to:
int *array = malloc(size * sizeof(int));
Than, later, you can resize it:
array = realloc(array, (size + el_no) * sizeof(int));
This is just an example -- in reality, you'd need to check the return values of malloc and realloc to make sure they're not NULL, indicating that something has gone wrong.
Also there are some other problems with your code. The way you're using the auxiliary index array looks wrong, and probably isn't necessary at all.
As I tried to show in my comment, you're not specifying an index for the index array. In that loop, you're scanfing to &index, which is the wrong argument for scanf. Your compiler should be giving you a warning:
warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int (*)[el_no]' [-Wformat=]
32 | scanf("%d",&index);
| ~^ ~~~~~~
| | |
| | int (*)[el_no]
| int *
Despite the warning, what's most likely happening is each value you enter in the loop is getting stored at index[0]. You need to change that loop from
for(i=0; i<el_no;i++){
scanf("%d",&index);
}
to
for(i=0; i<el_no;i++){
scanf("%d",&index[i]); // <-- note the [i] addition
}
You've done this correctly in the previous loop
for(i=0; i<size; i++){
scanf("%d",&array[i]);
}
This may not be the only problem, but it's a problem, and too long for a comment.
I've edited the code and stated where to correct the faults
#include<stdio.h>
int main(){
Initialize j here
int size,i,j;
printf("Enter array length - ");
scanf("%d",&size);
int array[size];
printf("Enter array elements : \n");
for(i=0; i<size; i++){
scanf("%d",&array[i]);
}
int el_no; //el_no means elemnet no which user should input
printf("How many element you want to insert - ");
scanf("%d",&el_no);
int element[el_no];
printf("Element value - ");
for(i=0; i<el_no;i++){
scanf("%d",&element[i]);
}
int index[el_no];
printf("Index no - ");
here is a mistake you can correct
for(i=0; i<el_no;i++){
scanf("%d",&index[i]);//Add[i] here
}
Also do not use same variable in more than one for loop in a nested loop
for(i=0; i<el_no;i++){
for(j=index[i]; j< size+el_no;j++){//Use any other variable than 'i' in this for loop
depending on what you want to do you can correct this line below
array[i+1]=array[i];
}
}
for(i=0; i<el_no; i++){
array[index[i]]=element[i];
}
for(i=0; i<size+el_no; i++){
printf("%d\t",array[i]);
}
return 0;
}
All is good.
Hope you find it useful.

Understanding the arrays in C

I'm new to C and need some help to understand how this piece of code works. I know that it reads the values that the user writes, puts them into an array, and then prints them out.
But I don't understand why I need two "counters" (i and j) to do this. Can someone help me to figure it out?
#include<stdio.h>
int main ()
{
int A[5];
int i=0;
int j=0;
while (i < 5)
i++;
printf("Enter your %d number\n", i);
scanf("%d", &A[i]);
}
while (j < 5)
{
j++;
printf ("\n%d\n", A[j]);
}
}
Technically, what you have aren't two counters, but two loops. If you wanted, to, you could just reuse i for the second loop as well, by doing something like this:
while (i < 5)
i++;
printf("Enter your %d number\n", i);
scanf("%d", &A[i]);
}
i = 0;
while (i < 5)
{
i++;
printf ("\n%d\n", A[i]);
}
As for why you have two loops, the reason is simple. The first loop (using i in your code), reads the 5 integers into the array A. After the first loop concludes, your array A holds the 5 int values, which you could've used however you wanted. In your case, you want to print those values. So what you do is use a loop for looping over the array elements and printing the values to the screen, one by one.
You don't need it, you can simply reset the first and reuse it. However you must increment your index only after having using it otherwise you will overflow the limit of the array :
#include<stdio.h>
int main ()
{
int A[5];
int i=0;
while (i < 5) {
printf("Enter your %d number\n", i);
scanf("%d", &A[i]); // the last must be 4 not 5
i++; //<== increment here
}
i=0;
while (i < 5)
{
printf ("\n%d\n", A[i]); //idem
i++;
}
}

how to speed up my code?

I want to write a bits seggregation code, but I wonder what can I do to increase the speed of the code. Can I get rid of some loops etc?
Aim of code is to seperate 1s and 0s of an array. 0s should be at left and 1s should be at right.
Here is my code:
#include <stdio.h>
int main() {
//code
int testCase;
scanf("%d\n", &testCase);
while(testCase>0) {
int n;
scanf("%d\n", &n);
int countzero = 0;
while(n>0) {
int i;
scanf("%d ", &i);
if(i==0){
countzero++;
}
}
for(int i=0; i<countzero; i++) {
printf("0");
}
for(int i=countzero; i<n ; i++) {
printf("1");
}
printf("\n");
}
return 0;
}
I wonder what can I do to increase the speed of the code. Can I get rid of some loops etc?
The time complexity of each test case will be O(n) regardless of what you do, since you have to read all the numbers before you know when you stop printing zeros.
Now, as for speeding up, you can indeed remove at least one loop. Hint: you don't need to count how many zeros there are, only how many ones.

Order an array when filling it in C

I have a problem with this code: when I enter a negative value as the first value entered the program replace it with 0. If I enter it anywhere else it works fine. Why is happening that? How can I fix it? Thanks in advance!
#include <stdio.h>
#define N 5
int main () {
float a[N], temp;
int i, j;
for (i=0; i<N; i++) {
scanf ("%f", &a[i]);
for (j=0; j<N; j++)
if (a[i]<a[j]) {
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
for (i=0; i<N; i++)
printf ("%.2f ", a[i]);
return 0;
}
You're very close. As others have mentioned the problem is that a is uninitialized so it's full of garbage until you fill it. But if you initialize it it will be full of zeros which will mess with the sorting.
The trick is to only sort up to where you've filled. That would be i.
for (i=0; i < N; i++) {
scanf ("%f", &a[i]);
for (j=0; j < i; j++) {
if (a[i]<a[j]) {
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
}
Note it's j < i. It's not j <= i because there's no point in comparing an element to itself
Incidentally, this is an inefficient way to sort. It's basically bubble sort, but unlike bubble sort which can stop early if the array is sorted, you'll always do ((n-1)*n)/2 operations which gets large fast. At 100 elements you're doing 4950 comparisons.
You're better off reading everything in and sorting the whole list.
The inner loop (the one with index j) is completely undefined because it iterates through a before all the values in a have even been initialized.
To fix this, you need to separate the population of the array into its own loop, then do further processing on it. From the lines:
if (a[i]<a[j]) {
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
I'm guessing that you're trying to implement bubble sort. This does need two nested loops, but the way you have it right now is wrong - array population needs to be on its own and before you even begin sorting, as stated before.

Segmentation fault in my program

My sorting program results in a "segmentation fault 11":
#include <stdio.h>
int main()
{
// Asking user for number of inputs in an array
int n;
do {
printf ("enter the number of intigers you want to sort\n");
scanf("%d",&n);
}while (n<=1);
int sort [n];
printf ("please enter %d numbers\n",n);
for (int i=0; i<n; i++) {
scanf("%d",&sort[i]);
}
printf("you entered\n ");
for (int i=0; i<n; i++) {
printf(" %d ",sort[i]);
}
printf("\n");
int k,c,i,x;
for (i=0;i<n;i++) {
if (sort[i]<sort[i-1]){
k=i-2;
while (sort[k]>sort[i]){
k--;
}
k++;
x =sort[i];
c=i;
for (c=i;c>k;c++){
sort[c-1]=sort[c];
}
sort[k]=x;
}
}
printf ("Sorted numbers :-\n");
for (int i=0; i<n; i++) {
printf ("%d ",sort[i]);
}
printf ("\n");
return 0;
}
Now I have looked up the internet and found that it is caused because a variable has value that exceeds the system's memory limit. But cannot understand that concept.
for (i=0;i<n;i++)
{
if (sort[i]<sort[i-1])
You are accessing array out of its bounds.Maybe you want to start your loop from 1.Also
k=i-2;
while (sort[k]>sort[i])
will access index beyond 0 for example if i is 0 or 1 or 2
k = i - 2; looks unstable for low values of i.
sort[i - 1] is undefined when i is zero.
The thing causes the behaviour of sort[k] to be undefined.
Moral of the story: check all the array indexes before attempting to retrieve an array element. Your debugger will help you here.
In addition to all said before:
c=i;
for (c=i;c>k;c++){
sort[c-1]=sort[c];
}
sort[k]=x;
i can be 0 -> c can be 0 -> sort[c-1] would also result in accessing array out of bounds.
There is no need to initialize c=i twice. It is enough to do it in the loop-declaration

Resources