0

I'm taking online classes, which makes it harder to get help, which is why I'm here. This week's lecture is on nested-loops. They are confusing the heck out of me. I am currently stuck on this problem.

Given numRows and numColumns, print a list of all seats in a theater. Rows are numbered, columns lettered, as in 1A or 3E. Print a space after each seat, including after the last. Use separate print statements to print the row and column. Ex: numRows = 2 and numColumns = 3 prints:

1A 1B 1C 2A 2B 2C >

I have tried many possible solutions which have yield many wrong results. This is my current solution

    int numRows;
      int numColumns;
      int currentRow;
      int currentColumn;
      char currentColumnLetter;

      numRows = scnr.nextInt();
      numColumns = scnr.nextInt();

      currentColumnLetter = 'A'; 

         for (currentRow = 1; currentRow <= numRows; currentRow++)
         {

             for (currentColumn = 1; currentColumn < numColumns; currentColumn++)

             {
               System.out.print(currentRow);
               System.out.print(currentColumnLetter + " "); 

             }

              if( currentColumn == numColumns)
               {
                  currentColumnLetter++;
               }
         }

The code yields this result

1A 1A 2B 2B 

The desired result is

1A 1B 2A 2B

I've been going at it for two days and its making me seriously frustrated. Thanks in advance for any help.

4
  • I recommend declaring local variables where you actually need them as well, there is not actually a reason for you to declare currentRow and currentColumn outside of the for declaration, it just clutters the code more. And things like currentColumnLetter you can just do char currentColumnLetter = 'A'; where you are going to use it rather than declare the variable earlier and set it later. (Or int numRows = scnr.nextInt()) Commented Oct 11, 2019 at 19:40
  • Some of the code is provided to me by the instructor. My task is to create the for loop. The details to which you point were given to me as is. Commented Oct 11, 2019 at 19:46
  • Ah, that makes sense then since I guess he wanted to choose the names you use to give some hints on how to do it. Commented Oct 11, 2019 at 19:51
  • The darn loop over char examples, I consider them nasty and unfit from an instruction point of view if it is about loops. See the long answer below. Commented Oct 11, 2019 at 20:34

3 Answers 3

1

You're pretty close.

However, you're not handling the column name correctly. As each row starts, you need to go back to A, and increment by one with each column:

for (currentRow = 1; currentRow <= numRows; currentRow++) {
    currentColumnLetter = 'A'; //Starting a new row, reset the column to `A`
    for (currentColumn = 1; currentColumn < numColumns; currentColumn++){
        System.out.print(currentRow); 
        System.out.print(currentColumnLetter + " ");
        currentColumnLetter++;
    }
}

It's also pretty weird to be using 1-based indexing. Indexing in Java (as well as many other languages) should be started at 0. Your column loop doesn't perform enough iterations as a result - if you set numColumns to 2, you'll only print a single column.

It would be more idiomatic to write the loops like this:

for (currentRow = 0; currentRow < numRows; currentRow++) {
    currentColumnLetter = 'A';
    for (currentColumn = 0; currentColumn < numColumns; currentColumn++) {
        System.out.print(currentRow + 1);
        System.out.print(currentColumnLetter + " ");
        currentColumnLetter++;
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

Also, he is using a 1-based index for currentColumn and using < instead of <= for his column for-loop condition.
1

Yo, the thing is deeper than one might think. I always found these loop over character examples nasty, i got it at my last job interview. So here we go:

If the exercise would be this way: rows got from 1..n, columns for 1..n, output should be "1/1, 1/2...3/1, 3/2...", it would be straight forward, wouldn't it?

public void seatnumbersNumbersOnly() {
        int numRows = 3;
        int numColumns = 3;

        for (int currentRow = 1; currentRow <= numRows; currentRow++) {
            for (int currentColumn = 1; currentColumn < numColumns; currentColumn++) {
                System.out.print(currentColumn + "/" + currentRow + " ");
            }
        }
    }

But the task is different, they want letters for the columns. Let's brute force it on the same basis.

public void seatnumbersNumbersMappedAgain() {
String[] seatLetters = new String []{"A", "B", "C"}; // so many letters as there are columns. Note: array index is 0-based
int numRows = 3;
int numColumns = 3;

for (int currentRow = 1; currentRow <= numRows; currentRow++) {
    for (int currentColumn = 1; currentColumn < numColumns; currentColumn++) {
        // seatLetters[i] is a string "s", not a char 'c', so everything's fine
        System.out.print(seatLetters[currentColumn - 1] + currentRow + " "); // -1: seatLetters indexing is zero based
    }
}

}

But then: in Java char and byte are interchangeable as long as you're in the ascii-range, you can assign a char literal to a byte and the other way round.

@Test
public void charByteEquivalence() {
    // check out http://www.asciitable.com/
    char ca = 'A';
    byte ba = 0x41;
    assertEquals(ca, ba);

    ca = 0x41;
    ba = 'A';
    assertEquals(ca, ba);
}

This means, you also can use the char variable directly for looping. But watch out, building the output string becomes messy, since you have to watch what gets "+"ed with what. You want String/char values for columns and numbers for rows. A "string" + char/byte/int ... becomes a string. char + int becomes and int? a byte? a char? Just certainly not a String. Disclosure: I trial-and-errored the string concatenation, and it becomes an int. Some examples for implicit type conversions are here, the official reference is here.

    public void seatnumbersChar() {
    int numRows = 3;
    int numColumns = 3;

    char firstColumnLetter = 'A';
    for (int currentRow = 1; currentRow <= numRows; currentRow++) {
        for (char currentColumn = firstColumnLetter; currentColumn < firstColumnLetter + numColumns; currentColumn++) {
            // at this point you have to watch out currentColumn + currentRow + " " will get evaluated left to right

            // currentRow is an int
            // currentColumn becomes an int when "+"ed with currentRow 
            // so currentRow + currentColumn would add two numbers instead of concatenating 2 strings, therefore
            // an explicit conversion to string is needed for one of the arguments
            System.out.print(currentColumn + String.valueOf(currentRow) + " ");
        }
    }
}

The same example going the byte route, similar mess with string concatenation, but not quite the same.

public void seatnumbersByte() {
    int numRows = 3;
    int numColumns = 3;

    byte firstColumnLetter = 'A';
    for (int currentRow = 1; currentRow <= numRows; currentRow++) {
        for (byte currentColumn = firstColumnLetter; currentColumn < firstColumnLetter + numColumns; currentColumn++) {
            // same case other trick: (currentRow + " ") forces the result to be a string due to the + " "
            // currentColumn here is declared as byte, when concatenated to a string the numeric representation would be taken (wtf...?)
            // therefore a cast to char is needed "(char) currentColumn"
            // what's left now ? (currentRow + " ") is a string
            // "(char) currentColumn" is a char
            // a char "+" a string is a string
            System.out.print((char) currentColumn + (currentRow + " "));
        }
    }
}

Hope I got my revenge on that last interview. Have gotten the job anyway ;)

Comments

0

You need to increment the currentColumnLetter inside the inner loop. Remember for each row, you need to traverse each column. That's the reason you are nesting loops, right?

Try this:

for (currentRow = 1; currentRow <= numRows; currentRow++) {
    currentColumnLetter = 'A';
    for (currentColumn = 1; currentColumn <= numColumns; currentColumn++) {
        System.out.print(currentRow);
        System.out.print(currentColumnLetter + " "); 
        currentColumnLetter++ 
    }
}

You do not need this condition in the outer loop:

if( currentColumn == numColumns)
{
    currentColumnLetter++;
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.