Ken Buliw
Ken Buliw

Reputation: 97

Using recursion to print strings in C

Let me start with saying I am not looking for someone to do this for me. I am hoping for a hint or suggestion.

I know there is a smarter way to do this. Code is posted below. I am trying to print an outline. My code works up to a depth of 3. (The depth is the number of subsections - so 3 would be section 1, section 1.A, and section 1.A.1). It also works for a width (number of sections and each type of subsection) of 26, where it is capped. However, to get a larger depth, it would involve many more loops. Not only is that terrible code, it also freezes up the terminal I'm working on. I believe recursion would make it much nicer, but I'm struggling to grasp the idea when using a string (I understand when it is a number).Thanks!

#include <stdio.h>

int sec(int width, int snum) {

    char section[100];
    sprintf(section, "Section ");
    printf("%s %i", section, snum);
    return 0;
}

int ssec_num(int width, int i) {
    char num[100];
    sprintf(num, "%i", i);
    printf(".%s", num);
}

int ssec_let(int width, char z) {
    char let[100];
    sprintf(let, ".%c", z);
    printf("%s", let);
}


int main(int argc, char* argv[]) {
    int depth = atoi(argv[1]);
    int width = atoi(argv[2]);
    int sec_int=1;
    int sec_wid = width;
    int let_wid;
    int num_int;
    int num_dep;
    int num_wid;
    int dep;
    char z = 'A';

    while(sec_wid > 0) {
        sec(width, sec_int);
        let_wid = width;
        dep = depth-1;
        printf("\n");
        while(dep > 0) {
            while(let_wid > 0) {
                num_wid = width;
                num_int = 1;
                sec(width, sec_int);
                ssec_let(let_wid, z);
                printf("\n");
                num_dep = depth-2;
                    while(num_dep > 0) {
                        while(num_wid > 0) {
                            sec(width, sec_int);
                            ssec_let(let_wid, z);
                            ssec_num(width, num_int);
                            num_wid--;
                            num_int++;
                            printf("\n");
                            num_dep--;
                        }
                    }
                let_wid --;
                z++;
            }
            dep --; 
        }
    sec_int++;
    sec_wid--;
    z = 'A';
    } 
 }

If depth is 3 and width is 2 then it would be

Section 1
 Section 1.A
  Section 1.A.1
  Section 1.A.2
 Section 1.B
  Section 1.B.1
  Section 1.B.2
Section 2
 Section 2.A
  Section 2.A.1
  Section 2.A.2
 Section 2.B
  Section 2.B.1
  Section 2.B.2

Upvotes: 1

Views: 2007

Answers (1)

ericbn
ericbn

Reputation: 10998

The algorithm you described uses a width to declare how many times each (sub)section is repeated. This kind of repetition you can achieve with a loop.

The algorithm also uses a depth to determine how many (sub)sections you have. Here is the tricky part, and you can use recursion to solve it. A recursive function is basically a function that calls itself a limited number of times. There must always be a condition to stop the recursion, otherwise the function would call itself until the call stack overflows, abnormally stopping the program execution.

For your problem, you can have a function that receives a counter, that determines at with (sub)section depth it currently is. It would loop width times (as described above) and call itself depth times, until the counter reaches the value of depth. This way, you'll have a function that has a depth number of (sub)sections, each with a width number of items.

As you need to print the (sub)sections at the previous depths, you can use a buffer to store the section values at each depth, like int buffer[MAX_DEPTH];, with #define MAX_DEPTH 100 to set the maximum depth your program supports.

Then you'll have something like

#include <stdio.h>

#define MAX_DEPTH 100

void print_section(const int *const buffer, const int current_depth) { 
    // print all the (sub)section values stored at the buffer so far
    // use a loop like for (i = 0; i <= current_depth; i++)
}

void recursive(int *const buffer, const int current_depth, 
        const int depth, const int width) {
    if (current_depth < depth) {
        // continue recursion
        int current_width;
        for (current_width = 1; current_width <= width; current_width++) {
            buffer[current_depth] = current_width;
            print_section(buffer, current_depth);
            recursive(buffer, current_depth + 1, depth, width);
        }
    }
    // else stop recursion
}

int main(int argc, char* argv[]) {
    // ...
    int buffer[MAX_DEPTH];
    recursive(buffer, 0, depth, width);
    return 0;
}

You'll also need some extra logic to determine when to print a letter or a number at each (sub)section depth.

EDIT: To print the (sub)section title just use the following

void print_section(const int *const buffer, const int current_depth) { 
    int i;
    printf("Section ");
    for (i = 0; i <= current_depth; i++) {
        printf(i == 0 ? "%i" : ".%i", buffer[i]);
    }
    printf("\n");
}

Upvotes: 2

Related Questions