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.
Related
I'm working on the following problem from CodingBat
withoutX
Given a string, if the first or last chars are 'x', return the string
without those 'x' chars, and otherwise return the string unchanged.
Examples:
withoutX("xHix") → "Hi"
withoutX("xHi") → "Hi"
withoutX("Hxix") → "Hxi"
I am still getting the last char of 'x' in my code when it has an x in the first and last index. I tried it several different ways but still getting the same result. What am I missing?
So currently my tests are not passing when the first & last chars are 'x'. It's supposed to remove the 'x' at the 0 and last index when the conditions are met, but only removes the first 'x' at index 0 (not the last).
public String withoutX(String str) {
if(str.length() > 0 && str.charAt(0) == 'x'){
return str.substring(1,str.length());
}
if(str.length() > 0 && str.charAt(str.length()-1) == 'x'){
return str.substring(0,str.length()-1);
}
return str;
}
I also tried it this way as well and get those tests to pass but here I get a StringIndexOutofBoundsException:
string index out of range: -1 (line:3)
I failed to find out the reason of this exception.
public String withoutX(String str) {
if(str.length() > 0 && str.substring(0).startsWith("x") &&
str.substring(str.length()-1).endsWith("x")){
return str.substring(1,str.length()-1);
}
if(str.length() > 0 && str.substring(0).startsWith("x")){
return str.substring(1,str.length());
}
if(str.length() > 0 && str.substring(str.length()-1).endsWith("x")){
return str.substring(0, str.length()-1);
}
return str;
}
Any explanations for these issues would be appreciated.
Mistakes explained
Your first attempt fails because the first condition would match two cases: when either the stating character or both and the stating the ending characters are equal to x. But it checks only the first case and immediately returns, which causes incorrect results.
if(str.length() > 0 && str.charAt(0) == 'x'){
return str.substring(1,str.length());
}
The second attempt looks better.
You've omitted the case when the given string contains only a single character, and this character is x. Then condition below would be evaluated to true:
if(str.length() > 0 && str.substring(0).startsWith("x") &&
str.substring(str.length() - 1).endsWith("x")) {
return str.substring(1, str.length() - 1);
}
And in this case substring(1, str.length() - 1) means substring(1, 0) because length in 1, which triggers an IndexOutOfBoundsException exactly as expected according to documentation of the String.substring():
IndexOutOfBoundsException – if the beginIndex is negative, or endIndex
is larger than the length of this String object, or beginIndex is
larger than endIndex.
Also note that str.substring(0).startsWith("x") is equivalent of str.startsWith("x"), generating substring is redundant. Similarly, str.substring(str.length() - 1).endsWith("x") does exactly the same as str.endsWith("x").
Valid Solution
Basically, you need to address four cases:
The stating and the ending characters are equal to x, the result should be str.substring(1, str.length() - 1).
Only the stating character is equal to x, the expected result would be str.substring(1).
Only the last character is equal to x, the result would be str.substring(0, str.length() - 1).
If the given string is doesn't contain x (it also imply that it could be empty), return it without changes.
We can simply apply these conditions in the order list above:
public String withoutX(String str) {
if (str.startsWith("x") && str.endsWith("x") && str.length() != 1) return str.substring(1, str.length() - 1);
if (str.startsWith("x")) return str.substring(1);
if (str.endsWith("x")) return str.substring(0, str.length() - 1);
return str;
}
This solution passes all test cases on Coding Bat.
It also can be done with fewer conditions by eliminating the leading x and then trailing x. But it would potentially require generating the substring twice, which is less performant than the first approach.
public String withoutX(String str) {
if (str.startsWith("x")) str = str.substring(1);
if (str.endsWith("x")) str = str.substring(0, str.length() - 1);
return str;
}
This solution also passes all test cases on Coding Bat.
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.
For a class project, I need to fix up some code to make it function, with the goal of creating a method that takes two inputs, two strings. If 'keyword' is embedded within another word in 's', or not present, it returns -1, otherwise it returns the index of the first instance of 'keyword' within 's' that is not embedded in another word.
However, every time I run the code, I'm getting an infinite loop error. I've realized the removing the '!' from line 30 allows the code to run, but outputs an entirely wrong answer for every occurrence. Does anyone know why I'm getting this infinite loop error, or how to make this code function. Thanks!
public static int indexOfKeyword(String s, String keyword) {
// Change both s and keyword to lower case
s = s.toLowerCase();
keyword = keyword.toLowerCase();
// The index of the first occurrence (perhaps embedded) of keyword in s
int startIdx = s.indexOf(keyword);
// Check if this occurrence is embedded and look further down s if it is
while (startIdx >= 0) {
// Find the substrings of length 1 immediately before and after
// this occurrence. Default to the string " " containing only a space.
String before = " ", after = " ";
if (startIdx > 0) {
before = s.substring(s.indexOf(keyword));
}
int endIdx = s.indexOf(keyword) + keyword.length();
if (endIdx < s.length()) {
after = s.substring(endIdx);
}
// If before and after aren't letters, this is the first whole word occurrence
if (!((before.compareTo("a") >= 0 && before.compareTo("z") <= 0) &&
(after.compareTo("a") >= 0 && after.compareTo("z") <= 0.))) {
return startIdx;
}
// This is not a whole word occurrence. Move to the next occurrence.
startIdx = s.indexOf(keyword, endIdx);
}
return -1;
}
Your way of finding before and after are pretty funky, aren't you only supposed to find the single character before and after the keyword? Because right now you're setting multiple characters as the before and after. Something like this should work.
before = s.charAt(s.indexOf(keyword)-1);
after = s.charAt(endIdx)+1;
Then to check if before and after are spaces
if(before == ' ' && after == ' '){
//the keyword is not embedded
}
If i'm not mistaken, before is supposed to find the character before the occurrence, yet your finding the substring from the index of where you occurrence starts?
Also i believe your endIdx variable has an off by 1 error, should be startIdx + keyword.length - 1
First, the before should be:
before = s.substring(startIdx - 1, startIdx);
And the if should be:
// If before and after aren't letters, this is the first whole word occurrence
if ((!(before.compareTo("a") >= 0 && before.compareTo("z") <= 0) && !(after.compareTo("a") >= 0 && after.compareTo("z") <= 0))) {
return startIdx;
}
Full Code:
public static int indexOfKeyword(String s, String keyword) {
// Change both s and keyword to lower case
s = s.toLowerCase();
keyword = keyword.toLowerCase();
// The index of the first occurrence (perhaps embedded) of keyword in s
int startIdx = s.indexOf(keyword);
// Check if this occurrence is embedded and look further down s if it is
while (startIdx >= 0) {
// Find the substrings of length 1 immediately before and after
// this occurrence. Default to the string " " containing only a space.
String before = " ", after = " ";
if (startIdx > 0) {
before = s.substring(startIdx - 1, startIdx);
}
int endIdx = s.indexOf(keyword) + keyword.length();
if (endIdx < s.length()) {
after = s.substring(endIdx);
}
// If before and after aren't letters, this is the first whole word occurrence
if ((!(before.compareTo("a") >= 0 && before.compareTo("z") <= 0) && !(after.compareTo("a") >= 0 && after
.compareTo("z") <= 0))) {
return startIdx;
}
// This is not a whole word occurrence. Move to the next occurrence.
startIdx = s.indexOf(keyword, endIdx);
}
return -1;
}
Im trying to write a method that takes in an ID of the form "xxxx-xxxx" (x being any number 1-9) and checks to see if the ID entered is valid. For example, 1111-1111 would be valid, but 111p-1111 or 11111-1111 would not be. However, after I have written this method, it comes out as true even when the ID is of the form 111p-1111.
public static boolean idCheck(String ID){
char[] idChar = ID.toCharArray();
boolean firstHalf = false;
boolean secHalf = false;
for (int i = 0; i < 5; ++i){//Check first half
if ((idChar[i] > 47 && idChar[i] < 58)){//Checks ascii vals to see if valid ID
firstHalf = true;
}
}
for (int i = 5; i < idChar.length; ++i){//Check second half
if ((idChar[i] > 47 && idChar[i] < 58)){//Checks ascii vals to see if valid ID
secHalf = true;
}
}
//If all values are valid, returns true.
if (firstHalf == true && secHalf == true && idChar[4] == '-' && ID.length() == 9){
return true;
}
return false;
}
Using a regular expression would be much simpler in this case:
\d{4}-\d{4}
In Java:
static boolean idCheck(String id) {
return id.matches("\\d{4}-\\d{4}");
}
If you're unfamiliar with regular expressions, here's an explanation:
\d Match a digit 0-9
{4} Repeat last token 4 times (matches 4 digits)
- Match a hyphen literally
\d Match a digit 0-9
{4} Repeat last token 4 times (matches 4 digits)
Your if statements only look at one number to determine if it sets the boolean to true. So if any of the numbers in each half are valid, the boolean will be set to true.
You are probably better off using regular expressions. regexr.com is a great resource to get started! :)
Something like:
[1-9]{4}-[1-9]{4} (You can also use \d)
You only check if there is at least one character that matches, not if any of the input characters are failing.
To have a quick solution that is easy to understand for any Java developer after you you could use a Regex and check if your input matches:
public static boolean idCheck(String id){
return Pattern.matches("\\d{4}-\\d{4}", id);
}
If you want to keep your way of checking you should start with true booleans and check if they stay true.
boolean firstHalf = true;
boolean secHalf = true;
and therefrom use firstHalf &= true for your updates and use a else{ firstHalf = false; } branch.
To keep your method I would prefer to always back out fast if you know the result:
public static boolean idCheck(String id)
{
//check length
if (id.length() != 9)
return false;
char[] idChar = id.toCharArray();
//check for dash
if (idChar[4] != '-')
return false;
//check first half
for (int i = 0; i < 5; ++i)
{
if (!(idChar[i] > 47 && idChar[i] < 58))
return false;
}
//check second half
for (int i = 5; i <= 10; ++i)
{
if (!(idChar[i] > 47 && idChar[i] < 58))
return false;
}
}
I have troubles in one method. In input we have string, for example (a+-b*i)some sign(c+-d*i). Program must calculate this and output result. I need to take index of sign in the first bracket and index in the second bracket. And than my program will be working. But, when in input (a-b*i)-(c-d*i) or (a-b*i)*(c-d*i) only, method returning wrong result -1.
My methods for two brackets.
public int getSign1(String str)
{
int sign1;
if(str.indexOf("+") < str.indexOf(")"))
sign1 = str.indexOf("+");
else if(str.indexOf("-", 2) < str.indexOf(")"))
sign1 = str.indexOf("-", 2);
else sign1 = -1;
return sign1;
}
public int getSign2(String str)
{
int sign2;
if(str.lastIndexOf("+") > str.lastIndexOf("("))
sign2 = str.lastIndexOf("+");
else if(str.lastIndexOf("-") > str.lastIndexOf("("))
sign2 = str.lastIndexOf("-");
else sign2 = -1;
return sign2;
}
The second method always working, but not the first (Please help me to find error).
Example: (1-2i)*(3-4i)
The first method is returning -1, but not 2. Why?
This happens because in the expression:
(1-2i)*(3-4i) you don't have any + char, and after seeing String#lastIndexOf:
the index of the last occurrence of the character in the character
sequence represented by this object, or -1 if the character does not
occur.
Then you know why str.lastIndexOf("+") will be -1. And it's of course < str.indexOf(")").
So sign1 will be -1.
You can fix it by:
if(str.indexOf("+")!= -1 && str.indexOf("+") < str.indexOf(")"))
For input (a-b*i)-(c-d*i) , here there is no '+' in this string.
public int getSign1(String str){
if(str.indexOf("+") < str.indexOf(")"))
sign1 = str.indexOf("+");
..
}
In this method first if you are checking '+' , hence it is not there its index is -1 which is less than str.indexOf(")") index so its returing -1.