I have the following code and would like to have the test run consider the outcome of the ‘desired output’ below. In particular, the “!!!Parse Error! End Tag and Start Tag Mismatch!” statement. This would happen when ‘Ending tag: ‘ does not match ‘Popped Starting tag: ‘. I have placed the following code to help with this, but I am not sure what is on the other side of the ‘!=’ operator.
if(stack.pop() != ) { System.out.println("!!!Parse Error! End Tag and Start Tag Mismatch!"); break; }
Desired output:
===> Test 3: <html> </head> </body> </html> [<html>, </head>, </body>, </html>] Beginning tag: <html> Ending tag: </head> Popped Starting tag: <html> !!!Parse Error! End Tag and Start Tag Mismatch! Test 3 all done!
Code:
class Main { static String[] tests = {"<html> <head> </head> <body> </body> </html>","<html> </head> </body>","<html> <head> <title> </title> </head> <body> <h1> </h1> </body> </html>","<html> </head> </body> </html>"}; public static void main(String[] args) { System.out.println("FEC-Stacks"); System.out.println("Code by Julian Blanco"); //System.out.println(tests.length); for (int i = 0; i < tests.length; i++) { System.out.println("===> Test " + i + ": " + tests[i]); String[] tags = tests[i].split(" ", 5); System.out.println(java.util.Arrays.toString(tags)); java.util.Stack<String> stack = new java.util.Stack<String>(); for( i = 0; i < tags.length; i++) { if(tags[i] == "<html>" || tags[i] == "<head>" || tags[i] == "<body>") { stack.add(i,tags[i]); System.out.println("Beginning tag: " + tags[i]); } else if(tags[i] == "</html>" || tags[i] == "</head>" || tags[i] == "</body>") { System.out.println("Ending tag: " + tags[i]); System.out.println("Popped Starting tag: " + stack.pop()); if(stack.pop() != ) { System.out.println("!!!Parse Error! End Tag and Start Tag Mismatch!"); break; } } } if(stack.isEmpty() == false) { System.out.println("!!!Parse Error!"); } System.out.println("Test " + i + " all done!"); } } }
Advertisement
Answer
To achieve that, you would have to compare the tag on the top of the stack with the current end tag, however you would have to modify the end tag to be comparable with its starting counterpart, since </html>
is always different than <html>
, due to the /
(slash) character. So you would have to get rid of slash, replace "/"
with ""
(an empty string) before comparing the end tag to the start tag.
Here is an idea, how you could change an end tag before you need to compare it to the start tag
String endTag = tags[i] String comparableEndTag = endTag.replaceAll("/", "")
Also note that in Java, if you want to compare strings for equality by their characters, you have to use someString.equals(otherString)
, because ==
compares the references – it checks if it is the same instance. There are cases where ==
works on strings, due to Java’s string interning, but that topic is beyond the scope here. So use .equals()
.
stack.pop().equals(comparableEndTag)
When you want to check the top of the stack without popping (removing) the value form it, use peek()
instead of pop()
.
// peek() to not pop the value from the stack already on this line System.out.println("Popped Starting tag: " + stack.peek());
When you call tests[i].split(" ", 5);
with value 5
as the second parameter (the 2nd parameter is limit), it means that you want only up to limit - 1
splits to happen (that is explained in the documentation of the split(String regex, int limit)
method). In your case, when there might be more than just 5 tags, use 0 for the second parameter, so that you split on all spaces, not just on the first 4.
Your outer for loop and your inner for loop use the same counter variable i
. That was probably not intended.
Hopefully these ideas/hints help you change your code and do the comparison correctly. If they don’t, let me know in the comments.