Detecting last character - java

Im trying to detect whether the last character of a string contains an operator using an array checker that was previously used for integers. For some reason the code will always display "Not In" Even if the last character is an operator
class Main {
public static boolean useLoopString(String[] arr, String targetValue)
{
for (String s : arr) {
if (s == targetValue)
return true;
}
return false;
}
public static void main(String[] args) {
String[] op={"+","-","×","÷"};
String eq = "43+4+";
String eqLast=eq.substring(eq.length()-1);
System.out.println(eqLast);
boolean in=useLoopString(op,eqLast);
if(in){
System.out.println("In");
}
else{
System.out.println("Not In");
}
}
}

You can use char to compare, like this:
public static boolean useLoopString(char[] arr, char targetValue) {
for (char ch : arr) {
if (ch == targetValue)
return true;
}
return false;
}
public static void main(String[] args) {
char[] op = { '+', '-', '×', '÷' };
String eq = "43+4+";
char eqLast = eq.charAt(eq.length() - 1);
boolean in = useLoopString(op, eqLast);
if (in) {
System.out.println("In");
} else {
System.out.println("Not In");
}
}

Using == on class objects checks whether the two objects are the exact same instance, rather than whether the objects are equivalent, as you are intending. Instead, you should use .equals as Strings are classes:
public static boolean useLoopString(String[] arr, String targetValue) {
for (String s : arr) {
if (s.equals(targetValue))
return true;
}
return false;
}

String equality should be checked using the equals method. One should not use the object reference comparison.
In your case s and targetValue might be logically equal but may or may not point to the same String object.
Therefore, replace
if (s == targetValue)
with
if (s.equals(targetValue))
Also, null check should be made before making method calls on any object.

typically in production world, Edge cases if array has null element, you end up with null pointer exception.
always safe to use if(s!=null && s.equals(targetValue))
or
use apache's StringUtils.equals(String a, Strin b)

Related

How to check if a string is only number values

I am trying to run a recursion function where i check each character in the string to see if the character is a numeric number, however im a little stuck as the function runs and only checks the first character of the string
public static boolean isNumeric(String str) {
if(str == null)
{
return false;
}
if(str=="") {
return true;
}
char first = str.charAt(0);
if(Character.isDigit(first))
{
return true;
}
if(Character.isDigit(first) == false)
{
return false;
}
String reduced = str.substring(1);
return isNumeric((reduced)); }
Not 100% sure if I understood you correctly. If you want to check, if the string contains numeric values just see my other examples further down.
Otherwise, if you want to check, if the string contains exclusively numerical signs and digits you could do something like:
public static boolean isInteger(String numericValue) {
if (numericValue == null) return false;
try {
Integer.parseInt(numericValue);
return true;
} catch (NumberFormatException e) {
return false;
}
}
Please note, that this example does only work for Integers. If you
want to use bigger numbers, we can use Long or even BigDecimal
instead. But the main idea stays the same - check, if it can be parsed.
Or probably more appealing:
public static void main(String args[]) {
System.out.println(MyClass.isNumeric(""));
System.out.println(MyClass.isNumeric(null));
System.out.println(MyClass.isNumeric("abc"));
System.out.println(MyClass.isNumeric("a2b"));
System.out.println(MyClass.isNumeric("1a2b3"));
System.out.println(MyClass.isNumeric("42"));
System.out.println(MyClass.isNumeric("-100"));
}
public static boolean isNumeric(String str) {
if (str == null) return false; // handle null-pointer
if (str.length() == 0) return false; // handle empty strings
// to make sure that the input is numeric, we have to go through the characters
for (char c : str.toCharArray()) {
if (!Character.isDigit(c)) return false; // we found a non-digit character so we can early return
}
return true;
}
This will only print true for 42. The other examples contain other characters, too.
There are multiple issues with your code:
if(str=="") {
return true;
}
For string comparison you should use the String.equals() method - there are alternatives to that for example for your use-case you could use the convenience method String.isEmpty() or you could also just check the length of the string.
if(Character.isDigit(first))
{
return true;
}
if(Character.isDigit(first) == false)
{
return false;
}
This is some kind of if-else structure here. No need to check the same condition twice. Besides, it won't work with your recursive approach, because for what you want to achieve you need the current state which is "have I already found a digit". You could solve that with a memoized recursive function where you pass the current state along as a second argument to each subsequent call.
In your case it will return the result of the latest iteration / the
latest character.
You could do something like the following instead of using recursion. Recursion is fine, but it also comes with some costs. For example is it arguably harder to read and maintain.
public static void main() { ... } // same as above
public static boolean isNumeric(String str) {
if (str == null) return false; // handle null-pointer
if (str.length() == 0) return false; // handle empty strings
boolean atLeastOneDigit = false;
// to make sure that the input is numeric, we have to go through the characters
// until we find the first one then we can early return
for (char c : str.toCharArray()) {
if (Character.isDigit(c)) {
atLeastOneDigit = true; // we found a digit, therefore it must be numeric
break; // early return to save some iterations
}
}
return atLeastOneDigit;
}
The output of the program is:
false
false
false
true
true
true
true
Another alternative is to use Regex:
private static final Pattern digitRegex = Pattern.compile("\\d+");
public static main() { ... } // same as above
public static boolean isNumeric(String str) {
if (str == null) return false;
Matcher matcher = MyClass.digitRegex.matcher(str);
return matcher.find();
}
I am trying to explain you to solve this problem by two string methods that is isDigit(character) and charAt(i). In this case we will try to solve this problem by for loop. we will apply for loop in order to check every character of a string whether it is digit or not. If it is digit we will return true otherwise false.
Code is looks like this :
import java.lang.*;
import java.util.Scanner;
class Main {
public boolean containsDigit(String str) {
byte flag = 0;
for (int i = 0; i < str.length(); i++) {
if (Character.isDigit(str.charAt(i))) {
flag = 1;
}
}
if (flag == 1) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter a string : ");
String str = sc.nextLine();
Main test = new Main();
boolean chkDigit = test.containsDigit(str);
if (chkDigit == true) {
System.out.println("String contains digit.");
} else {
System.out.println("String doesn't contain any digit.");
}
}
}

Compare value of enum

Implementing a infix to postfix calculator and need to check if an operator has a lower precedence than another. Here's what I have so far:
public enum Operators {
ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);
private char operator;
private int precedence;
Operators(char operator, int precedence) {
this.operator = operator;
this.precedence = precedence;
}
public char getOperator() {
return operator;
}
public int getPrecedence() {
return precedence;
}
}
private static boolean isOperator(char c) {
return c == Operators.ADD.getOperator() || c == Operators.SUBTRACT.getOperator()
|| c == Operators.MULTIPLY.getOperator() || c == Operators.DIVIDE.getOperator();
}
private static boolean isLowerPrecedence(char ch1, char ch2) {
// STUCK HERE
}
I've tried a number of different things to check the precedence of the char that is passed in but to no avail. Is there an easy way to compare two values of an enum? Will I have to create a loop?
It's easy to compare if you have a method that translates a "operator" char to an enum value.
For example:
static Operators getOperatorForChar(char op) {
for(Operators val: values())
if(op == val.operator)
return val; //return enum type
return null;
}
And then you can implement your method using:
private static boolean isLowerPrecedence(char ch1, char ch2) {
//assuming intention is to compare precedence of ch1 to that of ch2
return getOperatorForChar(ch1).precedence < getOperatorForChar(ch2).precedence;
}
You can loop the values of enum to match the right operator and compare its precedences:
private static boolean isLowerPrecedence(char ch1, char ch2) {
Integer first = null;
Integer second = null;
for (Operators o: Operators.values()) {
if (o.getOperator() == ch1) {
first = o.getPrecedence();
}
if (o.getOperator() == ch2) {
second = o.getPrecedence();
}
}
return (first != null && second !=null && first < second);
}
Returning boolean when the operator has not been found might be confusing. I recommend you to throw an exception in such case instead.
...
if (first == null || second ==null) throw new Exception("Operator not found.");
return first < second;
Or, you can compare the precedence like this:
private static boolean isLowerPrecedence(Operators operatorFirst, Operators operatorSecond) {
if(operatorFirst.getPrecedence() < operatorSecond.getPrecedence()){
return true;
} else {
return false;
}
}
Of course, it can be written as:
return operatorFirst.getPrecedence() < operatorSecond.getPrecedence();
By taking a look at this question, you can find out Java handles types comparisons via the Comparable and Comparator interfaces.
Of course, they are meant for more complex situations that this one, but I think you should take them into account so that you can see the proper way to deal with the set of ordering algorithms provided by the standard Java library.
Since you can't override default Enum's compareTo (it is declared as final), you can implement your own Comparator as such:
public class OperatorsComparator implements Comparator<Operators> {
#Override
public int compare(Operators o1, Operators o2) {
return o1.getPrecedence() - o2.getPrecedence();
}
}
Then you're going to need some kind of way to find the right Operators value from the char you give in:
private static Operators findOperator(char c){
for(Operators op : Operators.values()){
if(op.getOperator() == c)
return op;
}
return null;
}
By using a substraction between the two precedences and the previous Operators finder, you can implement your isLowerPrecedence method like this:
public static boolean isLowerPrecedence(char c1, char c2) throws Exception {
Operators o1 = findOperator(c1);
Operators o2 = findOperator(c2);
if(o1 == null || o2 == null)
throw new Exception("Invalid operators");
return new OperatorsComparator().compare(o1, o2) <= 0;
}
By comparing precedences this way, you'll get that o1 will be marked as lower precedence even if it has the same precedence as o2, as default behaviour.
Beware of the characters you try to use as operator, since you'll need to catch the Exception if anything goes wrong
Execution example:
System.out.println(isLowerPrecedence('+', '-'));
System.out.println(isLowerPrecedence('+', '*'));
System.out.println(isLowerPrecedence('/', '-'));
System.out.println(isLowerPrecedence('/', '*'));
System.out.println(isLowerPrecedence('*', '-'));
prints these messages:
true
true
false
true
false
You can use EnumLookup helper class proposed in this answer of mine (source code of EnumLookup there).
Upon redesining your Operators enum a little (I strongly suggest using a singular class name), you get:
public enum Operator {
ADD('+', 2), SUBTRACT('-', 2), MULTIPLY('*', 4), DIVIDE('/', 4);
private static final EnumLookup<Operator, Character> BY_OPERATOR_CHAR
= EnumLookup.of(Operator.class, Operator::getOperatorChar, "operator char");
private final char operatorChar;
private final int precedence;
Operator(char operatorChar, int precedence) {
this.operatorChar = operatorChar;
this.precedence = precedence;
}
public char getOperatorChar() {
return operatorChar;
}
public int getPrecedence() {
return precedence;
}
public static EnumLookup<Operator, Character> byOperatorChar() {
return BY_OPERATOR_CHAR;
}
}
private static boolean isOperator(char c) {
return Operator.byOperatorChar().contains(c);
}
private static boolean isLowerPrecedence(char ch1, char ch2) {
return Operator.byOperatorChar().get(ch1).getPrecedence() < Operator.byOperatorChar().get(ch2).getPrecedence();
}
The main drawback of this approach is that your char gets boxed into Character, but unless performance is critical for your application, I wouldn't worry about that (readability should be more important).

Java Palindrome (Boolean Method) with iterative solution (while loop)

Why doesn't my palindrome program work correctly? It always returns false, and I can't tell why.
Here is my code:
public static boolean isPalindromIterative(String string) {
int a = 0;
int b = string.length() - 1;
while (b > a) {
if (a != b) {
return false;
}
a++;
b--;
}
return true;
}
You are comparing values of a and b which aren't the same when you start comparing and hence you get false from your method.
In your if condition, Change it to be string.charAt(a) != string.chatAt(b)
When you say
while (b > a) {
if (a != b) {
It's clear that a is not equal to b (or the loop wouldn't be entered). Going by context, I believe you wanted to compare the characters in the String. I would use String.toCharArray() to get a char[] and do something like
char[] chars = string.toCharArray();
while (b > a) {
if (chars[a] != chars[b]) {
If b > a in your code while (b > a), then a doesn't equal to b in your code if (a != b).
To check given string is palindrome or not in java simply use StringBuilder class reverse() method and check with given string.
public static boolean isPalindromIterativeStringBuilder(String string) {
StringBuilder sb = new StringBuilder(string);
sb.reverse(); //Reverse to the given string
return sb.toString().equalsIgnoreCase(string); //Check whether given string is equal to reverse string or not
}
This is also an iterative method.
I would be happy if I helped someone. ;)
public static boolean isPalindromeIterative(String string) {
String polindromCheck = string.toUpperCase();
for (int index = 0; index < polindromCheck.length(); index++) {
if (polindromCheck.charAt(index) != polindromCheck.charAt(string.length() - 1 - index)) {
return false;
}
}
return true;
}

Password Validator

I'm currently trying to make a password validator work with boolean method, since the teacher asked us to do so. This is driving me nuts. To be correct, the password need to have one uppercase, one lower case letter, at least 10 characters and one number. I'm aware that right now, my method returns entirely with the value false, but I'm wondering how I can break the code once I have one uppercase, or one lowercase.
Thanks a lot for your help!
public class AtLeast1UppercaseLowercaseNumber {
public static void main(String[] args){
String password = "H";
System.out.println(password);
if(isSecurePassword(password)){
System.out.println("Yay it works");}
else {
System.out.println("you suck");}
}
public static isSecurePassword(String password) {
int uppercase = 0, lowercase = 0, number = 0;
for(int i=0; i<password.length(); i++) {
for(char c ='A'; c <='Z'; c++) {
if(password.charAt(i) == c) {
uppercase++;
if( uppercase >= 1) {
for(char t = 'a'; t <='z'; t++) {
if(password.charAt(i) == t) {
lowercase++;
if(lowercase >= 1) {
}
}
}
for(int j = '0'; j <='9'; j++) {
if(password.charAt(i) == j) {
number++;
if( number >= 1) {
}
}
}
}
return false;
}
}
I suggest you start by creating multiple private and static test methods, and then delegate to them in your public isSecurePassword(String) method. Implement test methods like boolean oneUpper(String), boolean oneLower(String), boolean oneDigit(String) and boolean tenCharacters(String) as an example
private static boolean tenCharacters(String str) {
return str.length() > 9;
}
and a second example
private static boolean oneUpper(String str) {
for (char ch : str.toCharArray()) {
if (Character.isUpperCase(ch)) {
return true;
}
}
return false;
}
Then your isSecurePassword(String) is just
public static boolean isSecurePassword(String str) {
return tenCharacters(str) && oneUpper(str) && oneLower(str)
&& oneDigit(str);
}
Since there is only one return in this method, which explicitly returns false, this method will always return false.
Method 1:
Define a boolean, which will be returned in the last statement of the method. This boolean is true by default and will be set false if one condition is wrong.
Method 2:
The last statement is an implicit return true statement, and whenever a condition is not fullfilled return false. This will prevent the method from executing more tests.
Method 3:
Make the method look like this
if (containsUpperCase(string) && contains...)
return true;
return false;

java iterative to recursive 2 nested for loop

I would like to check whether a string contains a sub list.
For example, str1 = "qwertyuiop" and str2 = "tyu" returns true.
I have written an iterative method.
public static boolean checkString(String str1, String str2) {
for (int i=0; i<str2.length(); i++) {
int j = 0;
for (; j<str1.length()&& str1.charAt(j)!=str2.charAt(i); j++) {
}
if (j== str1.length())
return false;
}
return true;
}
I am trying changing it to recursive method but not sure how as there are two nested for loops.
Thank you in advance.
I suggest you focus on other activities. Java already includes a function to do what you are implementing, and that is String.contains(CharSequence) like
if (str1.contains(str2)) { // <-- wherever you would have called "checkString"
// ...
}
public class Test {
public static void main(String[] args) {
System.out.println(isSubstring("ankur", "ku"));
}
public static boolean isSubstring(String str1, String str2) {
if ((str1 == null) || (str2 == null) || str1.isEmpty()) {
return false;
} else if (str1.startsWith(str2)) {
return true;
} else {
return isSubstring(str1.substring(1), str2);
}
}
}

Categories

Resources