简体   繁体   中英

Printing out a tower of numbers

I am trying to prepare for an exam, so I thought I'd go to the internet and find some recursion examples. Now the task I found was the following: You should code a printSequence method, where the output should like the following for n=3
1
12
123
12
1

and for n = 5
1
12
123
1234
12345
1234
123
12
1

Now I am pretty new to the idea of recursion, so sorry for asking something for such a simple task. But I cannot get my head around on how to solve this. I managed to print something like this for n=3
123
12
1

but I just can't get a grasp on how to do the upper part.

public static int printSequence(int n){
    if (n >= 1){
        for (int i = 1; i <= n; i++)
            System.out.print(i);          
        System.out.println();
        return printSequence(n-1);  
    }   
    return 0;
}

It might be that my idea is completely wrong, but as I said, I just can't think of another way on how to do this.

There is probably a cleaner way to do this, but simple way is to create another function and pass default parameters there:

  1. You check if your current iteration value i is bigger than n then you quit;
  2. If i == n you just print one string (the pinnacle or your pyramid);
  3. And for other cases you print line before and after all included iterations.

For example:

public static int printRecursive(int n, String line, int i) {
     if (i > n) {
        return 0;
    }
    System.out.println(line);
    if (i == n) {
        return 0;
    }
    printRecursive(n, line + " " + (++i), i);
    System.out.println(line);
    return 0;
 }

 public static int printSequence(int n){
    return printRecursive(n, "1", 1);
 }

This seems to work. Notes:

  • Rather than printSequence itself being recursive, it just accepts the limit (n) and acts as a wrapper to call the recursive method starting at 1.
  • The recursive method accepts the current string as an argument so the code doesn't have to reconstruct the string from 1 every time, it just appends the last digit.
  • Error checking to throw an exception if the (initial) argument is out of range.
public static void main(String[] args) {
    printSequence(5);  // test value
}

private static void printSequence(int n) {
    if (n < 1 || n > 9) {
        throw new IllegalArgumentException("Argument must be in the range 1 to 9 inclusive.");
    }
    doRecursion(1, "", n);  // call recursive method with initial values
}

private static void doRecursion(Integer counter, String currentString, int limit) {
    String newString = currentString + counter.toString();
    System.out.println(newString);
    if (counter < limit) {
        doRecursion(counter + 1, newString, limit);
        System.out.println(newString);
    }
}

This does exactly what you want:

   //This is the method that will be called from some other class
   public static int printSequence(int n){
       return printSequence(1, n);
   }

   /*We define this method, because the following code snippet
    is used multiple times in the method 'printSequence(int, int)'
    This method will simply print the numbers 1 - length*/
   private static void printLooper (int length){
        for(int i=1; i<=length; i++)
            System.out.print(i);
        System.out.print("\n");
    }

    /*This method has the logic. We give it 2 integers as parameters:
     int start and int end. I think the names of the parameters are self-explanatory*/
    private static int printSequence(int start, int end){
        /*This is the TERMINATING condition, so it is placed first.
         This part is really important. Always be aware of what type of recursion
         you are using. More on this later..*/
        if ( end == 1 ) {
            printLooper(end);
            return 0;
        }

        //OK. So, if start is less than end, then print 1 - start
        if (start < end){
            printLooper(start);
            //then return method recursively, with start INCREMENTED by one
            return printSequence(start+1, end);
        }

        /*Now, if start is equal to end, print number 1 - start, but this time,
        return the method recursively with end DECREMENTED by one*/
        else if (start == end){
            printLooper(start);
            return printSequence(start, end-1);
        }

        /*Now if start is larger than end, then that means that we need to start
         printing the lower part of the 'number tree'. So, call printLooper()
         to print 1 - end.*/
        else if (start > end){
            printLooper(end);
            return printSequence(start, end-1);
        }
        return 0;
    }

As for types of recursion and why it is important to know what type of function you are writing, check out this awesome tutorial .

Here's a code that might be of help to you. The code is as follows. It's quite self-explanatory. But I will add a detailed explanation if it seems complicated to you.

public static int printSequence(int n) {
    return printSequence(1, n); //start printing upper triangle (1 to n)
}

public static int printSequence(int currentNumber, int lastNumber){
    for (int i = 1; i <= currentNumber; i++)
        System.out.print(i);          
    System.out.println();

    if(currentNumber<lastNumber) //if in upper triangle
        return printSequence(currentNumber+1, lastNumber);

    if(currentNumber>lastNumber) //if in lower triangle
        return printSequence(currentNumber-1, lastNumber);

    if(currentNumber==lastNumber) { //if the end of a triangle is reached

        if(lastNumber==1) {  //if the end of lower triangle is reached, exit the method
            return 0;
        } else {
            return printSequence(lastNumber-1, 1); //if the end of upper triangle is reached, start the lower triangle ( n-1 to 1)
        }

    }
    return 0;
}

I think this solution might work but it uses 2 functions. Each function has recursion in it:

public static void printSequence(int n){
    printSequenceHelp1(1, n - 1);
    for (int i = 1; i <= n; i++)
        System.out.print(i);          
    System.out.println();
    printSequenceHelp2(n - 1);  
}

public static void printSequenceHelp1(int k, int n){
    if (k <= n){
        for (int i = 1; i <= k; i++)
            System.out.print(i);          
        System.out.println();
        printSequenceHelp1(k + 1, n);
    }   
}

public static void printSequenceHelp2(int n){
    if (n >= 1){
        for (int i = 1; i <= n; i++)
            System.out.print(i);          
        System.out.println();
        printSequenceHelp2(n - 1);  
    }   
}

I am pretty sure there is a more elegant solution with only one function. I'll try to think of it when if I'll find it I'll post it here.

A recursive solution

public static int printSequence(int n,int count){
    if(count == 2*n){
        return 0;
    }
    else{
        if(count<=n){
            int i=1;
            while(i<=count)
            {
                System.out.print(i);
                i++;
            }
            System.out.println();
            return printSequence(n,count+1);
        }
        else{
            int i=1;
            while(i<=n-(count-n)) 
            {
                System.out.print(i);
                i++;
            }
            System.out.println();
            return printSequence(n,count+1);
        }
    }
}

printSequence(n,1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM