Apologies in advance, I am very new to c and programming.
I'm currently working on understanding how recursive functions work and have a major mental block.
I was provided an example of a recursive function that creates a "pyramid" of sorts out of hash symbols (see below). I can't understand why the output is not flipped horizontally, with n hashes on top and 1 hash on bottom.
In trying to make sense of it, I created a table with the number of loops, n value, n - 1 value, and how man hashes I think it should print.
On loop 1, n starts out as 4 and the "for loop" should run 4 times since "i" goes through during 0, 1, 2, and 3.
Line break
On loop 2, n is now 3 and the "for loop" should run 3 times since "i" goes through during 0, 1, and 2.
And so on and so forth...
I created nested for loops that I thought would provide the same result: n (height) is 4 originally and works down to 0, i works upwards from 0 printing hashes but the result is the exact opposite.
#include <cs50.h>
#include <stdio.h>
void draw(int n);
int main(void)
{
// prompt user for height of pyramid
int height = get_int("Height ");
// call recursive 'draw' function
draw(height);
printf("\n");
// my nested loop function I made that I can't tell how is different from the recursive function
for (int n = height; n >= 0; n--)
{
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
}
// recursive function example I was given that I cannot make sense of
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
Result below. Their result on top. Mine below it.
If someone could please help clarify what I'm missing I would greatly appreciate it.
Look to see when this recursion will emit its first out put
void draw(int n)
{
if (n <= 0)
{
return;
}
draw(n - 1);
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
see that it keeps calling itself before the printf, it only stops doing that one n reaches 0, then it starts returning and calling the prints, but in reverse order of n.
ie it goes
draw(4)->draw(3)->draw(2)->draw(1)->draw(0)
printf loop *1
printf loop * 2
printf loop * 3
printf loop * 4
You have called the draw(n-1); before the for loop. Therefore the function recursively called like this.
First Draw(4); function calls from main function. Then calls Draw(4-1); -> Draw(3); Then again Draw(3-1); -> Draw(2); it doesn’t go to the line which has for loop until base condition. So, next again calls Draw(2-1); -> Draw(1);
After that Draw(1-1); -> Draw(0); since n=0 function will return.
Next go backwards now. Because you haven’t completed the Draw(n) function. You only did recursively calling it self. After finishing that you have printing part. Since you are now in Draw(1), you starts printing from 1. You came to Draw(1) from Draw(4). So now you have to go again back to Draw(4) from Draw(1). That’s why we go backwards.
Path explanation:
Now you are in Draw(1); so it prints #. Then finishes Draw(1); next Draw(2); so it prints ##. next Draw(3); so it prints ###.
next Draw(4); so it prints #### .
That’s how the recursion function works. Therefore the output is,
#
##
###
####
In your nested loop it starts from 4. Because you have used n=height. So your code should start from n=1 like below code.
for (int n = 1; n <= height ; n++)
{
for (int i = 0; i < n; i++)
{
printf("#");
}
printf("\n");
}
Related
I have an assignment from my uni where I have to print a triangle using recursion in C language. I have tried writing my code as follows but I am not able to find my mistake. Kindly can anyone point out where I have to edit.
int tri(int x, int org);
int dreick(int x) {
return tri(x,x);
}
int tri(int x,int org) {
if (x == 0) {
return 0;
}
else {
return (x - 1, org);
}
for (int i = 0; i < (org - x); i++) {
printf("");
}
for (int j = 0; j <= x; j++) {
printf("*");
}printf("\n");
}
int main() {
int a = dreick(5);
printf("%d",a);
}
Recursion works as follows: each step receives a parameter which specifies what work still needs to be done; if no work needs to be done, then it returns without doing anything; otherwise, it does one step of the work, and then invokes itself with a new value for the parameter which specifies the remaining work to be done.
In your case, the parameter specifying what work still needs to be done can be the row number.
Your triangle-printing code can print the top (single star at row 0) and the bottom (row of stars at row N) outside of recursion, so as to keep things simple. Use recursion to print each line of text from 1 to N-1.
On each step of the recursion you print a number of spaces, an asterisk, some more spaces, and then another asterisk. The number of spaces depends on the row number. (How deep down the triangle you are.) You are done when you reach N-1.
I've been stumped on this for hours. My code properly prompts for height but afterwards it does nothing. I've checked everything multiple times and Googled hard. Any help would be appreciated.
#include <cs50.h>
#include <stdio.h>
void build(int n);
int main(void)
{
int height;
// Get Height 1-8 or ask again
do
{
height = get_int ("Height: ");
}
while (height < 1 || height > 8);
}
void build(int n)
{
for (int i = 1; i < (n + 1); i++)
{
for (int j = 1; j < (n + 1); j++)
{
if (j <= (n - i))
{
printf(" ");
}
else
{
printf("#");
}
}
printf("\n");
}
}
Your build is a separate function from main. This should be obvious. And this means that whatever's in build does not get invoked.
Call build function after the do-while loop by adding this line: build(height);.
When your program runs, it's the main() function that gets executed. And all that function does is prompt the user to input a number and keep doing these prompts until a number between 1 and 8 is inputted. As soon as that happens, your program ends, and the build() function you wrote never gets called. What you need to do is call it once you have height with build(height).
Alternatively, you can, of course, integrate the code from build() into main() rather than having separate functions. It makes sense in your case since that code only gets executed once; functions are more useful when the same pieces of code are supposed to be executed several times from within main().
Here is a copy of my code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int height = get_int("Please enter a height between 1 and 8 (inclusive)\nHeight: ");
if(0 < height && height < 9)
for(int i = 0; i <= height; i++)
{
for(int s = (height - 1); s >= 1; s--)
{
printf("a");
}
for(int h = 1; h <= i; h++)
{
printf("#");
}
printf("\n");
}
else
printf("Please try again.\n"),
main();
}
The part I cannot seem to get right is printing the correct number of spaces as it does not seem to reduce the variable "s" after each loop. (I have replaced the spaces with the letter "a" so I can see where the code has gone wrong.)
The aim of the code is to print a pyramid of #'s that is right-aligned.
Where have I gone wrong here?
So for example, if the user inputs a height of 3, the output will be:
aa
aa#
aa##
aa###
however, I would like the output to be:
aa#
a##
###
The main issue is the 2nd for loop in your code when you print "a". Everytime you hit in this particular loop, you basically print (height - 1) times "a". In fact, you should print every time one less "a" (and one more hashes). To achieve this, we need to tweak condition of s.
Instead of this
int s = height - 1; s >= 1
Use this
int s = height - i; s > 1
Since your main loop has iterator i, we can use it here.
Second issue is that according to CS50 problem set description, you should actually print " " (spaces), not "a". For this, you should replace "a" with " ".
Third issue is your code prints an extra line with full of space in the begining. You need to tweak the main for loop with this condition to remove one extra line.
i < height
And in the for loop where you print # symbol, you need to start iterator h from zero, so that it prints right away with the first line.
int h = 0
The better solution is to use the built-in functionality of printf that is already in place, reducing the problem to a single, simple loop.
#include <stdio.h>
int main(void) {
int height = get_int("Please enter a height between 1 and 8 (inclusive)\nHeight: ");
unsigned char blocks[height];
memset(blocks, '#', height);
for(int i=0; i<height; ++i)
{
printf("%*.*s\n", height, i+1, blocks);
}
return 0;
}
Output
Success #stdin #stdout 0s 4212KB
#
##
###
####
#####
I apologize in advance for the length of the code and how tedious it may be to follow. I am trying to break a number down into individual digits and get the factorial of each one. I have successfully done that (with the help of paxdiablo) but I want to do this all the way from 99999 to 0. In order to do that I have placed all of the code in a loop starting indx at 99999 and decreasing value until it reaches 1. The reason I am trying to do this is because I need to compare the sum of the factorial of each individual digit to the number and if they are equal then I have a match. The program runs and the first run for the number 99999 works perfectly fine but the next loop SHOULD be 99998 and do the exact same thing but instead the next number is 4. I have no idea why it would do this. Any help would be appreciated.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
int indx;
int fact = 1;
int individualDigit[50];
int length;
for(indx = 99999; indx > 0; indx--)
{
num = indx;
for (length = 0; num > 0; length++, num /= 10)
{
individualDigit[length] = num % 10;
}
printf ("Digit count = %d, digits =", length);
for (indx = length - 1; indx >= 0; indx--)
{
printf (" %d", individualDigit[indx]);
}
for (indx = 0; indx < length; indx++)
{
while (individualDigit[indx] > 0)
{
fact = fact * individualDigit[indx];
individualDigit[indx]--;
}
printf("\n%d ", fact);
fact = 1;
}
printf("\n");
}
return 0;
}
The value in "indx" is being used by multiple for loops. The line
for (indx = 0; indx < length; indx++)
increments indx back up to 4, which is the value used by your outer loop. Just use some new variables to count the different loops
This seems like a homework question and your code quality seems to confirm that so I'm hesitant to write you actual code but I'll give you a few pointers.
As #Cody Braun said above your index variable is getting overwritten in line 23 where you calculate the factorial.
There is a much more efficient way to calculate factorials using dynamic programming
I don't know if you just didn't want to do it in the post but learning how to properly format your code will help you catch these errors quicker and keep yourself form making them. As well as make it easier for others to read your code.
Cheers
I am participating in Harvard's opencourse ware and attempting the homework questions. I wrote (or tried to) write a program in C to sort an array using bubble sort implementation. After I finished it, I tested it with an array of size 5, then 6 then 3 etc. All worked. then, I tried to test it with an array of size 11, and then that's when it started bugging out. The program was written to stop getting numbers for the array after it hits the array size entered by the user. But, when I tested it with array size 11 it would continuously try to get more values from the user, past the size declared. It did that to me consistently for a couple days, then the third day I tried to initialize the array size variable to 0, then all of a sudden it would continue to have the same issues with an array size of 4 or more. I un-did the initialization and it continues to do the same thing for an array size of over 4. I cant figure out why the program would work for some array sizes and not others. I used main to get the array size and values from the keyboard, then I passed it to a function I wrote called sort. Note that this is not homework or anything I need to get credit, It is solely for learning. Any comments will be very much appreciated. Thanks.
/****************************************************************************
* helpers.c
*
* Computer Science 50
* Problem Set 3
*
* Helper functions for Problem Set 3.
***************************************************************************/
#include <cs50.h>
#include <stdio.h>
#include "helpers.h"
void
sort(int values[], int n);
int main(){
printf("Please enter the size of the array \n");
int num = GetInt();
int mystack[num];
for (int z=0; z < num; z++){
mystack[z] = GetInt();
}
sort(mystack, num);
}
/*
* Sorts array of n values.
*/
void
sort(int values[], int n)
{
// this is a bubble sort implementation
bool swapped = false; // initialize variable to check if swap was made
for (int i=0; i < (n-1);){ // loops through all array values
if (values[i + 1] > values [i]){ // checks the neighbor to see if it's bigger
i++; // if bigger do nothing except to move to the next value in the array
}
else{ // if neighbor is not bigger then out of order and needs sorting
int temp = values[i]; // store current array value in temp variable for swapping purposes
values[i] = values[i+1]; //swap with neighbor
values[i+1] = temp; // swap neighbor to current array value
swapped = true; // keep track that swap was made
i++;
}
// if we are at the end of array and swap was made then go back to beginning
// and start process again.
if((i == (n-1) && (swapped == true))){
i = 0;
swapped = false;
}
// if we are at the end and swap was not made then array must be in order so print it
if((i == (n-1) && (swapped == false))){
for (int y =0; y < n; y++){
printf("%d", values[y]);
}
// exit program
break;
}
} // end for
// return;
}
You can easily use 2 nested for loops :
int i, j, temp ;
for ( i = 0 ; i < n - 1 ; i++ )
{
for ( j = 0 ; j <= n - 2 - i ; j++ )
{
if ( arr[j] > arr[j + 1] )
{
temp = arr[j] ;
arr[j] = arr[j + 1] ;
arr[j + 1] = temp ;
}
}
}
also you should now it's a c++ code not a c, because c doesn't have something like :
int mystack[num];
and you should enter a number when you're creating an array and you can't use a variable (like "int num" in your code). This is in C, but in C++ you're doing right.
The first thing to do when debugging a problem like this is ensure that the computer is seeing the data you think it should be seeing. You do that by printing out the data as it is entered. You're having trouble with the inputs; print out what the computer is seeing:
static void dump_array(FILE *fp, const char *tag, const int *array, int size)
{
fprintf(fp, "Array %s (%d items)\n", tag, size);
for (int i = 0; i < size; i++)
fprintf(fp, " %d: %d\n", i, array[i]);
}
int main(void)
{
printf("Please enter the size of the array \n");
int num = GetInt();
printf("num = %d\n", num);
int mystack[num];
for (int z = 0; z < num; z++)
{
mystack[z] = GetInt();
printf("%d: %d\n", z, mystack[z]);
}
dump_array(stdout, "Before", mystack, num);
sort(mystack, num);
dump_array(stdout, "After", mystack, num);
}
This will give you direct indications of what is being entered as it is entered, which will probably help you recognize what is going wrong. Printing out inputs is a very basic debugging technique.
Also, stylistically, having a function that should be called sort_array_and_print() suggests that you do not have the correct division of labour; the sort code should sort, and a separate function (like the dump_array() function I showed) should be used for printing an array.
As it turns out the reason why it was doing this is because when comparing an array's neighbor to itself as in:
if (values[i + 1] > values [i])
The fact that I was just checking that it is greater than, without checking if it is '=' then it was causing it to behave undesirably. So if the array is for example [1, 1, 5, 2, 6, 8] then by 1 being next to a 1, my program did not account for this behavior and acted the way it did.