I am currently working on a code that requires me to use the String Tokenizer method in order to evaluate expressions. This is fine as I understand how to use them, but in order to add the new value to the string and delete the two calculated values (because the method must be recursive), I wanted to use the String.replace() method. However, I cannot figure out how to find the substring of the two tokens, I tried it this way:
for(int j=0; j<expr.length(); j++)
{
int firstSub = 0;
int secondSub = 0;
int sign = j;
if(expr.charAt(j)=='*')
{
while(j != '/' || j!='+' || j!='-')
{
j--;
}
firstSub = j+1;
while(sign != '/' || j!='+' || j!='-')
{
sign++;
}
secondSub = sign-1;
}
}
which unfortunately did not work. Is there anyway to find the substring of two tokens?
There are (at least) 2 bugs:
Bug 1) Use charAt():
while(exp.charAt(j) != '/' && exp.charAt(j)!='+' && exp.charAt(j)!='-')
Bug 2) Use &&
Note both charAt() and change in logic from || to &&; with || the condition is always true.
You'll need to apply the same change to the next if.
Related
I have an if statement like this
if(areEqual(a,ax) && areEqual(b,bx) && areEqual(c,cx) && areEqual(d,dx) && areEqual(e,ex) && areEqual(f,fx) && areEqual(g,gx) && areEqual(h,hx) && areEqual(i,ix) && areEqual(j,jx) && areEqual(k,kx)
This if the statement includes lots of conditions and it is not readable. How can I avoid this situation? Is there any pipeline pattern for if conditions?
Assuming you are using Python, you can store all check in a list(say list1) and check
if sum(list1)==len(list1):
do something
In javascript, if you add true and true together you get 2. Using this information you could put all the conditions in an array and get the sum of it.
var conditions = [condition1, condition2, ... ]; -- all conditions go here
var sum = 0; -- works out the sum
for (var i = 0; i < conditions.length; i++) {
sum += conditions[i];
}
if (sum === conditions.length) {
console.log("success")
}
So im working on java codingbat and this is the question:
Given a string, look for a mirror image (backwards) string at both the beginning and end of the given string.
In other words, zero or more characters at the very begining of the given string, and at the very end of the string in reverse order (possibly overlapping).
For example:
the string "abXYZba" has the mirror end "ab". mirrorEnds("abXYZba") → "ab" mirrorEnds("abca") → "a" mirrorEnds("aba") → "aba" .
My code passed all the test except for the other test, which is not specified. I dont know what's wrong with it.
public String mirrorEnds(String string) {
String input = string, mirror = "";
int length = string.length();
for (int n = 0; n < (length+1) / 2; n++) {
if (input.charAt(n) != input.charAt(length - n - 1)) {
break;
}else if(length%2 == 1 && n == (length - 1)/2){
// System.out.println("length/2 = " );
return input;
}
else {
mirror += input.charAt(n);
}
}
return mirror;
}
You were correct in not needing to go though the entire word, but your logic is more complex than it needs to be, making it harder to find and fix the problem. The root cause of the test failure is in the last return statement. It must return string if the loop completes without breaking. You can fix your code by changing break; to return mirror; and changing the last return mirror; to return input;
The test that is failing is one like this:
mirrorEnds("abba") -> "abba"
A much simpler version of your code can be created like this:
public String mirrorEnds(String string) {
int len = string.length();
for (int i=0; i < len/2; ++i)
if (string.charAt(i) != string.charAt(len - 1 - i))
return string.substring(0, i);
return string;
}
mirrorEnds("abba")?
Anyways, I'm sure you could come up with a better question name than "some weird stuff"...
Since you are dividing n by 2 in your loop termination condition, it will end when halfway through the word. This is enough to tell the word is a palindrome, but not enough to build your output correctly. You have a condition handling palindrome with odd numbers of letter, but not even numbers of letters. I believe the failing test will be of the form "abba", where I believe what you have will return "ab", instead of "abba".
If you change you loop to:
for (int n = 0; n < length; n++) {
I believe it should be doing what you want. This also makes the short circuit case unnecessary, so:
for (int n = 0; n < length; n++) {
if (input.charAt(n) != input.charAt(length - n - 1)) {
break;
}
else {
mirror += input.charAt(n);
}
}
The first test I tried was with the string "abba" which fails. It returns ab, and not abba. As femtoRgon mentioned, you're not going through the entire word, which may some times be necessary. femtoRgon's solution works, as well as taking a slightly different approach to iterating through the word as follows:
public String mirrorEnds(String string) {
boolean matches = true;
StringBuilder mirrorEnd = new StringBuilder();
int index = 0;
while (matches && index < string.length()) {
if (string.charAt(index) == string.charAt(string.length() - index - 1))
mirrorEnd.append(string.charAt(index));
else
matches = false;
index++;
}
return mirrorEnd.toString();
}
public String mirrorEnds(String string) {
String comp="";
for(int i=0; i<string.length(); i++){
if(string.charAt(i)==string.charAt(string.length()-(i+1)))
comp= comp+ string.charAt(i);
else break;
}
return comp;
}
I'm trying to remove things like "I." "II." "279" (page numbers and chapters) etc from a text file of the story "robin hood". So far I cant figure out how to get rid of the numbers (the arraylist is a string)
for (int x = 0; x < list.size(); x++) {
if (list.get(x).equalsIgnoreCase("I.") || list.get(x).equalsIgnoreCase("II.") || list.get(x).equalsIgnoreCase("III.") || list.get(x).equals("IV.") || list.get(x).equals("V.") || list.get(x).equalsIgnoreCase("VI.") || list.get(x).equalsIgnoreCase("VII.") || list.get(x).equalsIgnoreCase("VIII.") || list.get(x).equals("IX.") || list.get(x).equals("X.") || list.get(x).equals("XI.") || list.get(x).equalsIgnoreCase("XII.") || list.get(x).equalsIgnoreCase("XIII.") || list.get(x).equalsIgnoreCase("XIV.") || list.get(x).equalsIgnoreCase("XV.") || list.get(x).equalsIgnoreCase("XVI.") || list.get(x).equalsIgnoreCase("XVII.") || list.get(x).equalsIgnoreCase("XVIII.") || list.get(x).equalsIgnoreCase("XIX.") || list.get(x).equalsIgnoreCase("XX.") || list.get(x).equalsIgnoreCase("XXI.")) {
list.remove(x);
numWords--;
}
for (int y = 0; y < 9; y++) {
if (list.get(x) == y) {
list.remove(x);
numWords--;
}
}
}
I'm aware there's an error where I'm looking to see if y == list.get(x) but I cant really think of another way to remove a number.
Instead of having that massive if statement you could perhaps do something like
if (list.get(x).toUpperCase().matches("[IVXLCDM]+\\.")) {...}
[IVXLCDM] matches either I, V .. M - so [IVXLCDM]+ matches any continuous string of these characters. The \. ensures that the string is ended with a period.
Now if you wanted to match numbers you could use the regular expression "\\d+", and apply the same idea as above.
You need to use regular expressions to find out lines that match numbers or roman numerals.
The regex (short for regular expression) you need is probably something like:
^([0-9]+)|([IVXLCM]+)\\.?$
to check both arabic and roman numerals.
Here's a tutorial on regular expressions, which gives you a sample application to try out regexes, and explains the syntax.
I'm having an issue comparing a character in Java. I'm trying to find a valid binary number, so I'm passing a string with the binary digits into a function and making sure they're either 0's or 1's. I loop through and check each character in the string, however, my function is telling me that it's bad (even when I know I've given it a proper binary number).
Here is the function:
public boolean isValidBinary(String s) {
//First we get the string length
int strLen = s.length();
//Now we loop through each character of the string
for(int x = 0; x < strLen; x++) {
//Assign the character to a variable each loopthrough
char c = s.charAt(x);
//Check if it's either a 0 or a 1
if(c != '0' || c != '1') {
return false;
}
}
//This is reached when all char's have been evaluated as 0 or 1
return true;
}
I have stared at this problem for quite some time and have been unable to figure it out, so any help would be appreciated.
That's a logical error. You meant && instead of ||.
You could use a regular expression for this anyway:
// must contain at least one digit, and only 0 or 1
public boolean isValidBinary(String s)
{
return s.matches("^[01]+$");
}
Rethink the logic in your inner condition: if(c != '0' || c != '1'). You want to use an AND here: if ((c != '0') && (c != '1')). This means that if both the conditions are true, then the input should be considered invalid, i.e,c is an invalid character if it isn't 0 and also isn't 1.
Consider the case where your code is checking a 1 character: it begins with the left side of the test: c != 0. This is true, and since the OR short-circuits, the result of your entire condition is true, and your function returns false, even though the current character being tested, 1, shouldn't invalidate the input.
public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
int j = 0;
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if ((k == f) || (bottom[k].isEmpty()) || (bottom[k].peek().getType() != i)) {
continue;
}
j = 1;
}
if (j == 0) {
bottom[f].push(rows[r].pop());
}
} else if ((!bottom[f].isEmpty()) && (rankTrueFalse(rows[r].peek(), bottom[f].peek())) && (rows[r].peek().getType() == bottom[f].peek().getType())) {
bottom[f].push(rows[r].pop());
}
}
As I'm still learning java I've been putting together some rules for a game, I went through how to do it logically and came up with the above code which works correctly but it looks like a bit of a mess - is there any neater way or a more efficient way of writing this code? any pointers are much appreciated.
I would extract methods to make the code more readable. At first sight I would extract
the for loop, or probably the whole contents of the if block,
the expression from the 2nd long else if
Use descriptive names for your new methods (and for your variables too, for that matter). This makes a huge difference in readability.
I would recommend that you use more descriptive names for your variables. What is r? What is f? I'm guessing that f is some sort of numeric representation of the suit, since you compare it to k, which iterates over four values.
There might be more to say about the code overall, but the first step is to write the code in a self documenting manner.
There are bits of expressions which could be extracted into local variables: rows[r].peek() and bottom[f].peek() being the most obvious ones.
It looks like you are using j as a flag. Booleans are better for that, but you can return early instead of setting the condition that guards the rest of the processing, getting rid of j entirely.
You're double checking that bottom[f].isEmpty()) is false, and can use the already looked up i instead of repeating rows[r].peek().getType()
Both sides of your first condition, if they end up doing the processing, do the same processing, which you can write once:
public void moveRowItemToBottomIfAllowed(int r, int f) {
int i = rows[r].peek().getType();
if (bottom[f].isEmpty()) {
for (int k = 0; k < 4; k++) {
if (k == f) continue;
if (bottom[k].isEmpty()) continue;
if (bottom[k].peek().getType() == i) return;
}
} else {
if (!rankTrueFalse(rows[r].peek(), bottom[f].peek())) return;
if (bottom[f].peek().getType() != i) return;
}
bottom[f].push(rows[r].pop());
}
This code is then structured as a bunch of guards with early exits, followed by the processing.
The guards could then be extracted into their own method, leaving:
public void moveRowItemToBottomIfAllowed(int r, int f) {
if (moveIsAllowed(r,f)) bottom[f].push(rows[r].pop());
}