Java, class, Boolean, logic mess - java

So, we were given to code this ScantronGrader for homework, and the specs say that we have to create this class isValid to check to validity of the options that fall into either A, B, C, or D (all uppercase), I first tried switch (error), if-else-if (error); do-while (Oh, I know so wrong and error). I tried for loop first, and the value didn't get incremented.
In its recent rendition, this is my issue. TBH, I don't even know what I am doing anymore.
public static boolean isValid(String inputstr)
{
int x = 0;
do
{
switch (inputstr.charAt(x))
{
case 'A':
case 'B':
case 'C':
case 'D':
return true;
default: return false;
x++;
}
} while (x < inputstr.length());
}
}
The problem with this is that it is not letting me increment the counter. Now, I need to do that, else, how would I shift right? Either way, please HALP.

Not sure if i understood what that method have to do, but if it has to return true only if the string have those letter you can do this:
public static boolean isValid(String inputstr)
{
int x = 0;
boolean bool = true;
do
{
if(!(inputstr.charAt(x) == 'A' || inputstr.charAt(x) == 'B' || inputstr.charAt(x) == 'C' || inputstr.charAt(x) == 'D'))
{
bool = false;
}
x++;
}while (x < inputstr.length());
return bool;
}

Okay, so after some ideas from here (Thank you for reaching out to help), I am toying with this one which seems to work. Just let me know if I am doing anything unnecessary/ useless, or there is a more efficient way to do this, please?
public static boolean isValid(String inputstr) {
int count = 0;
for (int x = 0; x < inputstr.length(); x++) {
switch (inputstr.charAt(x)) {
case 'A':
case 'B':
case 'C':
case 'D':
break;
default: count++;
}
}
if (count == 0) {
return true;
}
else {
return false;
}
}

Related

Why isn't .equals recognizing my variable as the same string that I'm passing it?

So this little function is supposed to check if parentheses and brackets are matched next to each other. I feel like it should work and I've tried it a few different ways but I can't figure out how to check if my next char is what I expect it to be.
class Parenths {
public boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i+=2) {
String curr= String.valueOf(parens[i]);
String next = String.valueOf(parens[i+1]);
// System.out.println(next.equals(")"); --------> false
// System.out.println(Object.equals(next, ")")); ----> error
switch (curr) {
case "(": if (!next.equals(")")) return false;
case "{": if (!next.equals("}")) return false;
case "[": if (!next.equals("]")) return false;
}
}
return true;
}
}
You can see the lines I printed to debug and it seems that .equals is not the right thing to use here? Can anyone explain why this isn't working?
PS. I realize I don't have to convert the string to a char array to compare elements, so unless that's the only fix, please don't point that out to me.
Not tested, but it seems to be a problem of fall through. Try to replace if (boolean) return boolean with return boolean, this should do the trick.
The problem is that you don't have a break at the end of the cases, so if, for example, your first case is true, it will not stop execution and execute the 2nd test, which will be false. If you change your conditional statements to a direct return, you will not have this problem.
EDIT: Sorry, I read too quickly. Doing so will break your loop. Actually, you have to add a break at the end of the cases.
case "(": if (!next.equals(")")) return false; break;
case "{": if (!next.equals("}")) return false; break;
case "[": if (!next.equals("]")) return false; break;
First , you have to add break; after the cases its important to stop seeing the cases
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
}
Secondly , your code doesnt support the confrotation of a closing patenthesis at first , you have to add a default case
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
Also , you have to make sure the next element is not null before comparing to it , and dont increment with 2 , you give a String with a one element and that's why you get the error
public static boolean isValid(String s) {
char[] parens = s.toCharArray();
if (parens.length == 0) return true;
for (int i = 0; i < parens.length; i++) {
String curr= String.valueOf(parens[i]);
String next = "";
try {
next = String.valueOf(parens[i+1]);
switch (curr) {
case "(": if (!next.equals(")")) return false;
break;
case "{": if (!next.equals("}")) return false;
break;
case "[": if (!next.equals("]")) return false;
break;
default :
break;
}
return true;
}catch(Exception e) {}
}
return false;
}
Test :
System.out.println(isValid("()"));
// Output : true
System.out.println(isValid("("));
// Output : false

Return multiple values from void and boolean methods

I have the following problem: Having a boolean static method that computes similarity between two integers, I am asked to return 4 results:
without changing the return type of the method, it
should stay boolean.
without updating/using the values of external variables and objects
This is what I've done so far (I can't change return value from boolean to something else, such as an int, I must only use boolean):
public static boolean isSimilar(int a, int b) {
int abs=Math.abs(a-b);
if (abs==0) {
return true;
} else if (abs>10) {
return false;
} else if (abs<=5){
//MUST return something else, ie. semi-true
} else {
//MUST return something else, ie. semi-false
}
}
The following is bad practice anyway, but If you can try-catch exceptions you can actually define some extra outputs by convention. For instance:
public static boolean isSimilar(int a, int b) {
int abs = Math.abs(a-b);
if (abs == 0) {
return true;
} else if (abs > 10) {
return false;
} else if (abs <= 5){
int c = a/0; //ArithmeticException: / by zero (your semi-true)
return true;
} else {
Integer d = null;
d.intValue(); //NullPointer Exception (your semi-false)
return false;
}
}
A boolean can have two values (true or false). Period. So if you can't change the return type or any variables outside (which would be bad practice anyway), it's not possible to do what you want.
Does adding a parameter to the function violate rule 2? If not, this might be a possible solution:
public static boolean isSimilar(int a, int b, int condition) {
int abs = Math.abs(a - b);
switch (condition) {
case 1:
if (abs == 0) {
return true; // true
}
case 2:
if (abs > 10) {
return true; // false
}
case 3:
if (abs <= 5 && abs != 0) {
return true; // semi-true
}
case 4:
if (abs > 5 && abs <= 10) {
return true; // semi-false
}
default:
return false;
}
}
By calling the function 4 times (using condition = 1, 2, 3 and 4), we can check for the 4 results (only one would return true, other 3 would return false).

Switch Statement: Execute Code Once

If I have a switch statement testing the value of integer i, how can I execute the same code once?
For example:
switch(i) {
case 0:
if(j == 2) {
booleanA = true;
booleanB = false;
case 1:
if(j == 4) {
booleanA = true;
booleanB = false;
}
With 5 different cases, instead of me having to type out
booleanA = true;
booleanB = false;
five times, is there a way to say if one of the if statements is true, use this block of code? Is that possible?
Thanks!
You can do it without a switch statement...
int[] requiredJ = {2,4};
if (j == requiredJ[i]) {
booleanA = true;
booleanB = false;
}
I can not understand logic behind your code, but may be this can be done ( Like switch hit in cricket !!! :p).
Assign the values to your booleans, and revert in default case.
booleanA = true;
booleanB = false;
// more code blocks
switch(i) {
case 0:
// Process
break;
case 1:
// Process
break;
default :
booleanA = false;
booleanB = true;
}

Code does not work as intended (Palindrome checker)

I am trying to check if a string is a palindrome, but it seems it does not work, because when I send a string that I know is not a palindrome, it returns that it is a palindrome, can anyone help? It also won't add to the variable counter.
package UnaryStack.RubCol1183;
public class CheckPalindrome {
static int counter = 0;
/** Decides whether the parentheses, brackets, and braces
in a string occur in left/right pairs.
#param expression a string to be checked
#return true if the delimiters are paired correctly */
public static boolean checkBalance(String expression)
{
StackInterface<Character> temporaryStack = new LinkedStack<Character>();
StackInterface<Character> reverseStack = new LinkedStack<Character>();
StackInterface<Character> originalStack = new LinkedStack<Character>();
int characterCount = expression.length();
boolean isBalanced = true;
int index = 0;
char nextCharacter = ' ';
for (;(index < characterCount); index++)
{
nextCharacter = expression.charAt(index);
switch (nextCharacter)
{
case '.': case '?': case '!': case '\'': case ' ': case ',':
break;
default:
{
{
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
originalStack.push(temporaryStack.pop());
}
{
char letter1 = Character.toLowerCase(originalStack.pop());
char letter2 = Character.toLowerCase(reverseStack.pop());
isBalanced = isPaired(letter1, letter2);
if(isBalanced == false){
counter++;
}
}
break;
}
} // end switch
} // end for
return isBalanced;
} // end checkBalance
// Returns true if the given characters, open and close, form a pair
// of parentheses, brackets, or braces.
private static boolean isPaired(char open, char close)
{
return (open == close);
} // end isPaired
public static int counter(){
return counter;
}
}//end class
Your implementation seems way more complex than it needs to be.
//Check for invalid characters first if needed.
StackInterface<Character> stack = new LinkedStack<Character>();
for (char ch: expression.toCharArray()) {
Character curr = new Character(ch);
Character peek = (Character)(stack.peek());
if(!stack.isEmpty() && peek.equals(curr)) {
stack.pop();
} else {
stack.push(curr)
}
}
return stack.isEmpty();
Honestly using a stack is over kill here. I would use the following method.
int i = 0;
int j = expression.length() - 1;
while(j > i) {
if(expression.charAt(i++) != expression.charAt(j--)) return false;
}
return true;
You put exaclty the same elemets in reverseStack and originalStack, because everything you push into the temporaryStack will be immediately pushed into originalStack. This does not make sense.
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
originalStack.push(temporaryStack.pop());
Therefore the expression
isBalanced = isPaired(letter1, letter2);
will always return true.
I found the errors in logic that were found inside the method checkBalace() and finished the code into a full working one. Here is what my finished code looks like:
public class CheckPalindrome {
static int counter;
/** Decides whether the parentheses, brackets, and braces
in a string occur in left/right pairs.
#param expression a string to be checked
#return true if the delimiters are paired correctly */
public static boolean checkBalance(String expression)
{
counter = 0;
StackInterface<Character> temporaryStack = new LinkedStack<Character>();
StackInterface<Character> reverseStack = new LinkedStack<Character>();
StackInterface<Character> originalStack = new LinkedStack<Character>();
boolean isBalanced = true;
int characterCount = expression.length();
int index = 0;
char nextCharacter = ' ';
for (;(index < characterCount); index++)
{
nextCharacter = expression.charAt(index);
switch (nextCharacter)
{
case '.': case '?': case '!': case '\'': case ' ': case ',':
break;
default:
{
{
reverseStack.push(nextCharacter);
temporaryStack.push(nextCharacter);
}
break;
}
} // end switch
} // end for
while(!temporaryStack.isEmpty()){
originalStack.push(temporaryStack.pop());
}
while(!originalStack.isEmpty()){
char letter1 = Character.toLowerCase(originalStack.pop());
char letter2 = Character.toLowerCase(reverseStack.pop());
isBalanced = isPaired(letter1, letter2);
if(isBalanced == false){
counter++;
}
}
return isBalanced;
} // end checkBalance
// Returns true if the given characters, open and close, form a pair
// of parentheses, brackets, or braces.
private static boolean isPaired(char open, char close)
{
return (open == close);
} // end isPaired
public static int counter(){
return counter;
}
}
I used 2 while methods outside of the for thus fixing the logic errors pointed out. I also assigned the value 0 to counter inside the method to fix a small problem I encountered. Feel free to revise the code if I still have errors, but I think I made no errors, then again, I'm a beginner.

Improve Java code: too many if's

I have several cases and I am just using simple if ... if else blocks.
How can I reduce the number of if statements in this code?
Perhaps I could use a lookup table, but I am not sure how to implement it in Java.
private int transition(char current, int state)
{
if(state == 0)
{
if(current == 'b')
{
return 1;
}
else
return 0;
}
if(state == 1)
{
if(current == 'a')
{
return 2;
}
else
return 0;
}
if(state == 2)
{
if(current == 's')
{
return 3;
}
else
return 0;
}
if(state == 3)
{
if(current == 'e')
{
return 3;
}
if(current == 'b')
{
return 4;
}
else
return 0;
}
if(state == 4)
{
if(current == 'a')
{
return 5;
}
else
return 0;
}
if(state == 5)
{
if(current == 'l')
{
return 6;
}
else
return 0;
}
else
return 0;
}
What you're trying to do looks very much like a finite state machine, and these are usually implemented with the help of a transition table. Once you set up the table, it's simply a matter of indexing to the position you want to get the return value. Assuming your return values are all less than 256, you can use a 2D byte array:
byte table[][] = new byte[NUM_STATES][NUM_CHARACTERS];
// Populate the non-zero entries of the table
table[0]['b'] = 1;
table[1]['a'] = 2;
// etc...
private int transition(char current, int state) {
return table[state][current];
}
Well, you can easily utilize hash. Simple and clean.
// declare hashtable
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("0-b", 1);
map.put("1-a", 2);
map.put("2-s", 3);
...
// get result
Integer result = map.get(state + "-" + current);
// change null (nothing found) to zero
return result == null ? 0 : result;
consider interfaces + enums:
interface State<T>
{
public void State<T> step(T input);
}
enum MyState implements State<Character> {
STATE0(0) { #Override public void MyState step(Character c) { return c == 'b' ? STATE1 : STATE0; }},
STATE1(1) { #Override public void MyState step(Character c) { return c == 'a' ? STATE2 : STATE0; }},
/* rest of states here */
final private int value;
MyState(int value) { this.value = value; }
public int getValue() { return this.value; }
}
class SomeClass
{
public MyState currentState = STATE0;
public void step(char input)
{
this.currentState = this.currentState.step(input);
}
}
i switch statement would be best here:
private int transition(char current, int state)
{
switch(state)
{
case 0:
return current == 'b' ? 1 : 0;
case 1:
return current == 'a' ? 2 : 0;
case 2:
return current == 's' ? 3 : 0;
case 3:
return current == 'e' ? 3 : (current == 'b' ? 4 : 0);
case 4:
return current == 'a' ? 5 : 0;
case 5:
return current == 'l' ? 6 : 0;
default:
return 0;
}
}
And a note, theres only 5 if statements there checking pure intergers, this is not exactly an overhead.
Looks like you need a better abstraction for a finite state machine. Think about a class that encapsulates what you want in a better way so you can extend it by configuration rather than modifying code.
If this code is about to be expanded over the time, why not use a state machine? Each state will return the next state based on the character it receives. Maybe it's an overkill for this code, but it'll be a lot easier to maintain, expand & read.
Use switch statement for the outer if chain:
switch (state) {
case 0: <code> ; break;
case 1: <code> ; break;
case 2: <code> ; break;
<etc>
default: return 0; break;
}

Categories

Resources