Word Search Program for loops not working - java

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.

Related

How to mirror text in 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

Java: Do-while loop executing even if condition is false

This is a word search program. The text it searches through is input and turned into a 2D array in another class.
This is the text the program is searching through:
10 //rows
15 //columns
fqexfecmxdvjlgu
cxomfslieyitqtz
nucatfakuxofegk
hfytpnsdlhcorey
pgrhdqsypyscped
ckadhyudtioapje
yerjodxnqzztfmf
hypmmgoronkzhuo
hdskymmpkzokaao
amuewqvtmrlglad
For some reason even if my terminating string end is typed in, it always goes into my checkDown() method and creates an out of bounds error. If I comment out that method and just execute the checkRight() and checkDiagonal() methods, everything seems to work fine.
This is my code:
import java.util.Scanner;
public class WordSearch
{
private char[][] array;
private String targetWord;
private int rowLocation;
private int colLocation;
public WordSearch(char[][] inArray)
{
array = inArray;
}
public void play()
{
do{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
System.out.print(array[row][col]);
}
System.out.println();
}
System.out.println();
Scanner input = new Scanner(System.in);
System.out.println("What word would you like to search for? Type end to quit: ");
targetWord = input.nextLine();
System.out.println("Typed in: " + targetWord);
System.out.println();
compareFirst(targetWord);
} while (!targetWord.equals("end"));
}
public void compareFirst(String inWord)
{
for (int row = 0; row < array.length; row++)
{
for (int col = 0; col < array[row].length; col++)
{
if(array[row][col] == inWord.charAt(0))
{
rowLocation = row;
colLocation = col;
suspectAnalysis();
}
}
}
}
public void suspectAnalysis()
{
checkRight();
checkDown();
checkDiagonal();
}
public void checkRight()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(colLocation + i > array[0].length - 1)
{
return;
}
else if(array[rowLocation][colLocation + i] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found horizontally at row " + rowLocation + " and column " + colLocation);
System.out.println();
return;
}
public void checkDown()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(rowLocation + i > array.length - 1 && colLocation + i > array[0].length - 1)
{
return;
}
else if(array[rowLocation + i][colLocation] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found vertically at row " + rowLocation + " and column " + colLocation);
System.out.println();
}
public void checkDiagonal()
{
for(int i = 1; i < (targetWord.length()); i++)
{
if(colLocation + i > array[0].length - 1 || rowLocation + i > array.length - 1)
{
return;
}
else if(array[rowLocation + i][colLocation + i] != targetWord.charAt(i))
{
return;
}
}
System.out.println(targetWord + " found diagonally at row " + rowLocation + " and column " + colLocation);
System.out.println();
}
}
Why doesn't this happen when I comment out the checkDown() method? How can I fix it?
I'd appreciate any help. Thank you!
there a three circumstances which cause the fail:
Cause you use the do-while-loop, which checks his condition on the end of your loop, the programm is looking for the word "end before finishing
Your last row has an "e" (and thats your luck ;-) ). So your Analysis starts
with row 9, col 3.
this condition:
if(rowLocation + i > array.length - 1 && colLocation + i > array[0].length - 1)
akaif(9 + 1 > 9 && 3 + 1 > 14)
gives back true && false => false
causing an out of bounce in your next condition:
else if(array[rowLocation + i][colLocation] != targetWord.charAt(i))
aka
else if(array[9 + 1][3] != targetWord.charAt(i))
So change && to ||...
If you dont wont to check the word "end" exchange your do-while with a while(true) and check via
if(!targetword.equals("end"))
break;
immediately after the scanner.

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;
}

Java: Array with loop(matches)

I need to find the first match in this task. Probably i am just missing something. As you can see, i found the last match.I am not copied the first half of the code. Thank you.
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
}
}
if (hely == -1) {
System.out.println("text");
} else {
System.out.println("text " + a + " text " + (hely + 1) + "text");
}
break the loop when you find first match.
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
break;
}
}
You need to exit the for loop after finding the first match:
for (int i = 0; i <= n - 1; i++) {
if (iv[i] == a) {
hely = i;
break;
}
}

go to beginning of for statement in java

I'm very new to Java and maybe my question is a bit irritating.
I have two for loops in my code and I want to go to the beginning of each one by a for-else statement.
public static void main(String[] args)
{
int[][] x=new int[1000][1000];
int[] Z=new int[1000];
lable1:
for(int i=1; i<=1000; i++)
{
Z[i]=rand1.nextInt(1000);
System.out.println("Z["+i +"] = " + Z[i] );
if(Z[i]>0 && Z[i]<=Nk)
{
int Z1=Z[i]-1;
lable2:
for(int j = 1; j<=Z1;j++ )
{
x[i][j]= rand2.nextInt(1000);
sum+=x[i][j];
if( sum<1000)
{
x[i][(j+1)]=1000-sum;
System.out.println("x[" + i+"][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i+"][" + (j+1) + "] = " +x[i][(j+1)]);
}
else{
// ????
//Goto lable2;
}
}
}
else{
//goto label1;
// ????
}
}
}
You can break to any defined label (within scope) by using:
break label;
Same holds for continue.
Here is something to read.
In your particular example, removing the elses would do what you want.
Just use continue keyword.. It will continue with the next iteration.. No need to label your loop.. As you are not continuing the outer loop from the inner one.. Or, if you want to continue with outer loop, you can use continue with a label...
And you should use your for loop from j = 0 to j < z1..
for(int j = 0; j < Z1;j++ ) {
if( sum<1000) {
x[i][(j+1)]=1000-sum;
System.out.println("x[" + i+"][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i+"][" + (j+1) + "] = " +x[i][(j+1)]);
}
else{ // Not needed if your else does not contain anything else..
continue;
}
}
In fact you don't need an else block at all.. If you are not doing any further processing in it..
Just remove it.. It will automatically go to your loop..
Suggestion: - You should use coding convention.. variable names start with lowercase letter or underscore.. (Z1 -> z1)
Here you are:
public static void main(String[] args) {
int[][] x = new int[1000][1000];
int[] Z = new int[1000];
boolean resetOuterCycle = true;
for (int i = 0; i < 1000; i++) {
Z[i] = rand1.nextInt(1000);
System.out.println("Z[" + i + "] = " + Z[i]);
if (Z[i] > 0 && Z[i] <= Nk) {
int Z1 = Z[i] - 1;
boolean resetInnerCycle = true;
for (int j = 0; j < Z1; j++) {
x[i][j] = rand2.nextInt(1000);
sum += x[i][j];
if (sum < 1000) {
x[i][(j + 1)] = 1000 - sum;
System.out.println("x[" + i + "][" + j + "] = " + x[i][j]);
System.out.println("Nx[" + i + "][" + (j + 1) + "] = " + x[i][(j + 1)]);
} else if (resetInnerCycle) {
j = 0;
resetInnerCycle = false;
}
}
} else if (resetOuterCycle) {
i = 0;
resetOuterCycle = false;
}
}
}
- In your above code you can use 2 approach to do it...
1st Approach : No else part
for (int i = 0; i < 1000; i++) {
if (Z[i] > 0 && Z[i] <= Nk){
for (int j = 0; j < Z1; j++) {
if(sum < 1000){
}
}
}
}
2nd Approach : With else part and continue
for (int i = 0; i < 1000; i++) {
if (Z[i] > 0 && Z[i] <= Nk){
for (int j = 0; j < Z1; j++) {
if(sum < 1000){
}else{
continue;
}
}
}else{
continue;
}
}

Categories

Resources