odd if statement behavior in java - java

I'm having a weird issue with if-else statements in java. Below is a recursive method that attempts to find the end of a maze called getPathThroughMaze.
private static String getPathThroughMaze(char[][] maze, Set<Point> visited, Point currentPoint) {
int currentX = currentPoint.x;
int currentY = currentPoint.y;
visited.add(currentPoint);
//end case. append '!' so we know which path leads to the end of the maze
if (currentX == (xLength - 2) && currentY == (yLength - 1)) {
return "!";
}
char left = maze[currentY][currentX - 1];
char right = maze[currentY][currentX + 1];
char up = maze[currentY - 1][currentX];
char down = maze[currentY + 1][currentX];
char current = maze[currentY][currentX];
/* If valid, visit all non-visited adjacent squares.
Only odd numbered columns will be traversed
since even numbered columns represent vertical wall
columns
*/
if (right == '_' || right == ' ') {
Point nextPoint = new Point(currentX + 2, currentY);
if (!visited.contains(nextPoint)) {
String path = "E" + getPathThroughMaze(maze, visited, nextPoint);
if (path.endsWith("!")) {
return path;
} else {
//do nothing.
}
}else {
//do nothing.
}
} else if (up == ' ') {
Point nextPoint = new Point(currentX, currentY - 1);
if (!visited.contains(nextPoint)) {
String path = "N" + getPathThroughMaze(maze, visited, nextPoint);
if (path.endsWith("!")) {
return path;
} else {
//do nothing.
}
} else {
//do nothing.
}
} else if ( current == ' ' && (down == '_' || down == ' ')) {
Point nextPoint = new Point(currentX, currentY + 1);
if (!visited.contains(nextPoint)) {
String path = "S" + getPathThroughMaze(maze, visited, nextPoint);
if (path.endsWith("!")) {
return path;
} else {
//do nothing.
}
} else {
//do nothing.
}
} else if (left == '_' || left == ' ') {
Point nextPoint = new Point(currentX - 2, currentY);
if (!visited.contains(nextPoint)) {
String path = "W" + getPathThroughMaze(maze, visited, nextPoint);
if (path.endsWith("!")) {
return path;
} else {
//do nothing.
}
} else {
//do nothing.
}
} else {
return "";
}
//otherwise...
return "";
}
At the point in the recursion where I run into a problem the variables are:
currentX = 3
currentY = 2
right = '|'
left = '|'
up = ' '
down = '_'
current = ' '
visited contains points (1,1), (3,1), (3,2)
In the first else if statement:
else if (up == ' ')
a new point (3,1) is created which IS already contained in the visited set. What I expect to happen is that
if(!visited.contains(nextPoint))
will evaluate to false and that I will (maybe after a few step over clicks in the debugger) arrive at
else if ( current == ' ' && (down == '_' || down == ' '))
where I can then check that condition (which I expect to be true) and continue traversing the maze. What actually happens is when I click step over on
if(!visited.contains(nextPoint))
the debugger (in both elcipse and intellij) moves all the way to the very last return statement of my method and it wants to return "". I don't understand why all my other if else statements are being skipped. Can anyone enlighten me as to why that might be the case? Please let me know if my explanation isn't clear enough.

If/else statements are exclusive, so you will not arrive to else if ( current == ' ' && (down == '_' || down == ' ')) as you have already entered the else if (up == ' ') branch. As if(!visited.contains(nextPoint)) in the inner if is false, the program goes into its else part with //do nothing comment and does nothing (actually, you don't need to and shouldn't write an empty else statement. At least add a log statement to it to make it easier to debug). Then it exits the if/else block and goes to return.
If you want your code to check every branch of if/else on every method call, just replace it with a number of simple if statements.
I.e. instead of:
if (condition1){
} else if (condition2){
} else if (condition3){
}
write
if (condition1){
}
if (condition2){
}
if (condition3){
}

Related

Getting wrong output in a test case in Chech brackets in code

boolean Match(char c) {
if (this.type == '[' && c == ']')
return true;
if (this.type == '{' && c == '}')
return true;
if (this.type == '(' && c == ')')
return true;
return false;
}
Stack<Bracket> opening_brackets_stack = new Stack<Bracket>();
for (int position = 0; position < text.length(); ++position)
{
char next = text.charAt(position);
if (next == '(' || next == '[' || next == '{')
{
// Process opening bracket, write your code here
Bracket temp = new Bracket(next,position);
opening_brackets_stack.push(temp);
}
if (next == ')' || next == ']' || next == '}')
{
// Process closing bracket, write your code here
try{
Bracket item = opening_brackets_stack.pop();
if(!item.Match(next))
{ //not match
System.out.println(position+1);
return;
}
}
catch(EmptyStackException e){}
}
}
// Printing answer, write your code here
try{
if(opening_brackets_stack.isEmpty())
{
System.out.println("Success");
}
else {
Bracket item = opening_brackets_stack.pop();
//print position of first unmatched opening bracket
System.out.println(item.position+1);
}
}
catch (EmptyStackException e){}
}
i am getting wrong answer in cases like "}","()}" in which bracket is at last position.
i am supposed to get answer "1","3" respectively for above cases but i am getting "Success".
In all other cases, it works perfectly fine.
What should I do?
With a string like "}", your code tries to pop an opening brace from the stack. But the stack is empty so you get an EmptyStackException, and control is transferred to your exception handler. Which does nothing.
Rather than trying to catch an exception, check to see if the stack is empty. If it is, then you know that you have too many closing braces. Treat it the same way you'd treat a false return from item.Match.

How do you break out of recursion with no base case

So im working on this program that will recursively solve a maze that i get from a txt file. I put the maze into a 2d array. Here is an example of the most simple maze.
+-+-+-+
|S| |
+ + + +
| |E|
+-+-+-+
i know im probably not going about solving the maze in the best way but i think my way works i just need to know how to break out of my recursion loop. What im doing is checking if there is a boarder in the next place and if there is a '*' two places later if not then i move there and put down a marker. This got me to the end of the maze but it breaks after. I need a way to break out of the loop. I just started learning about recursion so i think this is the problem but im not exactly sure.
The wrong choice method will return me to the last place where there is a cell with an open boarder and a no '*' with in two places.
public static void solveMaze(int COL, int ROW){
//find first open cell and choose it
if(drawArray[COL][ROW+1] == ' ' && drawArray[COL][ROW+2] != '*'){
//if(drawArray[COL][ROW+2] == 'E')
drawArray[COL][ROW+2] = '*';
ROW+= 2;
solveMaze(COL,ROW);
}
else if(drawArray[COL+1][ROW] == ' ' && drawArray[COL+2][ROW] != '*'){
drawArray[COL+2][ROW] = '*';
COL+= 2;
solveMaze(COL,ROW);
}
else if(drawArray[COL][ROW-1] == ' ' && drawArray[COL][ROW-2] != '*'){
drawArray[COL][ROW-2] = '*';
ROW-= 2;
solveMaze(COL,ROW);
}
else if(drawArray[COL-1][ROW] == ' ' && drawArray[COL-2][ROW] != '*'){
drawArray[COL-2][ROW] = '*';
COL+= 2;
solveMaze(COL,ROW);
}
else
wrongChoice(COL,ROW);
}
One can provide a partial result (initially empty) as parameter. And one can return a result.
Another parameter for recursion often is the set of possible candidates.
For instance something like:
public static void solveMaze(int COL, int ROW, Path pathTaken) {
Path pathTaken = new Path();
if (solveMazeRecursively(START_COL, START_ROW, pathTaken)) {
...
}
}
private static boolean solveMazeRecursively(int COL, int ROW, Path pathTaken) {
if (drawArray[COL][ROW+1] == 'E') {
System.out.println(pathTaken);
return true;
}
// The real work...
if (drawArray[COL][ROW+1] == ' ' && drawArray[COL][ROW+2] != '*'){
drawArray[COL][ROW+2] = '*';
ROW += 2;
takenPath.add(COL, ROW+2);
if (solveMazeRecursively(COL,ROW, takenPath)) {
return true;
}
takenPath.remove(COL, ROW+2);
}
Recursion implies being lazy checking first whether nothing has to be done (solution present, or impossible to continue), and otherwise delegating to new function instances.

Using replace to take a character and change it to another in java

I am trying to figure out how to remove certain characters to make it English after it being in l33t speak. For example, I 54w 3 5hip5, would translate to I saw 3 ships. I need the 3 to stay a 3 here but in, N3v3r f0rg37 y0|_|r t0w31, I would need the 3's to become e's. Here is my code as follows. All the characters translate over correctly, but I just can't figure out how to do the 3's to e's.
My question is, what is needed to be added to get the 3's to be e's at a certain time, and to have my 3's stay 3's another time. Just so that you know, is that we aren't allowed to use regex, arrays, or string builder for this.
Rules are that if the number is supposed to be a number that it stays a number when you translate it from l33t to English, if the l33t number is a letter than you replace the number and turn it into the letter that corresponds to it.
I also have a different block of code that already takes into consideration the 3 to e's, but instead adds two u's instead of one.
Here are the replacements for the letters, a = 4, b = 8, e = 3, l = 1, o = 0, s = 5, t = 7, u = |_|, z = 2.
I decided to go the route of mike's answer since I understand exactly what's going on.
Thanks to everyone for the help!
Input/Output examples
This following code translates
I 54w 3 5hip5
to
I saw 3 ships
and
3 5hip5 4r3 c0ming m3 w4y
to
3 ships are coming me way
Code
public static String translateToEnglish(String phrase) {
if (phrase == null)
return null;
boolean threeAtBeginning = false, threeAtEnd = fal;
if (phrase.charAt(0) == '3' && phrase.charAt(1) == ' ')
threeAtBeginning = true;
int length = phrase.length();
if (phrase.charAt(length - 1) == '3' && phrase.charAt(length - 2) == ' ')
threeAtEnd = true;
String finished = phrase.replace('4', 'a') .replace('1', 'l') .replace('2', 'z') .replace('5', 's') .replace('8', 'b') .replace('0', 'o') .replace('7', 't') .replace("|_|", "u") .replace("3", "e");
finished = finished.replace(" e ", " 3 ");
if (threeAtBeginning)
finished = '3' + finished.substring(1);
if (threeAtEnd)
finished = finished.substring(0, length - 1) + '3';
return finished;
}
This is clearly homework, and the restrictions are clearly intended to prevent any sane solution, but here's an O(n^2) solution that seems to avoid the restrictions:
public class RemoveL33t {
public static void main(String[] args) {
System.out.println(removeL33t("I 54w 3 5hip5"));
System.out.println(removeL33t("I 54w 33 5hip5"));
System.out.println(removeL33t("I 54w 45 5hip5"));
System.out.println(removeL33t("N3v3r f0rg37 y0|_|r t0w31"));
}
public static String removeL33t(String s) {
String result = "";
for (int pos = 0;;) {
// Find the beginning of the next word.
int whitespaceBegin = pos;
while (pos < s.length() && Character.isWhitespace(s.charAt(pos))) {
pos++;
}
// Add the whitespace to the result.
result += s.substring(whitespaceBegin, pos);
// If there is no next word, then we're done.
if (pos >= s.length()) {
return result;
}
// Find the end of the word. Determine if the word is entirely numbers.
int wordBegin = pos;
boolean nonNumber = false;
while (pos < s.length() && !Character.isWhitespace(s.charAt(pos))) {
nonNumber |= s.charAt(pos) < '0' || s.charAt(pos) > '9';
pos++;
}
// Append the word. Perform replacements if it contains a non-number.
if (nonNumber) {
result += s.substring(wordBegin, pos)
.replace('4', 'a')
.replace('8', 'b')
.replace('3', 'e')
.replace('1', 'l')
.replace('0', 'o')
.replace('5', 's')
.replace('7', 't')
.replace("|_|", "u")
.replace('2', 'z');
} else {
result += s.substring(wordBegin, pos);
}
}
}
}
I think this is it.
public static String translateToEnglish(String phrase) {
if (phrase == null) {
return null;
}
String finished = phrase.replace('4', 'a') .replace('1', 'l') .replace('2', 'z') .replace('5', 's') .replace('8', 'b') .replace('0', 'o') .replace('7', 't') .replace("|_|", "u") .replace("3", "e");
finished = finished.replace(" e ", " 3 ");
if(finished.startsWith("e ")){
finished = "3 " + finished.substring(2);
}
if(finished.endsWith(" e")){
finished = finished.substring(0, finished.length()-2) + " 3";
}
return finished;
}
I don't know if this is the answer, but is the best i could think of
public static void main (String[] args) throws java.lang.Exception
{
String c = "I 54w 45 5hip5";
for(String s: c.split(" ")){
try{
Integer.parseInt(s);
System.out.print(s + " ");
}
catch(NumberFormatException e){
s = s.replace('4', 'a').replace('1', 'l').replace('2', 'z').replace('5', 's').replace('8', 'b').replace('0', 'o').replace('7', 't').replace("|_|", "u").replace("3", "e");
System.out.print(s + " ");
}
}
}
This is for your "new" code that you decided to use, or this could just be an alternate solution. The input/output is identical to the samples I gave in my other answer:
public static String translateToEnglish(String phrase) {
if (phrase == null)
return null;
String finished = "";
for (int i = 0; i < phrase.length(); i++) {
char c = phrase.charAt(i);
if (c == '4')
finished += 'a';
else if (c == '3') {
if (i != phrase.length() - 1)
{
if (phrase.charAt(i + 1) == ' ') {
if (i == 0)
finished += c;
else
if (phrase.charAt(i - 1) == ' ')
finished += c;
else
finished += 'e';
}
else
finished += 'e';
}
else
{
if (phrase.charAt(i - 1) == ' ')
finished += c;
else
finished += 'e';
}
} else if (c == '1')
finished += 'l';
else if (c == '2')
finished += 'z';
else if (c == '5')
finished += 's';
else if (c == '7')
finished +='t';
else if (c == '8')
finished += 'b';
else if (c == '0')
finished += 'o';
else if (i + 2 < phrase.length() && phrase.charAt(i + 1) == '_' && phrase.charAt(i + 2) == '|') {
finished += 'u';
i += 2;
} else
finished += c;
}
return finished;
}

How to compare three boolean values

Compare three boolean values and display the first one that is true.
Hey guys, I am trying to write a program that compares three boolean values and displays the first true one. I am comparing three words for their length, and it will display the longest. The error that I am getting is that my else tags aren't working. Take a look at the code.
//Check which word is bigger
if (len1 > len2)
word1bt2 = true;
if (len2 > len3)
word2bt3 = true;
if (len1 > len3)
word1bt3 = true;
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true);
System.out.println(wor1);
else if (word2bt3 == true);
System.out.println(wor2);
else System.out.println(wor3);
I have set boolean values for word1bt2, word2bt3 and word1bt3. In eclipse, I am getting a syntax error under the elses in my code above. Any help would be great!
if (word1bt2 == true && word1bt3 == true);
Is wrong, you need to remove the semicolon:
if (word1bt2 == true && word1bt3 == true)
Same for the elses
else (word2bt3 == true);
Is wrong too, it should be
else if (word2bt3 == true)
Side note: boolean values can be used as condition, so your if statements should be
if (word1bt2 && word1bt3) // The same as if (word1bt2 == true && word1bt3 == true)
How to compare three boolean values?
Dont!
If you find yourself needing to compare three variable you may as well cater for any number of variables immediately - there's no point hanging around - do it properly straight away.
public String longest(Iterator<String> i) {
// Walk the iterator.
String longest = i.hasNext() ? i.next() : null;
while (i.hasNext()) {
String next = i.next();
if (next.length() > longest.length()) {
longest = next;
}
}
return longest;
}
public String longest(Iterable<String> i) {
// Walk the iterator.
return longest(i.iterator());
}
public String longest(String... ss) {
// An array is iterable.
return longest(ss);
}
Remove the ; and change it with brackets {}.
if (word1bt2 && word1bt3) {
System.out.println(wor1);
} else if (word2bt3) {
System.out.println(wor2);
} else {
System.out.println(wor3);
}
Issue with the else blocks: use {} insteaad of () to enclose instructions...
Remove the ; at the first if!!!!! - Quite common mistake, with very puzzling results!
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true) { //leave ; and always add bracket!
System.out.println(wor1);
}
else if(word2bt3 == true)
{
System.out.println(wor2);
}
else {
System.out.println(wor3);
}
if you need a condition in an else branch, you have to use if again - plain else won't have such a feature...
ALWAYS use brackets for bodies of if statements, loops, etc!!!
Be extremely careful NOT to use ; in the lines that don't behave well with it:
if statements
for loops
while() {...} loops' while statement
try this, if lenght are equal then s1 is considered as Bigger. Also i have not added null check
public class Test {
public static void main(String[] args) {
String word1 = "hi";
String word2 = "Hello";
String word3 = "Hell";
String Bigger = null;
if(word1.length() >= word2.length() && word1.length() >= word3.length() ){
Bigger = word1;
}else if(word2.length() >= word1.length() && word2.length() >= word3.length()){
Bigger = word2;
}else if(word3.length() >= word2.length() && word3.length() >= word1.length()){
Bigger = word3;
}
System.out.println(Bigger);
}
}

Compare strings using recursion

I've got a homework assignment that I just can't figure out. I have to write a static method match(String x, String y) that returns a boolean for whether or not string x and string y match. The matching process should allow "wild cards" such as '#' character which will match with any single character and the '*' character which will match with 0 or more characters of any type. I'm not allowed to use any loops and I have to use recursion.
What I've written so far is this...
public class CompareStrings {
public static boolean match(String x, String y) {
if (x.length() <= 1 && y.length() <= 1) {
if (x.equals("*") || y.equals("*")) {
return true;
}
if ((x.length() == 1 && y.length() == 1) && (x.equals("#") || y.equals("#"))) {
return true;
}
return x.equals(y);
}
String x1 = "";
String x2 = "";
String y1 = "";
String y2 = "";
if (x.length() == 0 && y.charAt(0) == '*') {
y2 = y.substring(1, y.length());
}
if (y.length() == 0 && x.charAt(0) == '*') {
x2 = x.substring(1, x.length());
}
if (x.length() > 1 && y.length() > 1) {
if (x.length() != y.length() && !x.contains("*") && !y.contains("*")) {
return false;
}
if (x.charAt(0) == '*') {
x1 = "*";
x2 = x.substring(1, x.length());
y1 = "*";
y2 = y.substring(y.length()-x2.length(), y.length());
}
else if (y.charAt(0) == '*') {
y1 = "*";
y2 = y.substring(1, y.length());
x1 = "*";
x2 = x.substring(x.length()-y2.length(), x.length());
}
else {
x1 = x.substring(0, 1);
x2 = x.substring(1, x.length());
y1 = y.substring(0, 1);
y2 = y.substring(1, y.length());
}
}
return match(x1, y1) && match(x2, y2);
}
public static void main(String[] args) {
System.out.println(match("hello", "hello.") + " 1 false"); // should return false
System.out.println(match("hello", "jello") + " 2 false"); // should return false
System.out.println(match("hello", "h#llo") + " 3 true"); // should return true
System.out.println(match("hello", "h####") + " 4 true"); // should return true
System.out.println(match("hello", "h*") + " 5 true"); // should return true
System.out.println(match("hello", "*l*") + " 6 true"); // should return true
System.out.println(match("anyString", "*") + " 7 true"); // should return true
System.out.println(match("help", "h####") + " 8 false"); // should return false
System.out.println(match("help", "h*") + " 9 true"); // should return true
System.out.println(match("help", "*l*") + " 10 true"); // should return true
System.out.println(match("help", "*l*p") + " 11 true"); // should return true
System.out.println(match("help", "h#llo") + " 12 false"); // should return false
System.out.println(match("", "*") + " 13 true"); // should return true
System.out.println(match("", "***") + " 14 true"); // should return true
System.out.println(match("", "#") + " 15 false"); // should return false
System.out.println(match("", "") + " 16 true"); // should return true
}
}
The main method is the test program given by the assignment. I realize my code is a little messy - I was scrambling a bit - but I can seem to get most of it working. The only example that doesn't return the right value is number 11. I get false when it should be true. The reason I think this is happening is because since the string y starts with a '', the thing my method does is splits both x and y strings into their last 3 characters, even though that first '' in y is supposed to represent 2 characters. How can I make it so that cases like this return a match?
Basically you need to understand the concept of recursion (that is the objective of your homework). The way recursion works is that everytime a function calls itself, the current execution (variables/ execution info) goes onto a stack and sleeps there till the new call finishes.
To solve the problem you have mentioned, lets take a simple example, hello and h#llo. A basic way to solve problem will be that match service call itself again and again till
A perfect match is found - return true
A failure condition is found- return false
In absence of above 2, match calls itself with one character less than the prev call
Something like
Call 1: hello & h#llo// calls match again and present call moves to stack, waits for a reply
Call 2: ello & #llo //matches special character
call 3: llo and llo// perfect match return true to call 2
Back to call 2: receives true from prv call and returns back to call 1
Back to call 1: receives true and returns to main.
Once you understand the concept of recursion stack, solving this problem will be simple
Your final match method will look something like
public static boolean match(String x, String y) {
//if both are empty
if(x.length()==0 && y.length()==0) return true;
//if one is empty
if(x.length()==0 )
{
if(y.charAt(0)!='*')
return false;
if(y.length()!=1)
//border line case
return match(x,y.substring(1));
else
return true;
}
if(y.length()==0 )
{
if(x.charAt(0)!='*')
return false;
if(x.length()!=1)
//border line case
return match(y,x.substring(1));
else
return true;
}
//Base case
if(x.equals(y) || x.equals("*") || y.equals("*"))
{
return true;//we are done as strings are equal
}
//we are here that means strings are not equal yet
if(x.charAt(0)=='#' || y.charAt(0)=='#' ||x.charAt(0)==y.charAt(0))
{
if(x.length()==1 && y.length()==1) return true;//this was the last character
if(x.length()>1 && y.length()>1)
{
//we have single char wild card or char 0 equal, lets remove the char at 0th location and check again
return (match(x.substring(1),y.substring(1)));
}
}
if(x.charAt(0)=='*')
{
//this is interesting now, we will need to skip 0..n number of characters till we find matching pattern
//case 0 chars: he*llo and hello
if(match(x.substring(1),y)==true)
{
return true;
}
else if (match(x.substring(1),y.substring(1))==true)
{
//case 1: he*lo and hello
return true;
}
else
{
//case n chars: h*o and hello
return (match(x, y.substring(1)));
}
}
if(y.charAt(0)=='*')
{
//this is interesting now, we will need to skip 0..n number of characters till we find matching pattern
//case 0 chars: he*llo and hello
if(match(y.substring(1),x)==true)
{
return true;
}
else if (match(x.substring(1),y.substring(1))==true)
{
//case 1: he*lo and hello
return true;
}
else
{
//case n chars: h*o and hello
return (match(y, x.substring(1)));
}
}
//nothing worked out
return false;
}
In the spirit of recursion (one of your tags) but not of Java, here is a Scheme implementation that gets all your test cases correct.
(define (match s1 s2) ; assumes s1 = string, s2 = pattern
(let matching ((l1 (string->list s1)) (l2 (string->list s2)))
(if (null? l1)
(or (null? l2) (eq? (car l2) #\*)) ; every #\*
(let ((c1 (car l1))
(c2 (car l2)))
(or (and (or (eq? c2 c1)
(eq? c2 #\#))
(matching (cdr l1) (cdr l2))) ; take one char from l1 and l2
(and (eq? c2 #\*)
(matching (cdr l1) l2))))))) ; take one char from l1
Note, for test cases with "*l*" the above gets the right answer but for the wrong reason. There are others that the above gets wrong (related to "*") but that are not in your test cases.

Categories