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.
Related
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.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
My try
int *nb=(int *)malloc(ntc*sizeof(int));// no of bus
int barr[ntc][ntc];// bus route array
int *nc=(int *)malloc(ntc*sizeof(int));// no of city
int carr[ntc][ntc];// city array
scanf("%d",&ntc); // input -> test case
for(i=0;i<ntc;i++)
{
scanf("%d",&(nb[i])); // input -> no of bus
p=2*nb[i];
for(k = 0; k < p; k++)
{
scanf("%d", &(barr[i][k])); // input -> bus route array
}
scanf("%d", &nc[i]); // input -> no of city for which bus passing by count is to be determined
q=nc[i];
for(j = 0; j < q; j++)
{
scanf("%d", &(carr[i][j])); // input -> city array
}
}
I am accepting input for various test cases. For test case#1 I am taking input of nb,barr,nc,carr arrays. This continues for ntc no of test cases. Below i have written the input statement of the problem
The first line contains the number of test cases (T), after which T
cases follow each separated from the next with a blank line. For each
test case, The first line contains the number of GBuses.(N) Second
line contains the cities covered by them in the form a1 b1 a2 b2 a3
b3...an bn where GBus1 covers cities numbered from a1 to b1, GBus2
covers cities numbered from a2 to b2, GBus3 covers cities numbered
from a3 to b3, upto N GBuses. Next line contains the number of cities
for which GBus count needs to be determined (P). The below P lines
contain different city numbers.
Suppose now input is
2
4
15 25 30 35 45 50 10 20
2
15
25
10
10 15 5 12 40 55 1 10 25 35 45 50 20 28 27 35 15 40 4 5
3
5
10
27
Now when i am printing the values just for a sanity check what i am getting is very strange.
printf("no of test case %d\n",ntc);
for(i=0;i<ntc;i++)
{
printf("Case #%d\n",i+1);
printf("no of bus %d\n",nb[i]);
p=2*nb[i];
printf("bus route array");
for(j=0;j<p;j++)
{
printf(" %d ",barr[i][j]);
}
printf("\nno of city for which bus passing by count is to be determined %d \n",nc[i]);
q=nc[i];
printf("city array");
for(k=0;k<q;k++)
{
printf(" %d ",carr[i][k]);
}
printf("\n");
}
no of test case 2
Case #1
no of bus 4
bus route array 10 15 5 12 40 55 1 10
no of city for which bus passing by count is to be determined 2
city array 5 10
Case #2
no of bus 10
bus route array 10 15 5 12 40 55 1 10 25 35 45 50 20 28 27 35 15 40 4 5
no of city for which bus passing by count is to be determined 3
city array 5 10 27
The output for Case #1 bus route should be 15 25 30 35 45 50 10 20 and not 10 15 5 12 40 55 1 10 and for city route it should be 15 25 not 5 10
int *nb=(int *)malloc(ntc*sizeof(int)); // what is ntc?
int barr[ntc][ntc]; // what is ntc?
int *nc=(int *)malloc(ntc*sizeof(int)); // what is ntc?
int carr[ntc][ntc]; // what is ntc?
scanf("%d",&ntc); // input -> test case // oh
C cannot see into the future. It is not possible to allocate an array and determine its size later. You need to read ntc first, then use it.
You also need to enable your compiler warnings and make sure all your programs build warning-free. This error can be easily caught by the compiler.
As a side note, automatic variable-length arrays in C are dangerous since they can easily cause your program to overstep its stack size limit. Avoid them. Allocate all arrays of unknown size dynamically.
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);
....
I have a data file in the format <0:00> - <19321> , <1:00> - <19324>, up to <24:00> - <19648>, so for every hour there is the total power used so far(the total is incremented), I am supposed to calculate the power used, find the average, and the highest usage of power and its index(time), (I don't need help with finding the max power used at its time index). I traced the problem down to line 31, but I don't understand why what I did was wrong. Can someone explain to me why the code in line 31 isn't saving the value of power used into the array? And how I can fix it? Thanks in advance!
float compute_usage(int num, int vals[], int use[], int *hi_idx)
15 {
16 int i;// i is a general counter for all for loops
17 int r1, r2, u, v, pow_dif, temp;//for loop 1
18 int tot;//for loop 2
19 int max_use, init, fina, diff;//for loop 3 //don't have to worry about this for loop, I am good here
20 float avg;//average power used
21
22 for(r1=r2=i=u=v=0;i<num;i++)//for loop 1
23 {
24 r1= vals[v++];//I set values of every hour as reading 1 & 2(later)
25 #ifdef DEBUG
26 printf("pre-debug: use is %d\n", use[u]);
27 #endif
28 if(r1!=0 && r2!=0)
29 {
30 pow_dif = (r1 - r2);//I take the to readings, and calculate the difference, that difference is the power used in the interval between a time period
31 use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
32 }
33 r2=r1;//the first reading becomes the second after the if statement, this way I always have 2 readings to calculate the power used int the interval
34 #ifdef DEBUG
35 printf("for1-debug3: pow_dif is %d\n", pow_dif);
36 printf("for1-debug4: (%d,%d) \n", u, use[u]);
37 #endif
38
39 }
40 for(tot=i=u=0;i<num;i++)//for loop 2
41 {tot = tot + use[u++];}
42
43 avg = tot/(num-1);
44 #ifdef DEBUG
45 printf("for2-debug1: the tot is %d\n", tot);
46 printf("for2-debug2: avg power usage is %f\n", avg);
47 #endif
Just to understand, how did you figure out that the code in line 31 is problematic? Is it the printf statement in line 36?
When you do this:
use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
printf("for1-debug4: (%d,%d) \n", u, use[u]);
The "u" variable in printf statement is incremented in the previous operation (u++), so you are looking past the element you changed.
use[u++] = pow_dif; //I.e. u=0 here, but u=1 after this is executed.
printf("...\n", u=1, use[1]);
What is the "i" for in this loop? Why don't you try "u++" in the for statement instead of "i++" and remove the "u++" in the use assignment expression?
I have to read text in from a file, then prompt for a value and search the file for this number. Once the file is read all the way through, I have to print the initial position and the number of times it appears. Obviously I do not just want the answer, but rather where my program went wrong because I am blind to it as of now.
My source code looks like this:
int count, number, value;
printf("What number are you looking for? ");
scanf("%d",&value);
FILE *fp = fopen("data.in","r");
count = 0;
while (!feof(fp)) {
fscanf(fp,"%d",&number);
if (number == value) {
++count;
}
}
fclose(fp);
printf("The number %d appears first at position %d in the file",value,number);
printf("The number %d appears %d time(s)",value,count);
return 0;
}
The data file I am reading from is:
3 8 33 75 25 10 41 8
10
55 10 1 0 10
10 18
However, when I run the program it returns:
What number are you looking for? 10
The number 10 appears first at position 18 in the file
The number 10 appears 5 time(s)
What number are you looking for? -5
The number -5 appears first at position 18 in the file
The number -5 appears 0 time(s)
Any ideas? Again, I am not looking for the straight answer, rather a way for me to look for these issues both now and in the future.
After coming out from while loop number is always the last number i.e. 18
irrespective of number you are looking for.
The line fscanf(fp,"%d",&number); reads the number of each line and when loop terminates the number is assigned as 18.
Also read : “while( !feof( file ) )” is always wrong ?
Do something like following:
int pos = -1, curr_lno = 0 ; // Keep track of position
while (fscanf(fp,"%d",&number) == 1)
{
++curr_lno ;
if (number == value)
{
pos = ( pos == -1 ) ? curr_lno : pos ;
++count;
}
}
fclose(fp);
if ( count > 0 )
{
printf("The number %d appears first at position %d in the file",value, pos );
}