This is an school assignment ive been trying to solve for a week, i still havent gotten close to the real answer. If someone is so kind and guides me with some solid pointers it would be really apreciated, Notice i do not want the solution.
For example, the strings () , [()] , {([])} , ()[] are 4 balanced strings.
Write the Recursive method:`
public static boolean isBalanced(String in)
that returns true if in is a balanced parentheses string and
false if it is not.
Here is some of the code ive been working on:
public static boolean isBalanced(String in){
if(in.length() == 0){
return true;
}
char aux = in.charAt(0);
if(aux == '{' ||aux == '[' ||aux == '(' ){
if(aux == '{'){
return isBalanced(in.substring(1));
}
if(aux == '}'){
return false || isBalanced(in.substring(1));
}
if(aux == '['){
return isBalanced(in.substring(1));
}
if(aux == ']'){
return false || isBalanced(in.substring(1));
}if(aux == '('){
return isBalanced(in.substring(1));
}
if(aux == ')'){
return false || isBalanced(in.substring(1));
}
}
return isBalanced(in.substring(1));
}
}
Since you do not want a copy&paste solution, you should check out this post:
https://stackoverflow.com/a/25854415/1057547
it is written in PHP, but exlains the idea behind, which you can adapt easily.
The page to "validate" your input is still available: http://dog-net.org/string.php, so you can test "huge" strings without doing paperwork.
As of your comments, you require to implement an recursive approach. So, with the given signature of isbalanced(String str) There are two options in my mind to generate a recursive approach:
First, you could - in the first recursion call - iterate over the string using the described ways, until you are balanced but have a remaining string. Then you just need to recursivly call the method on the remaining string.
So, for the input String () [()]{([])}()[] the callstack should become:
isBalanced("()[()]{([])}()[]");
isBalanced("[()]{([])}()[]");
isBalanced("{([])}()[]");
isBalanced("()[]");
isBalanced("[]");
This however will not go into recursion for strings like {([])} - because they could be handled within one call.
The second way would be to enter recursion depending on "characters". So, you always seek for the matching bracket of the first opening bracket within ONE recursion call, replace both and continue with another call. This would be a slower solution - performance-wise - but allows recursion with the given signature.
The callstack then should look like:
isBalanced("()[()]{([])}()[]");
isBalanced("__[()]{([])}()[]");
isBalanced("___()_{([])}()[]");
isBalanced("______{([])}()[]");
isBalanced("_______([])_()[]");
isBalanced("________[]__()[]");
isBalanced("____________()[]");
isBalanced("______________[]");
isBalanced("________________");
ps.:
No matter what you do, don't forget to add
isBalanced(String str){
if (str.length() % 2 != 0) return false;
...
}
for the "A+" :-)
Related
I am confused on how to use || and && in the same if statement.
What I am trying to do is have it print something if the string starts with an "D" or an "O", and if one is true check if the string has a character length of two.
Example: if the string is "DE" it will print something. However, if it is "SE" it will not print anything.
else if( (answer.startsWith("D") || answer.startsWith("O"))
&& (answer.length() == 2) ) {
//print something
}
Java is applying a "short circuit" to your logic. It does the first part (starts with "D" or "O") and if that's true it proceeds to the second part (length is 2). However if the first part evaluates to false then it never even bothers to execute the second part.
So your "SE" string will never go into the "print something" bit because it doesn't meet your first criteria of starting with D or O. And based on your description of what the logic should be, that is correct.
If you actually mean that if it starts with "D" or "O" OR is 2 characters long then your logic statement should have been:
else if( answer.startsWith("D") || answer.startsWith("O")
|| (answer.length() == 2 ) {
//print something
}
Edit: Oops, just pasted the original code in the first time...!
I would check first the length and after the two conditions e.g.
else if (answer.lenght()==2) {
if (answer.startsWith("D") || answer.startsWith("O"){
//print something that lenght is 2 and starts with D or O
}
}
}
In that case you have to check length first because && will true if left side and right side both true
else if( (answer.length() == 2)&&(answer.startsWith("D") || answer.startsWith("O"))
{
//your logic
}
So here's a snippet of code I'm working on:
String direction = s.readLine();
System.out.println(direction);
if (direction.equals("up") != true && direction.equals("down") != true &&
direction.equals("left") != true && direction.equals("right") &&
direction.equals(null) != true) {
System.out.println("Invalid Solution file");
System.exit(0);
}
What it is supposed to do is read a line from a text file (using a BufferedReader) and then if the line isn't either a valid direction or blank then it should print "Invalid Solution" and exit.
The problem is that no matter what the direction string is the if statement still runs. I put in a println to check whether the direction was being read correctly but it seems absolutely fine. So why isn't the code working as intended?
Part of your problem is readability. Fix that and your problem is 90% solved:
private static List<String> DIRECTIONS = Arrays.asList("up", "down", "left", "right");
then
if (!DIRECTIONS.contains(direction)) {
System.out.println("Invalid Solution file");
System.exit(0);
}
The other 10% was how to check for null, which is direction == null, but if you use this code you don't need to, because contains(null) will conveniently return false.
You code is much more complex than it is needs to.
Consider this instead:
Set<String> validDirections = new HashSet<>(Arrays.asList("up", "down", ...
if (validDirections.contain(direction.toLowerCase()) {
// good ...
} else {
// bad ..
}
You can make validDirections a global constant for example; so it could be used in other places as well.
What I am trying to explain here is: your code is low-level. Low level code is hard to write, read, maintain and extend. Programming is always about creating good abstractions. Or vice versa: if you don't use abstractions, you end up with pretty abstract code, like the one you are showing here!
For example: if you need another direction, you have to put into your already way too complicated if condition. In my solution, you just put it into the statement that builds that Set.
Finally: your error message, is saying nothing. So, that string is bad; but why is it? Wouldn't it be better to at least print the string that caused the error?!
Here && direction.equals("right") I think you have done a mistake since it is on contradiction with the rest :
direction.equals("up") != true &&
direction.equals("down") != true &&
direction.equals("left") != true
You test the negation in the most of conditions but direction.equals("right") tests the affirmation.
Try it , it's the same thing but less verbose and more readable :
if (direction !=null && !direction.equals("up") &&
!direction.equals("down") &&
!direction.equals("left") &&
!direction.equals("right") ){
System.out.println("Invalid Solution file");
System.exit(0);
}
First, you should not use != true with a boolean statement, it is bad form. Rewrite like this:
direction !=null &&
!direction.equals("up") &&
!direction.equals("down") &&
!direction.equals("left") &&
!direction.equals("right")
Your error was that you did not include the != true part on one of your statements within the compound if. Replace with the above code to solve the issue.
I'm confused why you are using !=true when your .equals method already returns a boolean. Try this.
String direction = s.readLine();
System.out.println(direction);
if ( direction!=null && !direction.equals("up") && !direction.equals("down")&& !direction.equals("left")&& direction.equals("right")){
System.out.println("Invalid Solution file");
System.exit(0);
}
Try the following code:
boolean match = false;
if (direction.equals("up"))
{ match = true; }
if (direction.equals("down"))
{ match = true; }
if (direction.equals("left"))
{ match = true; }
if (direction.equals("right"))
{ match = true; }
if (direction.equals(null))
{ match = true; }
if (match == false){
System.out.println("Invalid Solution file");
System.exit(0);
}
You might also want to trim the direction string after reading from file.
The quals method returns a boolean so the result does not need to be compared with the true or false value. Also, I would start with null comparison - boolean expressions in Java are shortened so if this part will be fulfilled rest of the expression is not evaluated. The correct expression might look like this:
if (direction == null || (!direction.equals("up") && !direction.equals("down") && !direction.equals("left") && !direction.equals ("right "))) {
}
But this code is not readable. You could use enums or list of Strings like below
List<String> directions = Arrays.asList("up", "down", "left", "right");
String direction = "readValue"
if (!directions.contains(direction)) {
System.out.println("Invalid direction");
System.exit(0)
}
Sorry about the ugly code. (I'm new coder trying to teach myself Java.)
I was just wondering why the compiler on http://codingbat.com refuses to run this and instead returns the error:
This method must return a result of type String
Here is the code.......................
public String startOz(String str) {
if (str.length() <= 2) {
return str;
}
else if (str.charAt(0) == 'o' && str.charAt(1) != 'z') {
return "o";
}
else if (str.charAt(1) == 'z' && str.charAt(0) != 'o') {
return "z";
}
else if (str.substring(0 , 3).equals("oz")) {
return "oz";
}
}
You need to think about what will be returned if none of those if conditions turns out to be true. Such as if you pass in the string "paxdiablo".
A simple:
return "Stuffed if I know!";
before the function closing brace may be all that's needed, though you'll probably want to use something a little more appropriate :-)
Actually, scratch that. Sit down with a pen and paper and actually write down all the inputs you expect and what the output should be for all of them.
Then think about what the output should be if the input isn't what you expect. Translating that to a series of if statements and a final return statement should then be quite easy.
If you were running this on an actual IDE, like eclipse, you would get the error:
missing return statement
Now you may be thinking,
"But Ruchir, I have 4 return statements already!"
No. Those return statements are all in if statements, meaning if the if statement isn't executed, the compiler won't know what to return. This will throw the null pointer exception.
If you are sure that one of those if statements will be executed, just put an empty return statement:
return;
By making a method without void, you are saying it will return something.
Just add a return statement outside of the if statement.
public String startOz(String str) {
if (str.length() <= 2) {
return str;
}
else if (str.charAt(0) == 'o' && str.charAt(1) != 'z') {
return "o";
}
else if (str.charAt(1) == 'z' && str.charAt(0) != 'o') {
return "z";
}
else if (str.substring(0 , 3).equals("oz")) {
return "oz";
}
return "Your last default String to return.";
}
you can add the last else statement at the end, which will execute when none of your if condition runs, like below -
else if (str.substring(0 , 3).equals("oz")) {
return "oz";
}
else{
return " last string to return" ;
}
if none of your 'if' conditions are met you still need to return a String or simply add the following to the bottom of your method.
return null;
This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I've been trying to figure out my code's bugs to no avail. I'm supposed to code an infix to postfix translator, in addition to evaluating the postfix expression. My code runs, but unfortunately it doesn't return the correct value.
I have a calculator GUI that calls the code shown below whenever the equals sign is pressed. The calculator passes as an argument a string separated by spaces. I then use the String Tokenizer on this space separated string and work from there. I can provide the code for the calculator GUI if it helps.
My problem lies with the answer the calculator provides. For example, if I input (5+2), the calculator returns 2 as an answer, and if I press the equals sign again it returns 5 as an answer. If I input (5*2)+(3*9), it returns 9 as an answer, and if I press the equals sign again it returns 5 as an asnwer. I've tried going through my code multiple times but unfortunately I haven't been able to find my mistake. Any help would be greatly appreciated!
DISCLAIMER: I am aware of the side note regarding the use of String Tokenizer. I would use something else but that is one of requirements. I haven't implemented any error checking yet or the checking of precedence because I want to make sure it works correctly assuming the input is correct and isn't excessively complicated first. Also, I'm aware that my code won't correctly process something like (5+2)-1 because of the lack of parenthesis around the 1. But then again it won't work with something even simpler than that so...I'll worry about that once I can get it to work with simpler input. Finally, this is indeed a homework assignment, but please don't think I want this to be done for me completely. Just a few pointers would be greatly appreciated.
Here is my code:
public class ExpressionEvaluator {
Stack<String> myStack = new Stack<>();
Queue<String> myQueue = new Queue<>();
String curToken; //Current token of my tokenized string.
double temp1; //Place holder for first value of the calc section.
double temp2; //Place holder for second value of the calc section.
public String processInput(String s) {
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
curToken = st.nextToken();
if (openParenthesis(curToken)) {
myStack.push(curToken);
}
if (closeParenthesis(curToken)) {
do {
myQueue.enqueue(myStack.pop());
} while (!openParenthesis(myStack.peek()));
}
if (isOperator(curToken)) {
while (!myStack.isEmpty() && !openParenthesis(myStack.peek())) {
myQueue.enqueue(myStack.pop());
}
myStack.push(curToken);
}
if (isDouble(curToken)) {
myQueue.enqueue(curToken);
}
}
while (!myStack.isEmpty()) {
myQueue.enqueue(myStack.pop());
}
while (!myQueue.isEmpty()) {
if (isDouble(myQueue.peek())) {
myStack.push(myQueue.dequeue());
}
else if (isOperator(myQueue.peek())) {
temp1 = Double.parseDouble(myStack.pop());
temp2 = Double.parseDouble(myStack.pop());
myStack.push(Double.toString(calc(temp1, temp2)));
}
else {
myQueue.dequeue();
}
}
return myStack.pop();
}
//Private methods used to simplify/clarify some things.
//Checks if input is an operator, returns true if it is
private boolean isOperator(String str) {
if (str == "+") {return true;}
else if (str == "-") {return true;}
else if (str == "*") {return true;}
else if (str == "/") {return true;}
else if (str == "^") {return true;}
else {return false;}
}
//Checks if input is an open parenthesis "(", returns true if it is
private boolean openParenthesis(String str) {
if (str == "(") {return true;}
else {return false;}
}
//Checks if input is a close parenthesis ")", returns true if it is
private boolean closeParenthesis(String str) {
if (str == ")") {return true;}
else {return false;}
}
//Checks if input is a double, returns true if it is
//I actually got this method from Stack Overflow, so thanks!
private boolean isDouble(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
//Method used to actually do the calculations. I have
//a feeling this is where my problem is, but I can't
//think of a way to fix it.
private double calc(double a, double b) {
String op = myQueue.dequeue();
if (op == "+") {return a+b;}
else if (op == "-") {return a-b;}
else if (op == "*") {return a*b;}
else if (op == "/") {return a/b;}
else if (op == "^") {return Math.pow(a, b);}
else {throw new UnknownElementException(null, "ERROR");}
}
}
Sorry for the weird indentation. Any help would be greatly appreciated!
There is an algorithm named Shunting-yard which specifies how to convert infix notation to post fix notation (also referred to as "Reverse Polish Notation"). Then you won't have to worry about operator precedence.
It uses a queue and a stack. Basically when you encounter a digit you add it to the queue. And when you encounter operators you push them on to the stack.
You can find the detailed algorithm here : Shunting-Yard Algorithm
Once in reverse polish notation you can easily evaluate it like described here :
Postfix evaluation algorithm
I finally figured it out! I was using == instead of .equals() to compare the strings in my isOperator, closeParenthesis, and openParenthesis methods.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I'm brand-spanking new to Java and I made this little translator for PigLatin.
package stringmanipulation;
public class PigLatinConverter {
public String Convert(String word){
int position = 0;
if (!IsVowel(word.charAt(0))) {
for (int i= 0; i < word.length(); i++) {
if (IsVowel(word.charAt(i))) {
position = i;
break;
}
}
String first = word.substring(position, word.length());
String second = word.substring(0, position) + "ay";
return first + second;
} else {
return word + "way";
}
}
public boolean IsVowel(char c){
if (c == 'a')
return true;
else if(c == 'e')
return true;
else if(c == 'i')
return true;
else if(c == 'o')
return true;
else if(c == 'u')
return true;
else
return false;
}
}
Are there any improvements I can make?
Are there any nifty Java tricks that are in the newest Java version I might not be aware of? I come from a C# background.
Thank you!
I'd rewrite isVowel(char ch) as follows:
return "aeiou".indexOf(ch) != -1;
And I'd write the following instead:
// String first = word.substring(position, word.length());
String first = word.substring(position);
I'd also rename method names to follow coding convention.
And of course, being me, I'd also use regex instead of substring and for loop.
System.out.println("string".replaceAll("([^aeiou]+)(.*)", "$2$1ay"));
// ingstray
References
Java Coding Convention - Naming Convention
Disclaimer: I don't know Java.
Inverted logic is confusing please write your if statement as such:
if (IsVowel(word.charAt(0))) {
return word + "way";
} else {
for (int i= 0; i < word.length(); i++) {
// ...
return first + second;
}
You can even drop the else.
IsVowel may need to be private. It can also be rewritten using a single || chain, or as a "".indexOf (or whatever it is in Java).
Your for logic can be simplified int a short while:
while (position < word.length() && !IsVowel(word.charAt(position)) {
++position;
}
Here's a complete rewrite that makes the code more readable if you know how to read regex:
String[] words =
"nix scram stupid beast dough happy question another if".split(" ");
for (String word : words) {
System.out.printf("%s -> %s%n", word,
("w" + word).replaceAll(
"w(qu|[^aeiou]+|(?<=(w)))([a-z]*)",
"$3-$1$2ay"
)
);
}
This prints (as seen on ideone.com):
nix -> ix-nay
scram -> am-scray
stupid -> upid-stay
beast -> east-bay
dough -> ough-day
happy -> appy-hay
question -> estion-quay
another -> another-way
if -> if-way
Note that question becomes estion-quay, which is the correct translation according to Wikipedia article. In fact, the above words and translations are taken from the article.
The way the regex work is as follows:
First, all words are prefixed with w just in case it's needed
Then, skipping that w, look for either qu or a non-empty sequence of consonants. If neither can be found, then the actual word starts with a vowel, so grab the w using capturing lookbehind
Then just rearrange the components to get the translation
That is:
"skip" dummy w
|
w(qu|[^aeiou]+|(?<=(w)))([a-z]*) --> $3-$1$2ay
\ 2\_/ /\______/
\_________1_________/ 3
References
regular-expressions.info
Character class:[…], Alternation: |, Repetition:+,*, Lookaround:(?<=…), and Capturing:(…)
I know this question is well over a year old, but I thought I would put my modification of it. There are several improvements in this code.
public String convert(String word)
{
int position = 0;
while(!isVowel(word.charAt(position)))
{
++position;
}
if(position == 0)
{
return word + "-way";
}
else if(word.charAt(0) == 'q')
{
++position;
}
return word.substring(position) + "-" + word.substring(0, position) + "ay";
}
public boolean isVowel(char character)
{
switch(character)
{
case 'a': case 'e': case 'i': case 'o': case 'u':
return true;
default:
return false;
}
}
First the code will find the position of the first vowel, and then jump out of the loop. This is simpler than using a for loop to iterate through each letter and using break; to jump out of the loop. Secondly, this will match all the testcases on the Wikipedia site. Lastly, since chars are actually a limited range int, a switch statement can be used to improve performance and readability.
Not strictly an improvement as such, but Java convention dictates that methods should start with a lowercase letter.
I'm years removed from Java, but overall, your code looks fine. If you wanted to be nitpicky, here are some comments:
Add comments. It doesn't have to follow the Javadoc specification, but at least explicitly describe the accepted argument and the expected return value and perhaps give some hint as to how it works (behaving differently depending on whether the first character is a vowel)
You might want to catch IndexOutOfBoundsException, which I think might happen if you pass it a zero length string.
Method names should be lower case.
IsVowel can be rewritten return c == 'a' || c == 'e' and so on. Due to short-circuiting, the performance in terms of number of comparisons should be similar.
Is this homework? If so, tag it as such.
Unclear what expected behaviour is for "honest" or "ytterbium".
It doesn't respect capitals ("Foo" should turn into "Oofay", and AEIOU are also vowels).
It crashes if you pass in the empty string.