John
John

Reputation: 197

Programmatically center text output in for loop

I'm trying to put out the following pattern of chars:

    x
   xxx
  xxxxx
 xxxxxxx
xxxxxxxxx

And this is what I currently have:

String y = "";
for(int i = 0; i < 10; i++)
{
      y="";
      for(int s = 0; s < i; s++)
      {
         y+= "x";
      }
      System.out.println(y);
}

This outputs

x
xx
xxx
xxxx
xxxxx
xxxxxx
xxxxxxx
xxxxxxxx

Which is an approach. I'm well aware of the fact that the target pattern increments two x each execution of the loop, and I know that I have to use blank spaces and insert them. However, I'm stuck with this really simple task.

EDIT: The task is to only use two loops. I thought of a way using three, though, but couldn't straight forwardly figure out a way to use two loops.

Upvotes: 2

Views: 1215

Answers (7)

Youcef LAIDANI
Youcef LAIDANI

Reputation: 60036

You can solve your problem, with just one loop, you can use padLeft with String.format, here is a simple example :

public static void main(String args[]) {
    int n = 5;
    String str;
    for (int i = n; i > 0; i--) {
        str = String.format("%0" + ((n - i) * 2 + 1) + "d", 0).replace("0", "x");
        System.out.println(String.format("%1$" + ((i - 1 + str.length())) + "s", str));
    }
}

Output

    x
   xxx
  xxxxx
 xxxxxxx
xxxxxxxxx

Upvotes: 1

Yahya
Yahya

Reputation: 14092

You may want to have a look at this:

public class CenterText {
    public static void main(String[] args){
        centerText(10, 'X');
    }

    public static void centerText(int noOfLines, char theChar){

        final int totalNoOfChars = noOfLines * 2;
        String totalSpaces = "";
        String chars = "";

        for (int i=0; i<totalNoOfChars; i++){
            totalSpaces += " ";
        }

        for (int j=1 ; j<=totalNoOfChars; j++){
            chars+=theChar;
            if(j%2==0){
                System.out.println(totalSpaces.substring(0, noOfLines-(j/2)) + chars);
            }       
        }   
  }


}

Examples:

Input:

centerText(10, 'X');

Output:

         XX
        XXXX
       XXXXXX
      XXXXXXXX
     XXXXXXXXXX
    XXXXXXXXXXXX
   XXXXXXXXXXXXXX
  XXXXXXXXXXXXXXXX
 XXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXX

Input:

centerText(7, '#');

Output:

      ##
     ####
    ######
   ########
  ##########
 ############
##############

Upvotes: 0

jrook
jrook

Reputation: 3519

Just for fun, let's have a no-loops-at-all solution too:

static Stack<String> getStarryStrings (String lastString, Stack<String> result) {
    //First count the number of *'s in the string
    //From:http://stackoverflow.com/questions/275944/java-how-do-i-count-the-number-of-occurrences-of-a-char-in-a-string
    int starCount = lastString.length() - lastString.replace("*", "").length();
    if(starCount<1) return result;
    result.push(lastString);

    //Find first and last occurrences of *
    int fio = lastString.indexOf('*');
    int lio = lastString.lastIndexOf('*');

    //And replace them with white spaces
    StringBuilder nextLast = new StringBuilder(lastString);
    nextLast.replace(fio,fio+1," ");
    nextLast.replace(lio, lio + 1, " ");

    //And recurse...
    return getStarryStrings(nextLast.toString(),result);
}


public static void main(String[] args) {
    Stack<String> res = getStarryStrings("*********",new Stack<>());
    while(!res.isEmpty()) {
        System.out.println(res.pop());
    }

Displays:

    *    
   ***   
  *****  
 ******* 
*********

Note: I am certain this can be done in a more efficient way to eliminate the need for a java.util.Stack. My only criteria was not using loops. I am letting the stack to remain there to show the recursive nature of the solution. It can easily be improved to use a StringBuilder in place of a stack.

Upvotes: 1

user7627726
user7627726

Reputation:

Rather than using two for loops, I used 1 for loop and 1 if statement (which is not a loop).

    String spaces = "     ";
    String word = "";
    String X = "x";
    for(int i = 10; i > 0; i--) {
        if (i%2 == 0) {
         word = spaces + X;  
         System.out.println(word);
         spaces = spaces.replaceFirst(" ","");
         X += "xx";
        }
    }

and the output is how you asked:

     x
    xxx
   xxxxx
  xxxxxxx
 xxxxxxxxx

Upvotes: 2

Ishan Dave
Ishan Dave

Reputation: 121

Two Loops.

char[] s = "           ".toCharArray();
int start = 5;
int end = 5;
for (int i = 0; i < 5; i++) {
    for (int j = start; j <= end; j++) {
        s[j] = 'x';

    }       
    start--;
    end++;
    System.out.println(s);
}

One loop

char[] s = "           ".toCharArray();
int start = 4;
int end = 5;
for (int i = 0; i < 5; i++) {
    Arrays.fill(s, start, end, 'x');//Remembering importing Arrays class
    start--;
    end++;
    System.out.println(s);
}

Upvotes: 0

Rajeev Singh
Rajeev Singh

Reputation: 3332

Maintain two pointer l & r which will decide from which position to which you have to print * otherwise print space. After each line decrease the l and increase r by 1, as triangle grows 1 step to left and right in each line.

Using only two loops...

int n = 5; // number of lines...
int l = n-1, r = n-1;
for(int i = 0; i < n; i++) {
    for(int s = 0; s < 2*n; s++) {
        if(s >= l && s<= r)
            System.out.print("*");
        else
            System.out.print(" ");
    }
    System.out.println();
    l--; r++;
}

Output:

    *
   ***
  *****
 *******
*********

Upvotes: 0

user1667096
user1667096

Reputation:

As there are many different possible answers to this question, this is just one possible solution.

For this solution, I don't bother printing the spaces after the X's. I only print those that come before.

int baseWidth = 10;


for (int a = baseWidth ; a > 0 ; a--) {
  for (int b = 0 ; b < a - 1 ; b++) {
    System.out.print(" ");
  }

  for (int b = a - 1 ; b < baseWidth - (a - 1) ; b++) {
    System.out.print("X");
  }

  System.out.print("\n");
}

The result of the above code is as follows for baseWidth = 10:

    XX
   XXXX
  XXXXXX
 XXXXXXXX
XXXXXXXXXX

The result of the above code is as follows for baseWidth = 9:

    X
   XXX
  XXXXX
 XXXXXXX
XXXXXXXXX

Following the edit of your post, this next code snip performs the same function as the previous one, but with only two loops.

int baseWidth = 9;


for (int a = baseWidth ; a > 0 ; a--) {
  for (int b = 0 ; b < baseWidth - (a - 1) ; b++) {
    if (b < a - 1) {
      System.out.print(" ");
    }

    if (b >= a - 1 && b < baseWidth - (a - 1)) {
        System.out.print("X");
    }
  }

  System.out.print("\n");
}

Upvotes: 1

Related Questions