Consider the following code. It is for check if the String has valid parenthesis but without using stack.
public boolean isValid(String input) {
while(input.length() != (input = input.replaceAll("\\(\\)|\\[\\]|\\{\\}", "")).length());
return input.isEmpty();
}
But Kinda difficult to understand. Can this be simplified? Without adding more number of new lines?
It helps if you first format and indent it properly:
public boolean isValid_2(String input) {
while(input.length() != (input = input.replaceAll("\\(\\)|\\[\\]|\\{\\}", "")).length())
;
return input.isEmpty();
}
Next, notice that the method doesn't depend on instances of its class, so can be static. Also, remove redundant escapes from the regex:
public static boolean isValid_3(String input) {
while(input.length() != (input = input.replaceAll("\\(\\)|\\[]|\\{}", "")).length())
;
return input.isEmpty();
}
Finally, break up the complicated statement into easy-to-understand parts, and introduce some variables with meaningful names, and then change the type of loop to something more useful, and you have your final version:
public static boolean isValid_4(String input) {
int oldLength, newLength;
do {
oldLength = input.length();
input = input.replaceAll("\\(\\)|\\[]|\\{}", "");
newLength = input.length();
} while (oldLength != newLength);
return input.isEmpty();
}
My simplification is this:
static boolean isValid(String input) {
String t = input, s;
do {
s = t;
t = s.replaceAll("\\(\\)|\\[\\]|\\{\\}", "");
} while (s.length() != t.length());
return t.isEmpty();
}
which, though longer, makes it easier IMO to see what's going on. I like brevity, but it's not always best.
This differs from other simplification answers in that it focuses more on the remaining strings than on the lengths, which to my mind is more to the point. But at some point, this is a matter of aesthetics.
(Also, you can conveniently stick a "print" after the assignments in the loop, to see what is really happening - I did this to debug my incorrect comment)
Note: The question has been updated after I've answered the question. So, if doesn't fulfill the questions answer's each and every aspect, then please just ignore it.
let's see:
public boolean isValid(String input) {
int prevLength = input.length();
input = input.replaceAll("\\(\\)|\\[\\]|\\{\\}", "");
while(prevLength != input.length()) {
prevLength = input.length();
input = input.replaceAll("\\(\\)|\\[\\]|\\{\\}", "");
}
return input.isEmpty();
}
I guess its enough simplified...
Related
I need to use indexOf to find numbers inside a string, and it gives me the error:
Type mismatch: cannot convert from int to boolean.
public static boolean validPassword(String password) {
if(password.length() >= 8 ){
return true;
}
else if (password.indexOf("0")) {
return true;
}
return false;
}
Don't use index. You can use String.matches().
String str = "ksksks8ksksksksksks";
System.out.println(str.matches(".*\\d.*"));
Honestly though, if you can do it anyway you want, I would simply write a method as follows. Regular expressions are great for complicated patterns but they are also expensive in terms of processing.
public static boolean containsNumber(String str) {
boolean found = false;
for (char c : str.toCharArray()) {
if (Character.isDigit(c)) {
found = true;
break;
}
}
return found;
}
You could also modify the above and call it indexOf and iterate thru the characters using a regular for loop. Then returning either the location of the first digit or -1 just like the String version of indexOf().
And finally, for fun, you could use the Streams capability of Java 8+.
public static boolean containsNumber(String str) {
return str.chars().filter(Character::isDigit).count() > 0;
}
Would appreciate comment on whether this is the best/recommended way to parse a pipe-delimited string for particular keys.
In a low-latency system which runs this operation for every request - inefficiency is expensive.
public String extractFields(String key,String comment){
if(comment!=null){
for(String test:comment.split("\\|")){
if(test.contains(key)){
return test.substring(test.indexOf(key)+key.length()).trim();
}
}
}
return null;
}
Hmm, the split and search seems a bit pointless to me.
Why not:
indexOf() of the key to get its location, test if this is valid
If valid, from that location, do indexOf() to the next |
Return a substring of the above region.
Based on Nim's answer, here is an implementation of the faster way to do it:
public String extractField(String key, String comment) {
if (key == null || comment == null)
return null;
int i = comment.indexOf(key);
if (i < 0) // Does not contain the key
return null;
String result = comment.substring(i + 1);
i = result.indexOf('|');
if (i >= 0)
result = result.substring(0, i);
return result;
}
The input to the "alphaNumeric" function is a String which consists of alphanumeric characters that are all lower case, for example "hello123hello". I want to be able to check all upper/lower case letter combinations for this string through a check( ) function. (Eg. HeLlO123hELlo is one of the combinations to be checked). I have written code in Java to do this where I store the matching String into an ArrayList, but would like to know if there a better way to do this without the ArrayList. Also, am I correct in saying the worst case runtime of this is O(2^n)? Note: Check is a function that returns either true or false, depending on whether the correct String is passed to the function.
public static String alphaNumeric(String input) {
ArrayList<String> list = new ArrayList<String>();
alphaHelper(input, "", list);
return list.get(0);
}
private static void alphaHelper(String in, String current, ArrayList<String> list) {
if (in.length() == 0) {
if (check(current)) {
list.add(current);
}
} else if (Character.isLetter(in.charAt(0))) {
alphaHelper(in.substring(1),current+in.substring(0,1).toLowerCase(),list);
alphaHelper(in.substring(1),current+in.substring(0,1).toUpperCase(),list);
} else if (Character.isDigit(in.charAt(0))) {
alphaHelper(in.substring(1),current+in.substring(0,1),list);
} else {
return;
}
}
If you just want to remove the ArrayList without changing your basic algorithm, you can do this:
public static String alphaNumeric(String input) {
return alphaHelper(input, "");
}
private static String alphaHelper(String in, String current) {
String result = null;
if (check(current)) {
result = current;
} else if (Character.isLetter(in.charAt(0))) {
result = alphaHelper(in.substring(1),current+in.substring(0,1).toLowerCase());
if (result == null) result = alphaHelper(in.substring(1),current+in.substring(0,1).toUpperCase());
} else if (Character.isDigit(in.charAt(0))) {
result = alphaHelper(in.substring(1),current+in.substring(0,1));
}
return result;
}
Yes it is O(2^n), and I can't see offhand how you would improve on that if you can't get the original string directly.
If you don't need to check substrings (i.e. you only care about case variations of the entire string) you could improve the algorithm by not testing the substrings, but it would still be O(2^n).
You could temporarily set both the check and input to lowercase and compare them then.
public static boolean alphaNumeric(String input, String check) {
return input.toLowerCase().equals(check.toLowerCase());
}
-Sean
I have an interview question that still kills my mind, please help.
You have to write a method in Java with a String parameter.
That String should be a tree of ternary operators (a?b:c). So basically it can be something like:a? g?h:j ? u?v:w : p : r?s:t
a
/ \
g?h:j r?s:t
/ \
u?v:w p
Something like that, I hope I even wrote it right, because I am really confused.
Then we have a class Node that has 2 fields: left and right:
class Node {
char variableName;
Node left, right;
}
So you have to return a Node with all the Nodes(left, right) from that String.
I hope this is understandable. If you need more information I will provide, but the basic idea here is to get all the nodes right. I was trying to do this using recursion and I still believe that this is right. But I cannot figure out how to do it right.
This question can be solved with a very simple recursive descent parser. The intention behind asking this question is to see if you can implement a recursive algorithm where recursion makes sense, as opposed to asking you to code up a boring recursive factorial to see if you have heard of recursion before.
Here is one possible implementation:
static class Parser {
private int pos = 0;
private String s;
public Parser(String s) {
this.s = s;
}
private void skipSpace() {
while (pos != s.length() && Character.isWhitespace(s.charAt(pos))) {
pos++;
}
}
public Node parse() {
skipSpace();
Node res = new Node();
res.variableName = s.charAt(pos++);
skipSpace();
if (pos == s.length()) return res;
if (s.charAt(pos) == '?') {
pos++;
res.left = parse();
skipSpace();
if (pos == s.length() || s.charAt(pos) != ':') {
System.err.println("Syntax error");
return null;
}
pos++;
res.right = parse();
}
return res;
}
}
public static Node parse(String s) {
Parser p = new Parser(s);
return p.parse();
}
Demo.
The idea is to use parse() method as if it's already written: first we parse the variable name, then we check if it is followed by a question mark. If it is, we consume the question mark, parse from the current position what becomes our left node, skip the colon (or error out if the colon is missing), and finally parse the right node. Skip whitespace as you go.
I'm trying to create a recall program that sends text messages to 200+ people and then searches an email that the replies are forwarded too.
This method is supposed to search the array list of replies that is built using another method, but it doesn't work correctly. It will only work if the very first message on the array list matches the very first number in the contact list.
Those are some other problems, but my main question here is why does it say that the code specifically inside of my for loop is dead code?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
else{
return false;
}
}
return false;
}
This is your code, properly formatted:
public static boolean searchForPhone(String phone) {
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
return false;
}
}
return false;
}
The construct flagged as Dead code is the i++ in the for-loop header. It is indeed dead code because the for loop's body unconditionally makes the method return. Therefore the "step" part of the for header is unreachable aka. dead.
The same fact makes your code perform incorrectly, BTW. Removing the else clause would be a big improvement.
Will this help?
public static boolean searchForPhone(String phone){
CharSequence phoneN = phone;
for(int i=0;i<myMessages.size();i++){
if(myMessages.get(i).contains(phone)){
return true;
}
}
return false;
}
Look you are looping over n-element list. When you get first element on the list you got if/else statement.
So you will HAVE TO either of 2 things, both of witch is return. So your program will exit on first element returned.
To make it simplier, your code is equal to:
CharSequence phoneN = phone;
if (myMessages.size() ==0 ){
return false;
}
return myMessages.get(0).contains(phone);
Try from Window > Preferences > Java > Compiler > Error/Warnings
Change Dead code (e.g 'if(false)') and Unnecessary 'else' statement to Error.
Your loop always returns from the function at the end of the first iteration. This makes i++ dead code since it never executes.
Anyway, remove the else clause to fix the code.
In the else part you need to continue to search. Else if your fist element is not the matching one will return false and not going to check other element.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
} else {
//return false this conditional return cause
// the complain it as dead code. Since for loop will become not
//loop
continue; // will search for other elements.
}
}
return false;
}
Now you can simplify this code to following because else part is not really necessary.
public static boolean searchForPhone(String phone) {
CharSequence phoneN = phone;
for (int i = 0; i < myMessages.size(); i++) {
if (myMessages.get(i).contains(phone)) {
return true;
}
}
return false;
}