Order an array when filling it in C - 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.

Related

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++;
}
}

I am trying to print an array in the reversed order but it is saying segmentation fault

This is the code that I wrote to print the array in the reversed order. But, it is giving the output "segmentation fault". Please help and explain.
#include<stdio.h>
int main()
{
int a;
scanf("%d",&a);
int arr[a];
for(int i=0;i<a;i++)
scanf("%d",&arr[i]);
for(int j=a-1;j>=0;j++)
printf("%d ",arr[j]);
}
You should have your second cycle decreasing j instead. In your code you wrote:
for(int j=a-1;j>=0;j++)
printf("%d ",arr[j]);
So after the first iteration j becomes a while you would like it to decrease by 1 at each step down to 0.
You should decrease your j index insted of increasing it.
Use following loop:
for(int j=a-1;j>=0;j--)
printf("%d ",arr[j]);
Avoid writing loops that count in non-trivial ways. To print backwards, simply change the index:
for(int i=0; i<a; i++)
scanf("%d", &arr[a-i-1]);

intersection and union of two unsorted arrays

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?

Bubble sort doubts

#include<stdio.h>
#include<conio.h>
int main( )
{
int a[100];
int i, j, temp, n ;
printf("how many numbers you want to sort : \n");
scanf("%d",&n);
printf("Enter %d number values you want to sort\n", n);
for(j=0; j<n; j++)
scanf("%d",&a[j]);
for(j=1;j<n;j++)
how do we know that the above mentioned for loop must be repeated n times,how should one develop logic for that ,I know that the inner for loop will only help to sort the elements in the list once,then why should we repeat inner loop n times
{
for(i=0; i<n; i++)
{
if(a[i]>a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
printf ( "\n\nArray after sorting:\n") ;
for ( i = 0 ; i <n ; i++ )
printf ( "%d\t", a[i] ) ;
getch();
}
in the internal loop you will find maximum. you can't be sure other numbers are sorted.
other version (faster):
do
for (i = 0; i < n-1; i++) do:
if A[i] > A[i+1] then
swap(A[i], A[i+1])
end if
end for
n = n-1
while n > 1
(not checking maximum of previous loops)
In order to understand that code, extract the code that outputs the current values of the array to a separate function. Then, every time you swap two elements, output a message saying which elements you swapped and what the resulting array now looks like.
You will not only see how it sorts, but you will also find a bug in the code. I'd try to help you further, but I don't want to spoil you the learning experience.

Understanding my mistake with for-loop

I'm new to C and I'm trying to practice my knowledge by doing programs by my own without the use of the internet. I'm stuck with a small and probably dumb mistake but i can't seem to understand what it is. I'm trying to build an hour glass but before i do so i need to understand printing triangles. I'm really going step by step with this and I have tried to understand my mistake for very long with this.
I have my code below and I'm trying to print j where i need j to print normally 12345 then 1234, 123 etc.. but when I use temp-- it skips by printing 123,1,1 and closes the program.
Can somebody have a look at it and tell me what the problem with me second for loop?
#include <stdio.h>
int main()
{
int i,j,k,num, temp=0;
printf("Enter a number: ");
scanf("%d", &num);
temp=num;
for (i=1; i<=num; i++) // Step1: Take care of the rows --> check
{
for (j=1; j<=temp; j++)
{
printf("%d", j);
temp-=1;
}
printf("\n");
}
}
You both increment j and decrement temp which leads to odd effects. You probably don't want to decrement temp. Or you need to reset temp before the inner loop, rather than before the outer loop.
Or, indeed, you do not really need temp at all. Here are two variants of the code, one creating a triangle growing, and one creating a triangle shrinking. Neither needs temp (though t-dn.c could use a variable in place of the expression num - i + 1, but the compiler will probably handle that anyway — it is a basic optimization).
t-up.c
#include <stdio.h>
int main(void)
{
int i,j,num;
printf("Enter a number: ");
scanf("%d", &num);
for (i=1; i<=num; i++)
{
for (j=1; j<=i; j++)
printf("%d", j);
printf("\n");
}
}
t-dn.c
#include <stdio.h>
int main(void)
{
int i,j,num;
printf("Enter a number: ");
scanf("%d", &num);
for (i=1; i<=num; i++)
{
for (j=1; j<=num-i+1; j++)
printf("%d", j);
printf("\n");
}
}
Example output
$ ./t-up
Enter a number: 5
1
12
123
1234
12345
$ ./t-dn
Enter a number: 5
12345
1234
123
12
1
$
t-ok.c
Another variant, keeping the temp variable around:
#include <stdio.h>
int main(void)
{
int i,j,num,temp;
printf("Enter a number: ");
scanf("%d", &num);
temp=num;
for (i=1; i<=num; i++)
{
for (j=1; j<=temp; j++)
printf("%d", j);
printf("\n");
temp--;
}
}
It produces the decreasing pyramid I believe you want. It places the decrement outside the inner loop.
You're decrementing your j-loop condition within the j-loop. This means that every time you print a number, you also decrease the size of your loop (not at all what you want). To fix this, you need to move your temp-=1 from
for (i=1; i<=num; i++) // Step1: Take care of the rows --> check
{
for (j=1; j<=temp; j++)
{
printf("%d", j);
temp-=1;
}
printf("\n");
}
to
for (i=1; i<=num; i++) // Step1: Take care of the rows --> check
{
for (j=1; j<=temp; j++)
{
printf("%d", j);
}
temp-=1;
printf("\n");
}
This decreases the size of your j-loop AFTER you've finished going through it, so you should wind up with the right amount of numbers.
You could even do away with your temporary variable by reversing the i-loop like such
for ( i = num ; i > 0 ; i-- ) {
for ( j = 1 ; j <= i ; j++ ) {
printf("%d", j);
}
printf("\n");
}
for a simpler code.

Resources