check if char[] contains only one letter and one int - java

I have no idea how to check if char[] contains only one letter (a or b) on the first position and only one int (0-8) on the second position. for example a2, b2
I have some this, but I do not know, what should be instead of digital +=1;
private boolean isStringValidFormat(String s) {
boolean ret = false;
if (s == null) return false;
int digitCounter = 0;
char first = s.charAt(0);
char second = s.charAt(1);
if (first == 'a' || first == 'b') {
if (second >= 0 && second <= '8') {
digitCounter +=1;
}
}
ret = digitCounter == 2; //only two position
return ret;
}
` public char[] readFormat() {
char[] ret = null;
while (ret == null) {
String s = this.readString();
if (isStringValidFormat(s)) {
ret = s.toCharArray();
}else {
System.out.println("Incorrect. Values must be between 'a0 - a8' and 'b0 - b8'");
}
}
return new char[0];
}`

First, I would test for null and that there are two characters in the String. Then you can use a simple boolean check to test if first is a or b and the second is between 0 and 8 inclusive. Like,
private boolean isStringValidFormat(String s) {
if (s == null || s.length() != 2) {
return false;
}
char first = s.charAt(0);
char second = s.charAt(1);
return (first == 'a' || first == 'b') && (second >= '0' && second <= '8');
}

For a well understood pattern, use Regex:
private static final Pattern pattern = Pattern.compile("^[ab][0-8]$")
public boolean isStringValidFormat(String input) {
if (input != null) {
return pattern.matcher(input).matches();
}
return false;
}

Related

Why does this method always return false?

I would like to evaluate a phone number using the provided method. The phone number should always have a length of 10. However the following method always seems to return false. Why is that? Thanks.
public static boolean valPhoneNumber(String phonenumber){
boolean result= true;
if (phonenumber.length() > 10 || phonenumber.length() < 10){
result= false;
}else
phonenumber.length();
char a=phonenumber.charAt(0);
char b=phonenumber.charAt(1);
char d=phonenumber.charAt(3);
char e=phonenumber.charAt(4);
char f=phonenumber.charAt(5);
if (a<2 || a>9){
result = false;
}else if( b<0 || b>8){
result = false;
}else if (d<2 || d>9){
result = false;
}else if (e==1 && f==1){
result = false;
}
return result;
}
So looking into your ladder which is comparing character to number. In this case the comparison will happen with ASCII value.
You can put single quotes to check the range:
if (a < '2' || a > '9') {
result = false;
} else if( b < '0' || b > '8') {
result = false;
} else if (d < '2' || d > '9') {
result = false;
} else if (e == '1' && f == '1') {
result = false;
}
One liner:
result = !((a < '2' || a > '9') || (b < '0' || b > '8') || (d < '2' || d > '9') || (e == '1' && f == '1'));
I think your code wrong at the parsing phonenumber.charAt(). This always return char, and when you do comparision with integer it will convert to number which present to that char code (ASCII code). I think you should modify your code to int a=Character.getNumericValue(phonenumber.charAt(0)); and so on
I think an approach with regex here would be the cleanest and easiest solution.
public static boolean valPhoneNumber(String phonenumber){
String regex = "[2-9][0-8][0-9][2-9][02-9][0-29][0-9]{4}";
return phonenumber.matches(regex);
}
You should cast the char variables to integer.
you can try this:
int a = Integer.parseInt(phonenumber.substring(0,1));
I added single quotes to check the range. Thank you all.
public static boolean valPhoneNumber(String phonenumber) {
boolean result= true;
if (phonenumber.length() != 10) {
result = false;
} else {
//phonenumber.length();
char a = phonenumber.charAt(0);
char b = phonenumber.charAt(1);
char d = phonenumber.charAt(3);
char e = phonenumber.charAt(4);
char f = phonenumber.charAt(5);
if (a < '2' || a > '9') {
} else if( b<'0' || b>'8') {
result = false;
} else if (d < '2' || d > '9') {
result = false;
} else if (e == '1' && f == '1') {
result = false;
}
}
return result;
}

Verify if String matches real number

I'm trying to verify if a String s match/is a real number. For that I created this method:
public static boolean Real(String s, int i) {
boolean resp = false;
//
if ( i == s.length() ) {
resp = true;
} else if ( s.charAt(i) >= '0' && s.charAt(i) <= '9' ) {
resp = Real(s, i + 1);
} else {
resp = false;
}
return resp;
}
public static boolean isReal(String s) {
return Real(s, 0);
}
But obviously it works only for round numbers. Can anybody give me a tip on how to do this?
P.S: I can only use s.charAt(int) e length() Java functions.
You could try doing something like this. Added recursive solution as well.
public static void main(String[] args) {
System.out.println(isReal("123.12"));
}
public static boolean isReal(String string) {
boolean delimiterMatched = false;
char delimiter = '.';
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i);
if (!(c >= '0' && c <= '9' || c == delimiter)) {
// contains not number
return false;
}
if (c == delimiter) {
// delimiter matched twice
if (delimiterMatched) {
return false;
}
delimiterMatched = true;
}
}
// if matched delimiter once return true
return delimiterMatched;
}
Recursive solution
public static boolean isRealRecursive(String string) {
return isRealRecursive(string, 0, false);
}
private static boolean isRealRecursive(String string, int position, boolean delimiterMatched) {
char delimiter = '.';
if (position == string.length()) {
return delimiterMatched;
}
char c = string.charAt(position);
if (!(c >= '0' && c <= '9' || c == delimiter)) {
// contains not number
return false;
}
if (c == delimiter) {
// delimiter matched twice
if (delimiterMatched) {
return false;
}
delimiterMatched = true;
}
return isRealRecursive(string, position+1, delimiterMatched);
}
You need to use Regex. The regex to verify that whether a string holds a float number is:
^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$
Can anybody give me a tip on how to do this?
Starting with your existing recursive matcher for whole numbers, modify it and use it in another method to match the whole numbers in:
["+"|"-"]<whole-number>["."[<whole-number>]]
Hint: you will most likely need to change the existing method to return the index of that last character matched rather than just true / false. Think of the best way to encode "no match" in an integer result.
public static boolean isReal(String str) {
boolean real = true;
boolean sawDot = false;
char c;
for(int i = str.length() - 1; 0 <= i && real; i --) {
c = str.charAt(i);
if('-' == c || '+' == c) {
if(0 != i) {
real = false;
}
} else if('.' == c) {
if(!sawDot)
sawDot = true;
else
real = false;
} else {
if('0' > c || '9' < c)
real = false;
}
}
return real;
}

Analyze a string of characters in java for format A^nB^n

I have a string of characters with As and Bs that I need to analyze for a Language A^nB^n. I can use the following code to work most of the time but when there is a letter that is not an "A" or "B" it may still return true, for example: AABACABAA should not be true, but it says it is. AABB is true; AABBAABB is not true. I have to use stacks and am not allowed to use counting.
public static boolean isL2(String line){
// set up empty stacks
Stack L2Stack = new Stack();
// initialize loop counter
int i = 0;
int n = line.length();
/* Push all 'A's to a_stack */
while ((i < line.length()) && (line.charAt(i) == 'A')) {
char ch = line.charAt(i);
L2Stack.push(ch);
i++;
}
/* Pop an 'A' for each consecutive 'B' */
while ((i < line.length()) && (line.charAt(i) == 'B')) {
if (!L2Stack.empty()){
L2Stack.pop();
i++;
}
else
return false;
}
if (i == n && !L2Stack.empty()){
return false; // more As than Bs
}
if (i != n && L2Stack.empty()){
return false; //more Bs than As
}else
return true;
}
if (i != n && L2Stack.empty()) {
return false; //more Bs than As
}
Should be
if (i != n) {
return false;
}
Since if you haven't finished reading all the characters, you can't return true, regardless of whether or not the stack is empty.
I'm assuming that AAABBBA should return false.
That change would also handle illegal characters.

String equation error checker not working

I have a method that checks to see if an equation written is correct.
This method check for:
Multiple Parentheses
Excess operators
Double Digits
q's
and any character in a string that is not and of these:
.
private static final String operators = "-+/*%_";
private static final String operands = "0123456789x";
It was working fine, but then I added in modular to the operators and now whenever my code reaches the part in the method that checks to the left and the right of an operand to see if it is neither the end of the string or the beginning I get an error saying
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
My method and all it's additional methods.
private static final String operators = "-+/*%_";
private static final String operands = "0123456789x";
public Boolean errorChecker(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder out = new StringBuilder();
for (int i = 0; i<chars.length; i++)
{
System.out.print(infixExpr.charAt(i));
if (isOperator(infixExpr.charAt(i)))
{
if (i == 0 || i == infixExpr.length())
{
out.append(infixExpr.charAt(i));
}
else if (isOperator(infixExpr.charAt(i + 1)) && isOperator(infixExpr.charAt(i - 1)))
{
System.out.println("To many Operators.");
return false;
}
else if (isOperator(infixExpr.charAt(i + 1)))
{
if (infixExpr.charAt(i) != '-' || infixExpr.charAt(i + 1) != '-')
{
System.out.println("To many Operators.");
return false;
}
}
else if (isOperator(infixExpr.charAt(i - 1)))
{
if (infixExpr.charAt(i) != '-' || infixExpr.charAt(i - 1) != '-')
{
System.out.println("To many Operators.");
return false;
}
}
}
else if (isOperand(infixExpr.charAt(i)))
{
if (i == 0 || i == infixExpr.length())
{
out.append(infixExpr.charAt(i));
}//THE LINE RIGHT BELOW THIS COMMENT THROWS THE ERROR!!!!!
else if (isOperand(infixExpr.charAt(i + 1)) || isOperand(infixExpr.charAt(i - 1)))
{
System.out.println("Double digits and Postfix form are not accepted.");
return false;
}
}
else if (infixExpr.charAt(i) == 'q')
{
System.out.println("Your meow is now false. Good-bye.");
System.exit(1);
}
else if(infixExpr.charAt(i) == '(' || infixExpr.charAt(i) == ')')
{
int p1 = 0;
int p2 = 0;
for (int p = 0; p<chars.length; p++)
{
if(infixExpr.charAt(p) == '(')
{
p1++;
}
if(infixExpr.charAt(p) == ')')
{
p2++;
}
}
if(p1 != p2)
{
System.out.println("To many parentheses.");
return false;
}
}
else
{
System.out.println("You have entered an invalid character.");
return false;
}
out.append(infixExpr.charAt(i));
}
return true;
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
My main portion that runs the method:
Boolean meow = true;
while(meow)
{
System.out.print("Enter infix expression: ");
infixExpr = scan.next();//THE LINE RIGHT BELOW THIS COMMENT THROWS THE ERROR!!!!!
if(makePostfix.errorChecker(infixExpr) == true)
{
System.out.println("Converted expressions: "
+ makePostfix.convert2Postfix(infixExpr));
meow = false;
}
}
It was working fine before, but now it won't even pass 1+2 which was previously working and I changed NONE of that you see. What's wrong!?!?
What looks like what's happening is that you check for the character at index (i + 1) several times in your code. Lets say you input a string with a length of five characters. The program goes through and reaches the line:
else if (isOperator(infixExpr.charAt(i + 1)) && isOperator(infixExpr.charAt(i - 1)))
If i == 4, this will cause the code:
infixExpr.charAt(i + 1)
to throw an index error.
In essance, you're checking for a character at index five (the sixth character) in a string with a maximum index index of four which is five characters in length. Also, your checking for
if(i==0 || i == infixExpr.length)
won't work as is. Maybe check for (i==infixExpr.length-1).

Optmizing a regex-based lookup function

I have the following function.
private boolean codeContains(String name, String code) {
if (name == null || code == null) {
return false;
}
Pattern pattern = Pattern.compile("\\b" + Pattern.quote(name) + "\\b");
Matcher matcher = pattern.matcher(code);
return matcher.find();
}
It is called many thousand times in my code, and is the function in which my program spends the most amount of time in. Is there any way to make this function go faster, or is it already as fast as it can be?
If you don't need to check word boundaries, you might do this :
private boolean codeContains(String name, String code) {
return name != null && code != null && code.indexOf(name)>=0;
}
If you need to check word boundaries but, as I suppose is your case, you have a big code in which you often search, you could "compile" the code once by
splitting the code string using the split method
putting the tokens in a HashSet (checking if a token is in a hashset is reasonably fast).
Of course, if you have more than one code, it's easy to store them in a structure adapted to your program, for example in a map having as key the file name.
"Plain" string operations will (almost) always be faster than regex, especially when you can't pre-compile the pattern.
Something like this would be considerably faster (with large enough name and code strings), assuming Character.isLetterOrDigit(...) suits your needs:
private boolean codeContains(String name, String code) {
if (name == null || code == null || code.length() < name.length()) {
return false;
}
if (code.equals(name)) {
return true;
}
int index = code.indexOf(name);
int nameLength = name.length();
if (index < 0) {
return false;
}
if (index == 0) {
// found at the start
char after = code.charAt(index + nameLength);
return !Character.isLetterOrDigit(after);
}
else if (index + nameLength == code.length()) {
// found at the end
char before = code.charAt(index - 1);
return !Character.isLetterOrDigit(before);
}
else {
// somewhere inside
char before = code.charAt(index - 1);
char after = code.charAt(index + nameLength);
return !Character.isLetterOrDigit(after) && !Character.isLetterOrDigit(before);
}
}
And a small test succeeds:
#Test
public void testCodeContainsFaster() {
final String code = "FOO some MU code BAR";
org.junit.Assert.assertTrue(codeContains("FOO", code));
org.junit.Assert.assertTrue(codeContains("MU", code));
org.junit.Assert.assertTrue(codeContains("BAR", code));
org.junit.Assert.assertTrue(codeContains(code, code));
org.junit.Assert.assertFalse(codeContains("FO", code));
org.junit.Assert.assertFalse(codeContains("BA", code));
org.junit.Assert.assertFalse(codeContains(code + "!", code));
}
This code seemed to do it:
private boolean codeContains(String name, String code) {
if (name == null || code == null || name.length() == 0 || code.length() == 0) {
return false;
}
int nameLength = name.length();
int lastIndex = code.length() - nameLength;
if (lastIndex < 0) {
return false;
}
for (int curr = 0; curr < lastIndex; ) {
int index = code.indexOf(name, curr);
int indexEnd = index + nameLength;
if (index < 0 || lastIndex < index) {
break;
}
boolean leftOk = index == curr ||
index > curr && !Character.isAlphabetic(code.charAt(index - 1));
boolean rightOk = index == lastIndex ||
index < lastIndex && !Character.isAlphabetic(code.charAt(indexEnd));
if (leftOk && rightOk) {
return true;
}
curr += indexEnd;
}
return false;
}
The accepted answer goes to dystroy as he was the first to point me in the right direction, excellent answer by Bart Kiers though, +1!

Categories