Trouble with extra zero in bubble sort in C - c

I am trying to sort, say, 10 integers in ascending order using bubble sort in C.
This is the code I am using:
#include<stdio.h>
void main()
{
int x[20],i,j;
float temp;
printf("Enter 10 values: \n");
for(i=0;i<10;i++)
{
printf("x[%d]: ",i+1);
scanf("%d",&x[i]);
}
for(i=0;i<10-1;i++)
{
for(j=0;j<=10-i-1;j++)
{
if(x[j]>x[j+1])
{
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
printf("The sorted list in ascending order is \n");
for(i=0;i<10;i++)
{
printf("%5d",x[i]);
}
}
The problem is that I am getting an extra zero as output despite giving only non-zero entries as my 10 integers.
This is the input and the corresponding output I am getting. Note that the second output gives a zero and the value 19 has disappeared from the sorted list:
Enter 10 values:
x[1]: 4
x[2]: 2
x[3]: 7
x[4]: 4
x[5]: 8
x[6]: 2
x[7]: 3
x[8]: 9
x[9]: 13
x[10]: 19
The sorted list in ascending order is
2 0 2 3 4 4 7 8 9 13
--------------------------------
Process exited after 44.89 seconds with return value 5
Press any key to continue . . .
I am unable to locate my precise mistake.

for(i=0;i<10-1;i++)
{
for(j=0;j<10-i-1;j++)
{
if(x[j]>x[j+1])
{
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
the bug is when i = 0 then inner loop condition is j<=10-0-1=9, then you compare a[j] and a[j+1], but a[j+1] could be a[10], the array starts from 0 to 19, and you only initialized the first 10 integers(0-9), the left 10 integers(10-19) is 0, so there will be an extra 0 in your result.
change j<=10-i-1 to j<10-i-1, and the code will run as you expect.

Related

Why is my programme showing Segmentation Fault on Ubuntu but working fine on Geeks IDE?

Experts, this is the program I made for First Come First Serve Scheduling in C language.
For the inputs like -
4
0 0 0 0
1 2 3 4
and inputs like -
5
0 1 2 3 4
4 3 1 2 5
My program is giving Segmentation fault (Core dumped) when I tried running it on my Ubuntu but it worked fine on GeeksForGeeks IDE.
And for the inputs like -
6
4 3 2 1 2 3
4 3 2 3 4 5
My program is working fine on my Ubuntu as well as on GeeksForGeeks IDE.
#include<stdio.h>
void main(){
int n,i;
printf("\nEnter the number of jobs:\n");
scanf("%d",&n);
int at[n],bt[n],at_copy[n];
printf("\nEnter the arrival time:\n");
for(i=0;i<n;i++){
scanf("%d",&at[i]);
at_copy[i]=at[i];
}
printf("\nEnter the burst time:\n");
for(i=0;i<n;i++)
scanf("%d",&bt[i]);
int priority[n],min=at_copy[0],k,j;
for(j=0;j<n;j++){
min=at_copy[0];
for(i=0;i<n;i++){
if(at_copy[i]<min){
min=at_copy[i];
k=i;
}
}
at_copy[k]=999;
priority[j]=k;
}
int ct[n],wt[n],tat[n],t=0;
for(i=0;i<n;i++){
if(at[i]<t)
k=0;
else
k=at[i];
t+=bt[i]+k;
ct[i]=t;
tat[i]=ct[i]-at[i];
wt[i]=tat[i]-bt[i];
}
printf("\nProcess\tAT\tBT\tCT\tTAT\tWT\n");
for(i=0;i<n;i++){
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",i+1,at[i],bt[i],ct[i],tat[i],wt[i]);
}
}
In the output, I am expecting a table like structure displaying the arrival time, burst time, completion time, burst time, turnaround time and waiting time of all the processes.
Here:
int priority[n],min=at_copy[0],k,j;
for(j=0;j<n;j++){
min=at_copy[0];
for(i=0;i<n;i++){
if(at_copy[i]<min){
min=at_copy[i];
k=i;
}
}
at_copy[k]=999;
...
Imagine what happens, when at_copy[0] is the minimal value. Then, the condition atcopy[i]<min is never true and k remains uninitialized resulting in an out-of-bounds access here:
at_copy[k]=999;
You have to initialize k with 0, since you assume in the first iteration, that at_copy[0] is the minimum.
int priority[n],min=at_copy[0],k=0,j;
With Geeks-IDE, you might have been "lucky" and k had the value 0 without being initialized.

C program to check lottery numbers: why some tests fail?

This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}
Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.
Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....

Null distribution of Rank tests

I need to compute the distribution of a test statistic in C. The test statistic is based on ranks. So rather than generating observations and rank them I think I can use natural numbers and there all possible distinct combinations for my computation. So i have written a code in C. But it is not displaying the expected output, just some symbols I suppose. When I ran it in an online compiler it displayed a Segmentation fault. Please help me rectify the errors. Any suggestions will be appreciated. The following is the code that I have written.
#include<stdio.h>
#include<conio.h>
void main()
{
int i1,i2,i3,j1,j2,j3,i,k,p,m1,n1,combo1,combo2,combo3;
int fcombo1=0, fcombo2=0, fcombo3=0;
m1=3;
n1=3;
p=1;
int factorial(int n,int r);
for(i1=1;i1<=6;i1++)
for(i2=i1+1;i2<=6;i2++)
for(i3=i2+1;i3<=6;i3++)
for(j1=1;j1<=6;j1++)
if(j1!=i1&&j1!=i2&&j1!=i3)
for(j2=1;j2<=6;j2++)
if(j2!=i1&&j2!=i2&&j2!=i3&&j2>j1)
for(j3=1;j3<=6;j3++)
if(j3!=i1&&j3!=i2&&j3!=i3&&j3>j2)
{
for(i=1;i<=3;i++)
for(k=0;k<=1;k++)
{
if(i==1)
{
combo1=factorial(i-1,1)*factorial(m1-1,p)*factorial(i1-i,p-k)*factorial(n1-i1+i,p+k+1);
fcombo1=fcombo1+combo1;
}
else if(i==2)
{
combo2=factorial(i-1,p)*factorial(m1-1,p)*factorial(i2-i,p-
k)*factorial(n1-i2+i,p+k+1);
fcombo2=fcombo2+combo2;
}
else if(i==3)
{
combo3=factorial(i-1,p)*factorial(m1-1,p)*factorial(i3-i,p-
k)*factorial(n1-i3+i,p+k+1);
fcombo3=fcombo3+combo3;
}
printf("%3d%3d%3d%3d%3d%3d%3d%3d%3d\n",i1,i2,i3,j1,j2,j3,
fcombo1,fcombo2,fcombo3);
}
}
getch();
}
int factorial(int n,int r)
{
if(n<r)
return(0);
else if(n==r)
return(1);
else if(r==1)
return(n);
else
return(factorial(n-1,r)+factorial(n-1,r-1));
}
Output:
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 2 0
1 2 3 4 5 6 0 2 0
1 2 3 4 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 4 4
1 2 4 3 5 6 0 4 8
Segmentation fault
First of all, the way you design the program uses 10 levels of for loops, it is usually a terrible idea to do that, think about how you can refactor it.
Second, for the specific problem, it lies in the factorial function, if r goes to less than 0, e.g. for the case of factorial(1, 0), the function will recurse infinitely, because none of the termination condition matches. As a result, the program aborted by segfault because of stack overflow in the function. So depending on how you need to calculate, add a terminate condition in the function, for example:
int factorial(int n,int r)
{
if(n<r)
return(0);
else if(n==r)
return(1);
else if(r<=1)
return(n);
else
return(factorial(n-1,r)+factorial(n-1,r-1));
}
or
if (r <= 0) abort(); // this should never happen
I just wanted to know why i am getting a segmentation fault....
I guess the reason is because of Stack Overflow. You are calling a recursive function factorial within a 8 levels of nesting. so this will be in the millions of calls.
Each time you call a function, some memory is allocated in the stack. Over millions of nested calls, the stack will overflow and cause a segmentation fault

Range of even numbers using recursion c

I know that there are a lot of questions and answers about recursion here, but hear me out. In my program, I'm trying to get a range of only even numbers. The user enters two numbers between -5000 and 5000; if the numbers are out of order (that is, greater number is entered first) the numbers are swapped into order; and in the recursion function, a simple function return 0 or 1 determining if the current value is even or odd using n%2. The problem is that I cannot figure out how to actually work with recursion.
int recursive_function(int first_number, int second_number)
{
printf("\n Entering sum function for range %d to %d",
first_number, second_number);
if(first_number > second_number)
return 1;
else
{
if(is_even(first_number) == 0)
{
printf("\n Adding: %d", first_number);
return (first_number += recursive_function(first_number + 1, second_number));
printf("\nThis equals added");
}
else
{
printf("\n Skipping: %d", first_number);
return (first_number += recursive_function(first_number + 1, second_number));
printf("\nThis equals skipped");
}
}
}
The program works, in terms of the recursion terminating, I just do not understand how I am supposed to pop the rest of the stack. Here is a representation of what is supposed to be the output. (Assuming the values are 10 and 20)
Processing the range 10 to %20:
Entering the sum function for range 10 to 20
Adding: 10
Entering the sum function for range 11 to 20
Skipping: 11
Entering the sum function for range 12 to 20
Adding: 12
Entering the sum function for range 13 to 20
Skipping: 13
Entering the sum function for range 14 to 20
Adding: 14
Entering the sum function for range 15 to 20
Skipping: 15
Entering the sum function for range 16 to 20
Adding: 16
Entering the sum function for range 17 to 20
Skipping: 17
...
Entering the sum function for range 20 to 20
Adding: 20
Entering the sum function for range 21 to 20 (recursion stops here)
(This next part is where I don't know how this happens)
Exiting sum function for range 21 to 20 with result: 0
Exiting sum function for range 20 to 20 with result: 20
Exiting sum function for range 19 to 20 with result: 20
Exiting sum function for range 18 to 20 with result: 38
Exiting sum function for range 17 to 20 with result: 38
Exiting sum function for range 16 to 20 with result: 54
....
Exiting sum function for range 11 to 20 with result: 80
Exiting sum function for range 10 to 20 with result: 90
The sum of all even numbers in the range 10 to 20 is: 90
I know this has to do with popping all these statements "off the stack". The problem is all the research I have done gives me explanations with the assumption that one truly understands recursion whereas I am an amateur. Could any one help and explain in English?
To understand what is happening write down a sequence of calls on a piece of paper. Use a smaller range, say 18 to 20.
Here is an example. I omitted most of the function body leaving lines with recursive calls.
recursive_function(18, 20): <<< initial call, depth 0
printf("\n Entering
...
printf("\n Skipping: %d", 18); <<< Execution goes to this
return (18 += recursive_function(19, 20)): <<< recurses, depth 1
printf("\n Entering
...
printf("\n Adding: %d", 19);
return (19 += recursive_function(20, 20)): <<< depth 2
printf("\n Entering
...
printf("\n Skipping: %d", 20);
return (20 += recursive_function(21, 20)): <<< depth 3
printf("\n Entering
...
if(21 > 20)
return 1; <<< end of recursion
printf("\nThis equals skipped"); <<< left over at depth 2
printf("\nThis equals added"); <<< left over at depth 1
printf("\nThis equals skipped"); <<< left over at depth 0
Now you can collect all printf statements sequentially and have a resulting output. Note that in your code you skipped "Exiting..." part, while the output has it.
Popping off the stack. Popping off the stack is done for you by the compiler. It happens when function returns. You should worry about returning at a proper moment, not about how to pop off the stack.

Find the longest sequence of ascending numbers in unsorted array

Suppose the Array[10] = {10,6,11,9,-18,0,91,18,24,32}
The largest sequence will be 10,11,18,24,32 or -18,0,18,24,32
The solution to this is make another Array[10] which will store the number of sequences. Starting from the last element 32 which makes just 1 sequence i.e. the number itself.
24 makes 2
18 makes 3
91 makes 1
0 makes 4
-18 makes 5
9 makes 4
11 makes 4
6 makes 4
10 makes 5
The output should be either 5 starting from -18 or 5 starting from 10.
Can anyone help me with the code please.
more or less it will look like that, now you need to translate this to language what you are using
largestSequience = [];
temporaryArray = [];
for (element in array)
{
if (temporatySize not empty and temporarySize[lastElement]>=element)
{
if (temporaryArray.length > largestSequence.length) largestSequence = temporaryArray;
temporaryArray = [element]
}
temporaryArray.add(element)
}
What you want in C++. The running time is O(NlogN), in which N is the size of Array[]
#include<stdio.h>
#include<map>
using namespace std;
int main(void) {
int Array[10] = {10,6,11,9,-18,0,91,18,24,32};
int p[10],next[10];
int i,j,n=10;
map<int,int> places;
for(i=n;i>=0;i--){
map<int,int>::iterator ii=places.upper_bound(Array[i]);
if(ii==places.end()){ //no item on the right is larger
p[i]=1;
next[i]=-1;
}else{
next[i]=ii->second;
p[i]=p[ii->second]+1;
}
places[Array[i]]=i;
ii=places.find(Array[i]);
while(ii!=places.begin()){
ii--;
if(p[ii->second]<=p[i]){
places.erase(ii);
}else
break;
ii=places.find(Array[i]);
}
}
int longestI=0;
for(i=1;i<n;i++){
if(p[i]>p[longestI])
longestI=i;
}
for(i=longestI;i>=0;i=next[i]){
printf("%d\n",Array[i]);
}
return 0;
}

Resources