How to mirror text in Java - java

I'm trying to create a full diamond and I have almost all of it down
T T
Te Te
Tes Tes
Test Test
Test Tes
Tes Te
Te T
T
These for loops are what create the diamonds, but the spaces.substring is where I am having difficulties. Would anyone know how to approach this by solely editing the spaces.substring?
for (int i = 0 ; i < len; i++)
{
System.out.print(SPACES.substring(0,i));
System.out.print (word.substring (0,i) + System.lineSeparator());
//System.out.print(SPACES.substring(i,i+1));
System.out.print (word.substring (0,i+1));
}
for (int g = len ; g >= 0; g--)
{
System.out.print(SPACES.substring(0,g));
System.out.print (word.substring (0,g) + System.lineSeparator());
System.out.print (word.substring (0,g));
}
As you can see the first two lines in each for loop create the right half of the diamond, and the last lines creates the left half. But there is no spaces.substring for the left half, because I don't know what I would put in it.
Should look like this:
H
O O
U U
S S
E E
S S
U U
O O
H

Code
Are you allowed to use methods?
Yes:
public static void main(String[] args)
{
new Main().printDiamond("HOUSE");
}
private void printDiamond(String word)
{
for (int i = 0 ; i < word.length(); i++)
{
printPart(word, i);
}
for (int i = word.length() - 2; i >= 0; i--)
{
printPart(word, i);
}
}
private void printPart(String word, int i)
{
space(word.length() - (i + 1));
System.out.print(word.charAt(i));
if (i > 0)
{
space((i * 2) - 1);
System.out.print(word.charAt(i));
}
space(word.length() - (i + 1));
System.out.println();
}
private void space(int i)
{
for (int j = 0; j < i; j++)
{
System.out.print(" ");
}
}
No:
String word = "HOUSE";
String SPACES = " ";
int len = word.length();
for (int i = 0 ; i < len; i++)
{
System.out.print(SPACES.substring(0, len - (i + 1))); //print left padding spaces
System.out.print(word.charAt(i)); //print left/middle character
if (i > 0) //we don't want to do this on run 0 because there we only need to print one character in the middle (H)
{
System.out.print(SPACES.substring(0, (i * 2) - 1)); //print middle padding spaces
System.out.print(word.charAt(i)); //print right character
}
System.out.println(SPACES.substring(0, len - (i + 1))); //optional: print right padding
}
for (int i = len - 2; i >= 0; i--) //start at len - 2. -1 because arrays start at 0 and -1 because we don't want to print the last character (E) again
{
System.out.print(SPACES.substring(0, len - (i + 1)));
System.out.print(word.charAt(i));
if (i > 0)
{
System.out.print(SPACES.substring(0, (i * 2) - 1));
System.out.print(word.charAt(i));
}
System.out.println(SPACES.substring(0, len - (i + 1)));
}
Output
H
O O
U U
S S
E E
S S
U U
O O
H

Related

(Java Number Pyramid) How do I get my numbers to have more spaces between them while lining up accurately when it is an integer is > 9?

I am having difficulty getting the desired output. I know there are problems that are similar to mine that is already posted, but I find it hard to relate my code to their solutions without a massive overhaul.
The solution for my class assignment:
Supposed to continue until every direction of pyramid equals 1
My second method "spaces" is redundant and I am not sure why. Any help would be appreciated.
Blockq
public static void main(String[] args) {
numPar();
spaces();
}
private static void spaces() {
int x = 0;
if(x > 0 && x < 10) {
System.out.print(" ");
} else if (x > 10 && x < 99) {
System.out.print(" ");
} else if (x > 99) {
System.out.print(" ");
}
}
private static void numPar() {
int spaces = 14;
for(int i = 0; i<= 7; i++) {
for(int u = 0; u<spaces; u++) {
System.out.print(" ");
}
spaces--;
spaces--;
for(int j = 0 ; j <i ; j++) {
System.out.print(""+ (int) Math.pow(2,j)+" ");
}
for(int k = i ; k >=0 ; k--) {
System.out.print(""+ (int) Math.pow(2,k)+" ");
}
System.out.println("");
}
}
}
I made every number take 3 places using String.format("%3s", (int) Math.pow(2, j)). You can make it dynamic by replacing the number 3 here with the length of the largest number you'll print. I also changed the number of spaces in your print statements. Here is the full code that prints an evenly spaced pyramid:-
public static void main(String[] args) {
numPar();
spaces();
}
private static void spaces() {
int x = 0;
if (x > 0 && x < 10) {
System.out.print(" ");
} else if (x > 10 && x < 99) {
System.out.print(" ");
} else if (x > 99) {
System.out.print(" ");
}
}
private static void numPar() {
int spaces = 14;
for (int i = 0; i <= 7; i++) {
for (int u = 0; u < spaces; u++) {
System.out.print(" ");
}
spaces--;
spaces--;
for (int j = 0; j < i; j++) {
System.out.print("" + String.format("%3s", (int) Math.pow(2, j)) + " ");
}
for (int k = i; k >= 0; k--) {
System.out.print("" + String.format("%3s", (int) Math.pow(2, k)) + " ");
}
System.out.println("");
}
}
String.format explanation:-
String.format("%3s", str) will print the string str, padding it with spaces, to make the total length 3 if it's less than 3. Note that you can write anything instead of 3 - I used 3 because your biggest number was of length 3.
So "A" will be printed as "_ _ A" (2 spaces), and "Ab" will be printed as "_ Ab" (1 space).
I just replaced str with your Math.pow(2, j).

Word Search Program for loops not working

I have this code that will take a word search and find words in it. I got it to work for some things, i tired BINARY and i tried DRAC and it worked, but for some stuff, especially the diagonals, keep giving me outofbounds errors.
import java.util.Scanner;
public class WordSearch {
public static void main(String[] args) {
Scanner kboard = new Scanner(System.in);
char[][] maze = { {'A','P','B','I','N','A','R','Y','D','C','O','C','A','R','D'},
{'M','T','C','O','S','M','A','L','L','E','A','A','T','E','B'},
{'P','O','E','N','A','M','G','I','S','R','L','N','S','I','R'},
{'R','L','D','H','M','A','S','P','I','N','S','T','E','S','T'},
{'A','E','A','E','T','G','T','A','B','M','U','H','A','S','G'},
{'L','M','G','N','R','E','D','O','O','P','B','E','F','E','H'},
{'U','Y','L','O','E','N','O','K','A','L','L','R','A','M','T'},
{'C','I','E','V','E','T','E','C','U','N','A','C','D','Y','I'},
{'R','C','C','A','E','H','S','E','E','W','N','U','E','T','A'},
{'I','I','I','S','O','N','W','D','D','O','O','L','O','H','N'},
{'C','T','N','L','E','H','S','O','H','R','L','E','U','O','J'},
{'I','A','E','P','I','R','A','M','O','C','I','S','T','L','I'},
{'M','N','R','T','A','E','L','D','E','R','S','P','O','O','L'},
{'E','E','E','E','N','R','E','T','T','A','P','A','T','G','I'},
{'S','V','B','L','A','C','K','H','O','L','E','S','O','Y','N'}, };
for(int i = 0; i <= 14; i++)
{
for(int j = 0; j <= 14; j++)
{
System.out.print(maze[i][j] + " ");
}
System.out.println();
}
String input = kboard.nextLine();
//checking the word search horizontally
for(int r = 0; r <= maze.length - 1; r++)
{
for(int c = 0; c <= (maze.length - input.length()); c++)
{
boolean match = true;
for(int i=0; i<input.length(); i++)
{
if(maze[r][c + i] != input.charAt(i))
{
match = false;
break;
}
}
if(match)
{
System.out.print("Found match (horizontal) for " + input + " starting at (" + r + ", " + c + ")");
}
}
}
//checking the word search backwards horizontally
for(int r = 0; r < maze.length - 1; r++)
{
for(int c = 0; c <= (maze.length + 3 - input.length()); c++)
{
boolean match = true;
for(int i = 0; i < input.length(); i++)
{
if(maze[r][c - i] != input.charAt(i))
{
match = false;
break;
}
}
if(match)
{
System.out.print("Found match (backwards horizontal) for " + input + " starting at (" + r + ", " + c + ")");
}
}
}
//checking the word search diagonally down
for(int r = 0; r < maze.length - 1; r++)
{
for(int c = 0; c <= (maze.length - input.length()); c++)
{
boolean match = true;
for(int i = 0; i < input.length(); i++)
{
if(maze[r + i][c + i] != input.charAt(i))
{
match = false;
break;
}
}
if(match)
{
System.out.print("Found match (diagonal down) for " + input + " starting at (" + r + ", " + c + ")");
}
}
}
//searching the word search diagonally up
for(int r = 0; r < maze.length - 1; r++)
{
for(int c = 0; c <= (maze.length - input.length()); c++)
{
boolean match = true;
for(int i = 0; i < input.length(); i++)
{
if(maze[r - i][c - i] != input.charAt(i))
{
match = false;
break;
}
}
if(match)
{
System.out.print("Found match (diagonal up) for " + input + " starting at (" + r + ", " + c + ")");
}
}
}
}
}
Ive tried numbers and keep getting errors like
Found match (horizontal) for BLACKHOLE starting at (14, 2)
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1 at WordSearch.main(WordSearch.java:112)`
Also, is it bad to use the same for loop each time? Do i only need to change the one line in the third for loop of each one?
This line is causing issues:
if(maze[r - i][c - i] != input.charAt(i))
Because the loop only increments i and c, r remains at 0, so 0 - 1 = -1, hence out of bounds.
Adjusting to:
if(maze[r][c - i] != input.charAt(i))
Stops the out of bounds error, and the loops seem to go through all the columns of each row when searching "BLACK", but doesn't make diagonally searching work well.
You don't ask for different approaches, but you could try going from every point on the grid in all directions, and catching/ignore any outofbounds exceptions, since you know they will be false results, just a thought.

Empty diamond shape with numbers

So I have been asked this question and I could only solve the top part of the code, I am stuck on the bottom part.
Write a Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines as shown below. Sample output where n = 3:
1
2 2
3 3
2 2
1
Here's my code so far:
public static void shape(int n) {
//TOP PART
for (int i = 1; i <= (n - 1); i++) {
System.out.print(" ");
}
System.out.println(1);
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= (n - i); j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= 2 * i - n + 1; j++) {
System.out.print(" ");
}
System.out.println(i);
}
//BOTTOM PART (The messed up part)
for (int i = n + 1; i <= 2 * n - 2; i++) {
for (int j = 1; j <= n - i; j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= n; j++) {
System.out.print(" ");
}
System.out.print(i);
}
for (int i = 1; i <= (n - 1); i++) {
System.out.print(" ");
}
System.out.println(1);
}
public static void main(String[] args) {
shape(4);
}
Maybe a little bit late, but because the bottom part of your message is just the first part mirrored you can use a Stack to print the message in reverse order:
public static void main(String[] args) {
int maxNumber = 3;
Stack<String> message = new Stack<>();
// upper part
for (int row = 0; row < maxNumber; row++) {
int prefix = maxNumber - (row + 1);
int spaces = row >= 2 ? row * 2 - 1 : row;
String line = getLine(row, prefix, spaces);
System.out.println(line);
if (row != maxNumber - 1)
message.add(line);
}
// bottom part
while (!message.isEmpty())
System.out.println(message.pop());
}
public static String getLine(int row, int prefix, int spaces) {
StringBuilder line = new StringBuilder("_".repeat(prefix));
line.append(row + 1);
if (row != 0) {
line.append("_".repeat(spaces));
line.append(row + 1);
}
return line.toString();
}
Output:
__1
_2_2
3___3
_2_2
__1
You can of course use any method you want to fill the stack (i.e. to generate the upper part of your message) like with the method this question suggessted. This upper part I describe contains the first line (inclusive) up to the middle line (exclusive).
Here is the program for printing empty diamond:
int n = 3; //change the value of n to increase the size of diamond
int upperCount = 1;
for (int i = n; i >= 1; i--) {
for (int j = i; j >= 1; j--) {
System.out.print(" ");
}
System.out.print(upperCount);
for (int j = 0; j <= upperCount - 2; j++) {
System.out.print(" ");
}
for (int j = 0; j <= upperCount - 2; j++) {
System.out.print(" ");
}
if (upperCount != 1) {
System.out.print(upperCount);
}
upperCount++;
System.out.print("\n");
}
int lowerCount = n - 1;
for (int i = 1; i <= n - 1; i++) {
for (int j = 0; j <= i; j++) {
System.out.print(" ");
}
System.out.print(lowerCount);
for (int j = 0; j <= lowerCount - 2; j++) {
System.out.print(" ");
}
for (int j = 0; j <= lowerCount - 2; j++) {
System.out.print(" ");
}
if (lowerCount != 1) {
System.out.print(lowerCount);
}
lowerCount--;
System.out.print("\n");
}
Do following changes in the Bottom Part of your code:
int lowerCount = n - 1;
for (int i = n - 1; i >= 2; i--) {
for (int j = 1; j <= (n - i); j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= lowerCount; j++) {
System.out.print(" ");
}
System.out.print(i);
lowerCount -= 2;
}
You can print an empty diamond shape with numbers using two nested for loops over rows and columns from -n to n. The diamond shape is obtained when iAbs + jAbs == n:
int n = 2;
for (int i = -n; i <= n; i++) {
// absolute value of 'i'
int iAbs = Math.abs(i);
for (int j = -n; j <= n; j++) {
// absolute value of 'j'
int jAbs = Math.abs(j);
// empty diamond shape
System.out.print(iAbs + jAbs == n ? jAbs + 1 : " ");
if (j < n) {
System.out.print(" ");
} else {
System.out.println();
}
}
}
Output:
1
2 2
3 3
2 2
1
You can separately define width and height:
int m = 4;
int n = 2;
int max = Math.max(m, n);
for (int i = -m; i <= m; i++) {
// absolute value of 'i'
int iAbs = Math.abs(i);
for (int j = -n; j <= n; j++) {
// absolute value of 'j'
int jAbs = Math.abs(j);
// empty diamond shape
System.out.print(iAbs + jAbs == max ? jAbs + 1 : " ");
if (j < n) {
System.out.print(" ");
} else {
System.out.println();
}
}
}
Output:
1
2 2
3 3
3 3
2 2
1
See also:
• Filling a 2d array with numbers in a rhombus form
• How to print a diamond of random numbers?
java-11
Using String#repeat introduced as part of Java-11, you can do it using a single loop.
public class Main {
public static void main(String[] args) {
int n = 3;
for (int i = 1 - n; i < n; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + (n - x)
+ " ".repeat(Math.abs((n - x) * 2 - 3))
+ ((i == 1 - n || i == n - 1) ? "" : (n - x)));
}
}
}
Output:
1
2 2
3 3
2 2
1
You can print a variant of the diamond simply by increasing the amount of space by one character:
public class Main {
public static void main(String[] args) {
int n = 3;
for (int i = 1 - n; i < n; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + (n - x)
+ " ".repeat(Math.abs((n - x) * 2 - 3))
+ ((i == 1 - n || i == n - 1) ? "" : (n - x)));
}
}
}
Output:
1
2 2
3 3
2 2
1
Alternative solution:
public static void main(String[] args) {
int n = 7;
for (int i = -n; i <= n; i++) {
for (int j = -n; j <= n; j++) {
// edge of the diamond
int edge = Math.abs(i) + Math.abs(j);
// diamond shape with numbers
if (edge == n) System.out.print(n - Math.abs(i) + 1);
// beyond the edge && in chessboard order || vertical borders
else if (edge > n && (i + j) % 2 != 0 || Math.abs(j) == n)
System.out.print("*");
// empty part
else System.out.print(" ");
}
System.out.println();
}
}
Output:
** * * 1 * * **
* * * 2 2 * * *
** * 3 3 * **
* * 4 4 * *
** 5 5 **
* 6 6 *
*7 7*
8 8
*7 7*
* 6 6 *
** 5 5 **
* * 4 4 * *
** * 3 3 * **
* * * 2 2 * * *
** * * 1 * * **
See also: How to print a given diamond pattern in Java?
Solution: Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines.
public class EmptyDiamond {
public static void main(String[] args) {
shape(3); // Change n to increase size of diamond
}
public static void shape(int n) {
int max = 2 * n - 1; // length of the diamond - top to bottom
int loop = 0; // with of each loop. initialized with 0
for (int i = 1; i <= max; i++) {
int val = 0;
if (i <= n) {
loop = n + i - 1;// e.g. when i = 2 and n = 3 loop 4 times
val = i; // value to be printed in each loop ascending
} else {
loop = n + (max - i); //e.g. when i = 4 and n = 3 loop 4 times
val = max - i + 1; // value to be printed in each loop descending
}
for (int j = 1; j <= loop; j++) {
// (value end of loop)
// || (value in the beginning when i <= n)
// || (value in the beginning when i > n)
if (j == loop
|| j == (n - i + 1)
|| j == (n - val + 1)) {
System.out.print(val); // Print values
} else {
System.out.print(" "); // Print space
}
}
System.out.println(); // Print next line
}
}
}
Output when n = 3:
1
2 2
3 3
2 2
1
Stream-only function:
public static void printEmptyDiamond(int n) {
IntStream.range(1, 2*n)
.map(i-> i > n ? 2*n-i : i)
.mapToObj(i -> " ".repeat(n-i) + i + (i>1 ? " ".repeat(2*(i-1)-1)+i : ""))
.forEach(System.out::println);
}
Example output (printEmptyDiamond(7)):
1
2 2
3 3
4 4
5 5
6 6
7 7
6 6
5 5
4 4
3 3
2 2
1
With explainations:
public static void printEmptyDiamond(int n) {
IntStream.range(1, 2*n)
.map(i-> i > n? 2*n-i : i) // numbers from 1 to n ascending, then descending to 1 again
.mapToObj(i -> " ".repeat(n-i) // leading spaces
+ i // leading number
+ (i>1 ? // only when number is > 1
" ".repeat(2*(i-1)-1) // middle spaces
+ i // trailing number
: ""))
.forEach (System.out::println);
}
I did it for fun, here's the code :
import java.util.Scanner;
public class Diamond {
public static void main(String[] args) {
Scanner read = new Scanner(System.in);
int num = read.nextInt();
read.nextLine();
//TOP
for(int i = 1;i<=num;i++) {
//LEFT
for(int k = i; k<num;k++) {
if ( k % 2 == 0 ) {
System.out.print(" ");
}
else {
System.out.print(" ");
}
}
if(i>1) {
for(int j =1;j<=i;j++) {
if (j==1 || j== i) {
for(int u=0;u<j;u++) {
System.out.print(" ");
}
System.out.print(i);
}
else {
System.out.print(" ");
}
}
System.out.println("");
}
else {
System.out.println(" "+i);
}
}
//BOTTOM
for(int i = num-1;i>0;i--) {
for(int k = i; k<num;k++) {
if ( k % 2 == 0 ) {
System.out.print(" ");
}
else {
System.out.print(" ");
}
}
if(i>1) {
for(int j =1;j<=i;j++) {
if (j==1 || j== i) {
for(int u=0;u<j;u++) {
System.out.print(" ");
}
System.out.print(i);
}
else {
System.out.print(" ");
}
}
System.out.println("");
}
else {
System.out.println(" "+i);
}
}
}
}
And the output :
7
1
2 2
3 3
4 4
5 5
6 6
7 7
6 6
5 5
4 4
3 3
2 2
1
Having seen the other answers, there's a whole load of loops I could've skipped. Just decided to wing it at the end and do it as quick as possible.

Missing a logic on table based printing in Java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I recently wrote some code that is supposed to make a string into a box.
If the input is "hello", The output should look like this:
hello
e l
l l
l e
olleh
I have pretty much all of the code and I made it into a box, except I can't seem to make the letters line up. I know the part where I messed up, I just don't know how to fix it. The part that is messed up is in quotations and is commented. Here is the code, Thank you!:
int num = 0;
for (int i=1;i<=word.length();i++){
for (int a=1;a<=word.length();a++){
if(i>1 && i<word.length() && a>1 && a<word.length())
System.out.print(" ");
else
//"System.out.print(word.charAt(num));
}
System.out.println("");
}
You could have your String reversed first, and store it in a char[] array. (As I forgot to use StringBuilder#reverse()).
You can then iterate with 2 for loops as you did, with some conditions for the top, bottom and middle lines as follows:
The trick is using the original string for the top and left part and the reverse one on the right and bottom one.
Also note that you're starting from index 1~word.lenght() and this is not what you want since when printing each character you start from index 0 not 1
public class WordSquare {
public static void main(String[] args) {
String word = "hello";
int num = 0;
char[] reverseWord = new char[word.length()];
int counter = 0;
for (int i = word.length() - 1; i >= 0; i--) {
reverseWord[counter] = word.charAt(i);
counter++;
}
for (int i = 0; i < word.length(); i++) {
counter = 0;
for (int j = 0; j < word.length(); j++) {
if (i == 0) {
System.out.print(word.charAt(j));
} else {
if (j == 0) {
System.out.print(word.charAt(i));
} else if (j < (word.length() - 1)) {
if (i < (word.length() - 1)) {
System.out.print(" ");
} else {
System.out.print(reverseWord[j]);
}
} else {
System.out.print(reverseWord[i]);
}
}
}
System.out.println("");
}
}
}
Which produces:
hello
e l
l l
l e
olleh
I just assumed that you had to do it inside the two for loops so I just added to the loop.
for (int i = 0; i <= word.length() - 1; i++){
for (int a = 0; a <= word.length() - 1; a++){
if(i > 0 && i < word.length() - 1 && a > 0 && a < word.length() - 1) {
System.out.print(" ");
} else if(i == word.length() - 1) {
System.out.print(word.charAt(word.length()-1-a));
} else if(a != word.length() - 1) {
System.out.print(word.charAt((a+i)%word.length()));
} else {
System.out.print(word.charAt((a-i)%word.length()));
}
}
System.out.println("");
}
Here's the same thing in only two else statements
for (int i = 0; i <= word.length() - 1; i++){
for (int a = 0; a <= word.length() - 1; a++){
if(i > 0 && i < word.length() - 1 && a > 0 && a < word.length() - 1) {
System.out.print(" ");
} else if (a == 0 || i == 0) {
System.out.print(word.charAt((a+i)%word.length()));
} else {
System.out.print(word.charAt((2*(word.length()-1)-a-i)%word.length()));
}
}
System.out.println("");
}
String word = "hello";
System.out.println(word);
for (int i = 1; i < word.length() - 1; i++) {
System.out.print(word.charAt(i));
for (int j = 0; j < word.length() - 2; j++) {
System.out.print(" ");
}
System.out.println(word.charAt(word.length()-i-1));
}
System.out.println(new StringBuilder(word).reverse().toString());
Output:
hello
e l
l l
l e
olleh
Try this, More Simpler logic
public class SchoolAssignment
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
String input = "hello";
String middleSpaces = null;
//Determine amount of space in middle rows
StringBuilder middleSpace = new StringBuilder();
middleSpace.append("%");
middleSpace.append(String.valueOf(input.length()-2));
middleSpace.append("s");
middleSpaces = String.format(middleSpace.toString(), " ");
//print first line
System.out.println(input);
//print middle lines
for(int i = 1; i <= input.length() - 2; i++){
StringBuilder middleLine = new StringBuilder();
middleLine.append(input.charAt(i));
middleLine.append(middleSpaces);
middleLine.append(input.charAt(input.length() - 1 - i));
System.out.println(middleLine.toString());
}
//print last line
StringBuilder lastLine = new StringBuilder();
lastLine.append(input);
lastLine=lastLine.reverse();
System.out.println(lastLine);
}
}
Try this
public void print(String word){
System.out.println(word);
for (int i=1;i<word.length()-1;i++){
System.out.print(word.charAt(i));
for (int j=0;j<word.length()-2;j++){
System.out.print(" ");
}
System.out.println(word.charAt(word.length()-i-1));
}
System.out.println(new StringBuilder(word).reverse().toString());
}
Interesting homework question btw

How do I read across an array in a different way than I filled it

In my current program, I am trying to decrypt a string with a very basic cipher. To do this I convert an inputted string into a 2d array of characters, and fill the array downwards. By doing this the actual message can be seen by reading across the rows. My problem is that I can fill the array correctly but have no idea how to read across the rows and output those values to get the un encrypted message.
The relevant code is as follows
char[][] charArray = new char[column][row];
for (int j = 0; j < row; j++) {
for (int i = 0; i < column; i++) {
if (x < input.length()) {
charArray[i][j] = input.charAt(x);
outputArea.append("[" + i + "]" + "[" + j + "]" + charArray[i][j]);
x++;
}
if (x >= input.length()) {
charArray[i][j] = ' ';
outputArea.append("[" + i + "]" + "[" + j + "]" + charArray[i][j]);
x++;
}
}
}
Since I output the same way as I read-in, I just get the string over again.
For example I would like the string PNTSLTMAAEEGIXSE to display PLAINTEXTMESSAGE
The grid would be as such
P L A I
N T E X
T M E S
S A G E
You would want something like this to get the original string back:
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
char c = charArray[j][i];
System.out.print(c);
}
}
Also, you should have the x++; done once; otherwise you will overwrite the last character with a space.
When x = input.length - 1; You x++; then you will go into the next if within the same loop iteration and overwrite the char you just stored.
Have it this way:
for (int i = 0; i < column; i++) {
if (x < input.length()) {
charArray[i][j] = input.charAt(x);
outputArea.append("[" + i + "]" + "[" + j + "]" + charArray[i][j]);
}
if (x >= input.length()) {
charArray[i][j] = ' ';
outputArea.append("[" + i + "]" + "[" + j + "]" + charArray[i][j]);
}
x++; // have it here outside both if statments
}
Here is a complete code fragment:
String str = "PLAINTEXTMESSAGE";
// To get the row and column
double sqrt = Math.sqrt(str.length());
int row = (int)sqrt; // be careful
int column = row + (sqrt % 1d > 0 ? 1 : 0);
// To encrypt
char[][] array = new char[row][column];
for (int i = 0, cursor = 0; i < row * column; i++) {
array[i % row][i / row] = cursor < str.length() ? str.charAt(cursor++) : 0;
}
//// Just a equivalent to above
//for (int i = 0, cursor = 0; i < column; i++) {
// for (int j = 0; j < row; j++) {
// array[j][i] = cursor < str.length() ? str.charAt(cursor++) : 0;
// }
//}
// Print the encrypted array
StringBuilder encrypted = new StringBuilder();
for (int i = 0; i < row * column; i++) {
char c = array[i / column][i % column];
System.out.print(c + ((i + 1) % column == 0 ? "\n" : " "));
encrypted.append(c);
}
System.out.println("The encrypted string: " + encrypted);
// To decrypt
System.out.println();
int decryptRow = array.length;
if (decryptRow < 1) {
throw new RuntimeException("Empty array");
}
StringBuilder decrypted = new StringBuilder();
for (int i = 0; i < row * column; i++) {
char c = array[i % row][i / row];
System.out.print(c + ((i + 1) % row == 0 ? "\n" : " "));
decrypted.append(c);
}
System.out.println("The decrypted string: " + decrypted);
Output:
P N T S
L T M A
A E E G
I X S E
The encrypted string: PNTSLTMAAEEGIXSE
P L A I
N T E X
T M E S
S A G E
The decrypted string: PLAINTEXTMESSAGE
Assuming you know numberOfColumns and numberOfRows the following method will decrypt the message:
public String decrypt(int numberOfRows, int numberOfColumns, String encrypted) {
String decrypted = "";
for(int c = 0; c < numberOfColumns; c++) {
for(int r = 0; r < numberOfRows; r++) {
decrypted += encrypted.charAt(numberOfColumns * (r % numberOfRows) + (c % numberOfColumns));
}
}
return decrypted;
}

Categories

Resources