I am writing a function to fulfill these requirements:
Given a string, return true if it is a nesting of zero or more pairs of parenthesis, like (()) or ((())). Suggestion: check the first and last chars, and then recur on what's inside them.
nestParen("(())") → true
nestParen("((()))") → true
nestParen("(((x))") → false
The correct solution shown on the site is:
public boolean nestParen(String str) {
if (str.equals("")) return true;
if (str.charAt(0) == '(' && str.charAt(str.length()-1) == ')')
return nestParen(str.substring(1,str.length()-1));
else
return false;
}
I don't understand why this works. If the given string has a character other than ( like a ", won't it hit the else case and return false rather than skipping to the next (?
This will definitely not work if the input string contain some thing other than ( and ) to make this work just call another function like below before calling this function:
clean(String str){
String str = "(((X+y)+z))";
String retStr = "";
for(int i = 0 ; i<str.length() ; i++){
if(str.charAt(i) == '(' || str.charAt(i) == ')')
{
retStr += str.charAt(i);
}
}
return retStr
}
and then call your recursive function with input of retStr.
As seems typical with much example code, the suggested correct solution is inadiquate.
Here is an actually correct solution:
public boolean nestParen(final String value)
{
if (value != null)
{
if (value.isEmpty())
{
return true;
}
if (value.charAt(0) == '(' && value.charAt(value.length()-1) == ')')
{
return nestParen(value.substring(1, value.length()-1));
}
else
{
return false;
}
}
else // value is null
{
return true;
}
}
Explanation: (same as with the other answer)
if the parameter is not null, continue. This prevents NullPointerExceptions.
if the parameter is empty, return true. The problem appears to be return true if a string contains zero or more nested pairs of parens and nothing else.
If the first char is '(' and the last char is ')', strip these chars and check again (this is the recursion).
otherwise (first is not '(' and/or last is not ')') return false.
lastly, if the parameter was null, return true (it contains zero pairs and nothing else).
Related
How check if a String contains only one specific character?
Eg:
On the String square/retrofit and square/retrofit/issues I need to check if the String has more than one / character.
square/retrofit/issues need to be false because have more than one / character and square/retrofit need to be true.
The string can have numbers.
You do not need regex. Simple indexOf and lastIndexOf methods should be enough.
boolean onlyOne = s.indexOf('/') == s.lastIndexOf('/');
EDIT 1
Of course, if / does not appear in given string above will be true. So, to avoid this situation you can also check what is returned index from one of these methods.
EDIT 2
Working solution:
class Strings {
public static boolean availableOnlyOnce(String source, char c) {
if (source == null || source.isEmpty()) {
return false;
}
int indexOf = source.indexOf(c);
return (indexOf == source.lastIndexOf(c)) && indexOf != -1;
}
}
Test cases:
System.out.println(Strings.availableOnlyOnce("path", '/'));
System.out.println(Strings.availableOnlyOnce("path/path1", '/'));
System.out.println(Strings.availableOnlyOnce("path/path1/path2", '/'));
Prints:
false
true
false
Or if you'd like to use a bit more modern approach with streams:
boolean occursOnlyOnce(String stringToCheck, char charToMatch) {
return stringToCheck.chars().filter(ch -> ch == charToMatch).count() == 1;
}
Disclaimer: This is not supposed to be the most optimal approach.
A bit more optimized approach:
boolean occursOnlyOnce(String stringToCheck, char charToMatch) {
boolean isFound = false;
for (char ch : stringToCheck.toCharArray()) {
if (ch == charToMatch) {
if (!isFound) {
isFound = true;
} else {
return false; // More than once, return immediately
}
}
}
return isFound; // Not found
}
I am wondering what return str.substring(1,4).equals("bad"); is doing here in the else if(len>=4). I think the if statement is a guard clause but I am not 100%. Can I have an explanation of what exactly is going on here? How is this read to output "false"?
Given a string, return true if "bad" appears starting at index 0 or 1 in the string, such as with "badxxx" or "xbadxx" but not "xxbadxx". The string may be any length, including 0. Note: use .equals() to compare 2 strings.
hasBad("badxx") → true
hasBad("xbadxx") → true
hasBad("xxbadxx") → false
public boolean hasBad(String str)
{
int len = str.length();
if(len == 3 && str.equals("bad"))
return true;
else if(len >= 4)
{
if(str.substring(0, 3).equals("bad"))
return true;
return str.substring(1, 4).equals("bad");
}
else
return false;
}
if(str.substring(0, 3).equals("bad")) is the easy part. "Return true if 'bad' is the beginning of the String.'
return str.substring(1, 4).equals("bad") essentially means, "Return true if 'bad' occurs after the first character, and false otherwise". This is basically a shortcut of
if(str.substring(1, 4).equals("bad")) return true;
else return false;
Because the if already evaluates a boolean (what goes inside of an if results in a boolean value), there's no reason to tell it to return "true if true, else false", you can just return the boolean value directly.
you can try it in other way too, like below one
public static boolean hasBad(String str) {
for (int i = 0; i < str.length() - 1; i++) {
if (str.length()>=3 && str.charAt(0) == 'b' || str.charAt(1) == 'b' ) {
if (str.substring(i).contains("bad")) {
return true;
}
}
}
return false;
}
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
Given a string personName, I'm trying to create a boolean condition2 equal to the condition
the first or last letter in personName is 'A' (case-insensitive). e.g., 'aha' or 'A'
Here's what I've tried so far:
boolean condition2;
if (personName.charAt(0) = "a" || personName.charAt(personName.length()-1) = "a") {
condition2 = true;
} else {
condition2 = false;
}
char type in Java is a character so wouldn't you be looking for something like this?
boolean condition2;
if((personName.charAt(0) == 'a' || personName.charAt(0) == 'A') &&
(personName.charAt(personName.length()-1) == 'a' || personName.charAt(personName.length()-1) == 'A'))
{
condition2 = true;
}
else{
condition2 = false;
}
For your first question where first and last character of a String should be 'a'
boolean condition1 = false;
if(personName.charAt(0) == 'a' && personName.charAt(personName.length()-1) == 'a') {
condition1 = true;
}
For your second condition where variable should be true only if age is in the range [18,24]
boolean condition2 = false;
if(personAge >=18 && personAge <=24) {
condition2 = true;
}
You can do it this way except comparison operator is == and you compare characters, not String.
So right way would be:
Character.toLowerCase(personName.charAt(0)) == 'a'
See, double equals and single quote.
use single quote for data type char. and convert it to lower case, so that it allow whether it's upper case or lower case.
Also use == when comparing if it's equal. this = sign, is for assigning value
if(Character.toLowerCase(personName.charAt(0)) == 'a' ||
Character.toLowerCase(personName.charAt(personName.length()-1)) == 'a')
it will look like this
boolean condition2;
if(Character.toLowerCase(personName.charAt(0)) == 'a' || Character.toLowerCase(personName.charAt(personName.length()-1)) == 'a')
{
condition2 = true;
}
else{
condition2 = false;
}
Your problem can be solve in this manner;
public static void main(String[] args) {
String s = "bsdadasd";
boolean condition2;
System.out.println(check(s.toLowerCase().charAt(0),s.toLowerCase().charAt(s.length()-1)));
}
public static boolean check(char a,char b){
return (a == 'a' || b == 'a');
}
You can pass the two characters as parameters for a method where it return true or falsedepending on the condition.
Since both characters are irrelevant of its case first made them to lowercase. toLowerCase() then passed the char at 0 and char at last.
The return statement will return the true or false to you.
And also use == to check if similar = means assigning.
It is circuitous to write
boolean b;
if (some boolean expression)
b = true;
else
b = false;
Much simpler to write
boolean b = some boolean expression;
For reasons I don't understand, there is a widespread reluctance to write a boolean expression (as distinct from the simple literal values true/false) outside an 'if' statement.
And don't get me started on if (b == true)
I'm just learning java, and I have an assignment where I have to write a program that checks the validity of expressions about sets. Valid expressions are capital letters, an expression with a tilde in front, and can be combined using + and x as well as with parentheses. I've written a program that almost works, but I can't figure out how to get the binary operators to work with the parentheses.
It may also be that I have approached the problem in the wrong way (trying to validate from left to right, ignoring everything to the left once it's been validated). I can use any help I can get about writing recursive programs for this sort of problem; that is, if you have any pointers for a better way of approaching the problem, that would be incredibly helpful.
For reference, here is the code that I have:
public static boolean check(String expr) {
char spot;
int close=0;
expr = expr.trim();
//base case
if (expr.length() == 1 && expr.charAt(0)>= 'A' && expr.charAt(0) <= 'Z')
return true;
if (expr.charAt(0) == '~') {
if (expr.charAt(1) == 'x' || expr.charAt(1) == '+' || expr.charAt(1) == ')')
return false;
return check(expr.substring(1));
}
if (expr.indexOf('x') > 0 && expr.indexOf('x') > expr.indexOf(')')) {
int x = expr.indexOf('x');
if (check(expr.substring(0, x)) && check(expr.substring(x)))
return true;
}
if (expr.indexOf('+') > 0 && expr.indexOf('+') > expr.indexOf(')')) {
int plus = expr.indexOf('+');
if (check(expr.substring(0, plus)) && check(expr.substring(plus+1)))
return true;
}
if (expr.charAt(0) == '(') {
close = findEnd(expr.substring(1));
if (close < 0)
return false;
if (check(expr.substring(1,close)) && check(expr.substring(close+1)))
return true;
}
return false;
}
I'm not sure why your code is that complex. Recursion for this is pretty simple overall; here's what I'd do:
public static boolean check(String str) {
if(str.equals("")) return true;
if(str.charAt(0).isAlphaNumeric() || str.charAt(0) == '(' || str.charAt(0) == ')') return check(str.substring(1));
return false;
}
Your edge cases are if the string is empty; if this is the case, then the string is valid. If the character doesn't match what you're looking for, return false. Otherwise, check the next character.
I want to check if a String has matching braces, brackets or parenthesis.
For example:
{}
()
[]
I can do it with a stack. I want to do it with recursion. I was reading the answers for a similar question and the replies were recursion mixed in with a stack. An user responded to those answers saying that recursion is also a stack so your recursive method should not have a stack in the parameters -- this makes sense to me.
I have a big problem though, I'm looking through the String backwards and always removing the last position I check until the String is empty so I return true. I can't picture how I will check for the particular parts, braces, brackets or parenthesis without having an extra parameter in my method to hold what I am looking for. Yet I keep thinking there has to be an easier way to do this.
public boolean isBalanced(String in)
{
if(in.isEmpty())
return true;
if(in.charAt(in.length()) == '}')
{
return recIsBalanced(in.substring(0, in.length()));
}
else if(in.charAt(in.length()) == ']')
{
}
return recIsBalanced(in.substring(0, in.length()));
}
Easiest way to solve this problem using recursion is to shrink the string from both directions. You iterate from left and from right until you see . If these do not match, String is not balanced otherwise apply same algorithm for the String enclosed between those braces. Going only from one end will be a lot trickier and you will have to store some state.
EDIT: thanks to DanielFischer. Actually iterate from one side e.g. left until you find a brace(if this brace is not opening one return false). Than iterate from the other side(in this case right) until you find a matching brace. Now the string will be balanced if and only if the substring enclosed within this braces is balanced and the string to the right of the closing bracket are both balanced using recursion.
public static boolean isBalanced(String str) {
if (str.length() == 0) {
return true;
}
if (str.contains("()")) {
return isBalanced(str.replaceFirst("\\(\\)", ""));
}
if (str.contains("[]")) {
return isBalanced(str.replaceFirst("\\[\\]", ""));
}
if (str.contains("{}")) {
return isBalanced(str.replaceFirst("\\{\\}", ""));
} else {
return false;
}
}
Here is a solution, not replacing anything, straight up recursion:
/**
* #param args
*/
public boolean balance(String s, int start, int end)
{
System.out.println("start:"+start + " end" + end);
if (start == s.length()) return end == 0;
if (end<0) return false;
//if (end == s.length()-1) return start == 0;
if (s.charAt(start) == '(')
return balance(s, start+1, end+1);
if (s.charAt(start) == ')')
return balance(s, start+1, end-1);
return balance(s, start+1, end );
}
It can be done by parsing input string. Grammar for this case is:
P -> (P)
P -> [P]
P -> {P}
P -> e (Null)
It is easier to track position what is parsed in a string, and that recursion stack holds what parenthesis to be closed. Here is simple python implementation.
ps = { '{': '}', '(': ')', '[': ']'}
all_ps = set(['{', '}', '(', ')', '[', ']'])
read_position = 0
def _is_balanced( s, closing_par=None ):
global read_position
while read_position < len(s):
if s[read_position] == closing_par:
read_position += 1 # Read closing parenthesis
return True
elif s[read_position] in ps:
read_position += 1 # Read opening parenthesis
if not _is_balanced( s, ps[s[read_position-1]] ):
return False
else:
if s[read_position] not in all_ps:
read_position += 1 # Read non-parenthesis char
else:
return False # It is closing parenthesis, witouh opening before
return closing_par is None # Are we looking for a closing parenthesis?
def is_balanced( s ):
global read_position
read_position = 0 # Reset parsing position
return _is_balanced( s )
boolean isBalanced(String str)
{
if (str.isEmpty()) {
return true;
}
else if (str.charAt(0) == '(') {
return str.charAt(str.length() - 1) == ')'
&& isBalanced(str.substring(1, str.length()));
}
else if (str.charAt(0) == '[') {
return str.charAt(str.length() - 1) == ']'
&& isBalanced(str.substring(1, str.length()));
}
else if (str.charAt(0) == '{') {
return str.charAt(str.length() - 1) == '}'
&& isBalanced(str.substring(1, str.length()));
}
else {
return true;
}
}