Write a recursive method called isReverse("word1", "word2") that accepts two Strings as parameters and returns true if the two Strings contain
the same sequence of characters as each other but in opposite order, ignoring case, and returning false otherwise.
For example, the call of:
isReverse("Desserts", "Stressed")
would return true. [So eat desserts when you are stressed?]
Null, empty and one letter strings are also to return true (if both parameters are the same value).
This is homework and I am having trouble making this code work appropriately. It returns true no matter what I do.
public static boolean isReverse(String word1, String word2)
{
if(word1 == null || word2 == null)
{
if(word1!= null && word2 != null)
{
return false;
}
return false;
}
else if(word1.length() == word2.length())
{
String firstWord = word1.substring(0, word1.length());
String secondWord = word2.substring(word2.length()-1);
if (firstWord.equalsIgnoreCase(secondWord))
{
return isReverse(word1.substring(0, word1.length()), word2.substring(word2.length() - 1));
}
}
return true;
}
First, you have this set so that it will only return false if both words are null; If they are not null you're re-calling the method(in the event that the length is equal), which will return true.
private static boolean isReverse(String a, String b) {
// make sure the strings are not null
if(a == null || b == null) return false;
// If the lengths are not equal, the strings cannot be reversed.
if(a.length() != b.length()) {
return false;
}
// Convert string b to an array;
char[] bArray = b.toCharArray();
// Create an array to write bArray into in reverse.
char[] copy = new char[bArray.length];
// Iterate through bArray in reverse and write to copy[]
for(int i = bArray.length; i < 0; i--) {
copy[bArray.length - i] = bArray[i];
}
// Convert copy[] back into a string.
String check = String.valueOf(copy);
// See if they reversed string is equal to the original string.
if(check.equalsIgnoreCase(a)) {
return true;
} else {
return false;
}
}
You are saying
if (firstWord.equalsIgnoreCase(secondWord))
{
return isReverse(word1.substring(0, word1.length()), word2.substring(word2.length() - 1));
}
which is OK. But what if firstWord does not equal second word
It falls through and returns true.
You need to add an
else
return false;
I will also add that your null checking will not work.
if(word1!= null && word2 != null)
{
return false;
}
Is not useful because you are already in an if that only happens when word1 or word2 is null. So they can't be null and null here.
It would work if you made it
if(word1 == null && word2 == null)
{
return true;
}
Is this an exercise? Recursion doesn't seems to be the best option here. Anyway, you're just trimming one word, why? You must trim both words if you expect to compare each char in each recursive call. And you're not even passing the trimmed words as parameter to the recursive function!
The basic thing you're missing is a base case. When the recursion must return? In your case, you're reducing each string size at each step of recursion, so you must have a base case to check if the size is one.
Hope that this code clear your mind:
public static boolean isReverse(String word1, String word2) {
if (word1 == null || word2 == null) {
return false;
}
if (word1.length() == 1 && word2.length() == 1) {
//Used equals just for fast compare
return word1.equals(word2);
} else if (word1.length() == word2.length()) {
if (word1.charAt(0) == word2.charAt(word2.length() - 1)) {
String firstWord = word1.substring(1, word1.length());
String secondWord = word2.substring(0, word2.length() - 1);
System.out.printf("Trimmed %s, %s to %s, %s\n", word1, word2, firstWord, secondWord);
return isReverse(firstWord, secondWord);
} else {
//Characters didn't matched
return false;
}
} else {
//Lenght doesn't match
return false;
}
}
First I have reversed one of the string(i took word1) using recursion.then compared to second string if both strings are equal result set to true.
public static boolean isReverse(String word1, String word2)
{
boolean result = false;
//check null to avoid null pointer exception
if(word1 == null | word2 == null){
result = false;
}else if(word1.length() == word2.length()){
word1 = reverseString(word1);
if(word1.equalsIgnoreCase(word2)){
result = true;
}
}
return result;
}
static String reverse = "";
public static String reverseString(String str){
if(str.length() == 1){
reverse+=str;
} else {
reverse += str.charAt(str.length()-1)
+reverseString(str.substring(0,str.length()-1));
}
return reverse;
}
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
}
For my assignment I have to use recursion to test if two strings are the same but reversed.
Here is the actual question:
Write a recursive method called isStringReversed which, given two String parameters, returns true if the two strings contain the same sequence of characters but in reverse order (ignoring capitalization), and false otherwise. For example, isStringReversed("piano", "oNaIp") would return true. Note: the null (empty) string and string of one letter are both the reverse of themselves.
Here's what I have made, but when I execute the program, i always get
a false return. Heres my code:
public static boolean isStringReversed(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() == 1 || s2.length() == 1) {
return true;
}else if (s1.length() != s2.length()) {
return false;
}else {
char s1first = Character.toLowerCase(s1.charAt(0));
char s2last = Character.toLowerCase(s2.charAt(s2.length() - 1));
if (s1first == s2last){
String s1shorter = s1.substring(0, s1.length() - 1);
String s2shorter = s2.substring(0, s2.length() - 1);
return isStringReversed(s1shorter, s2shorter);
}else {
return false;
}
}
}
When doing substring on s1first, you should remove the first character, not the last.
Just one line above that you compare first character of s1first and last character of s2last. So once you establish that they are equal, that's what you remove and continue the recursion.
Instead of
String slshorter = sl.substring(0, s1.1ength() - l) ;
String s2shorter = s2.substring(0, s2.1ength() - l) ;
use
String slshorter = sl.substring(1) ;
String s2shorter = s2.substring(0, s2.1ength() - 1) ;
Note that the second parameter of the method substring() means to that index exclusive.
This is the recursive idea
public static bool isStringReversed(string input1, string input2)
{
string s1 = input1.ToLower();
string s2 = input2.ToLower();
if(s1 == null && s2 == null)
return true;
if (s1.Length == 1 && s2.Length == 1)
{
if (s1 == s2)
return true;
return false;
}
if (s1.Length != s2.Length)
return false;
return isStringReversedRec(s1, s2, s1.Length - 1, 0);
}
private static bool isStringReversedRec(string s1, string s2, int indexS1, int indexS2)
{
if (indexS1 < 0)
return true;
if (s1.charAt(indexS1) != s2.charAt(indexS2))
return false;
return isStringReversedRec(s1, s2, indexS1 - 1, indexS2 + 1);
}
I have the following question:
Write a recursive static method isSubstring with the following signature -
public static boolean isSubstring(String s1,String s2)
gets two strings - s1, s2 and returns true if s2 is a substring of s1.
the method should be recursive without using iterations at all. also any other method you write (if you write).
the correct answer does not change the method type signature/annotation (not even by overloading).
you can only use the following methods in your solution:
public char charAt(int i)
public int length()
public String substring(int i)
that's what I have so far, I know it doesn't work IE isSubstring("hello","ho") will return true. any idea what could be done?
public static boolean isSubstring(String s1, String s2) {
if (s2.length() == 0)
return true;
if ((s1.length() == 0) || (s1.length() < s2.length()))
return false;
if (s1.charAt(0) != s2.charAt(0))
return isSubstring(s1.substring(1), s2);
else
return isSubstring(s1.substring(1), s2.substring(1));
}
I think this should do it.
It uses an auxiliary method. When you see the first match, it will call the auxiliary method and verify if the substring matches from that point. If it doesn't, it tries the same with the next match.
public static boolean isSubstring(final String s1, final String s2) {
if (s2.length() == 0) {
return true;
}
if ((s1.length() == 0) || (s1.length() < s2.length())) {
return false;
}
if (s1.charAt(0) != s2.charAt(0)) {
return isSubstring(s1.substring(1), s2);
}
if (!isSubstringAux(s1.substring(1), s2.substring(1))) {
return isSubstring(s1.substring(1), s2);
}
return true;
}
public static boolean isSubstringAux(final String s1, final String s2) {
if (s2.length() == 0) {
return true;
}
if (s1.charAt(0) == s2.charAt(0)) {
return isSubstringAux(s1.substring(1), s2.substring(1));
}
return false;
}
Your solution is almost good but you have to somehow remember that you made a replacement. I propose the following solution (using a helper function with a different prototype, which fits the requirements of the problem) :
public static boolean sub(final String s1, final String s2, final boolean hasReplaced) {
if (s2.length() == 0) {
return true;
}
if ((s1.length() == 0) || (s1.length() < s2.length())) {
return false;
}
if (s1.charAt(0) != s2.charAt(0)) {
if (hasReplaced) {
return false;
}
return sub(s1.substring(1), s2, hasReplaced);
}
return sub(s1.substring(1), s2.substring(1), true);
}
public static boolean isSubstring(final String s1, final String s2) {
return sub(s1, s2, false);
}
public static boolean isSubstring(String s1, String s2) {
return s2.length() == 0
|| ( s1.length() >= s2.length()
&& ( matchStartOfString( s1, s2 )
|| isSubstring( s1.substring(1), s2 )
)
);
}
private static boolean matchStartOfString( final String s1, final String s2 )
{
return s2.length() == 0
|| ( s1.length() >= s2.length()
&& s1.charAt( 0 ) == s2.charAt( 0 )
&& matchStartOfString( s1.substring(1), s2.substring(1) )
);
}
public static boolean isSubstring(String s1, String s2){
if (s2.length == 0) return true;
if (s1.length < s2.length) return false;
if (s1.charAt(0) == s2.charAt(0))
return isPrefixString(s1.substring(1, s2.length), s2.substring(1, s2.length))
|| isSubstring(s1.substring(1, s1.length), s2);
return isSubstring(s1.substring(1, s1.length), s2);
}
private static boolean isPrefixString(String s1, String s2){
if (s2.length == 0) return true;
if (s1.charAt(0) != s2.charAt(0)) return false;
return isPrefixString(s1.substring(1, s1.length), s2.substring(1, s2.length));
}
Basic algorithm:
isSubstring function:
Base case 1: If s2 is empty (either because it's empty or because it's been exhausted) then return vacuous truth (every string contains the empty string).
Base case 2: If s1 is shorter than s2, then s1 can't possibly contain s2, so return tautologic false.
Recursive case 1: If s1 contains s2, then some substring of s1 starts with the same letter as s2 starts with. Therefore, if s1 does not start with the same letter as s2, find some other point in the string to use as the start point. By "some other", this algorithm just iterates linearly through the string.
Recursive case 2: If s1 and s2 start with the same string, test whether s2 is a prefix string of s1 (i.e. if s1 starts with s2) recursively. If s2 is not a prefix string of s1, then try another start point. Otherwise, s2 is a prefix of s1 and hence s1 contains s2.
Note that the code has recursive cases 1 and 2 backwards from how I've written it here.
isPrefixString function:
Base case 1: If s2 is empty, then return (vacuous) truth.
Base case 2: If s1 and s2 do not start with the same letter, then s2 cannot possibly be a prefix of s1, so return false.
Recursive case: If s1 and s2 start with the same character, check if the next character is the same as well.
Recursion should be thought of as two parts.
1) A base case. This is trivial case that can easily be determined.
What you have so far is a good start to a base case.
1) Is the string less then 3? Then return false.
2) Does the string start with "bab" then return true.
2) A recursive case.
This splits the problem up into a tinier problems, and if you split them up enough hopefully you have a base case.
Here is a good example of a simple recursion.
public static boolean substringRec(String str, String str2) {
if (str.length() < str2.length()) return false;
if (str.length() == str2.length())
{
if (equals(str, str2))
return true;
return false;
}
else
return substringRec(str.substring(1), str2);
}
public static boolean equals(String str1, String str2)
{
if (str1.charAt(0) == str2.charAt(0))
{
if (str1.length() == 1)
return true;
return equals(str1.substring(1), str2.substring(1));
}
return false;
}
This uses simple base cases and as a recursive case checks the string from index one on. This reduces our string only by one charter, but is enough to solve the problem.I had to implement a .equals since apparently you can't use that, you can do that in a similar way.
This means we end up with a stack level of the length of the string.
Can we do better? A little, by breaking the problem in half we only need a stack level of ln(n) where n is the length of string. This is not a big deal for most lengths, but if you were searching a string with a length of one million it maybe significant. With the first version our stack would be about a 1,000,000 deep! But with this binary version we only need to go about 14 levels deep.
This comes at a cost though, our solution because more involved and will break some of the rules you have on your assignment, but I think it's interesting to think about.
Our base cases
1) If the string is less then the length of the search string, return false.
2) If the string is length of the search string, if they are equal return true, else return false.
3) If the string appears over the mid point of the string return true.
If none of these are true,we break the string into two parts and recursively check over that string.
Here is an example of that algorithm, although it hasn't been fully tested for that I'm pretty sure it will be okay.
public static boolean substringRec2(String str, String searchString) {
// Base cases
if (str.length() < searchString.length())
return false;
if (str.length() == searchString.length())
{
if (str.equals(searchString))
{
return true;
}
return false;
}
int halfWay = str.length()/2;
// Now check for the search string over the "break"
for (int i = 0; i < searchString.length(); i++)
{
int startIndex = halfWay - 1 - i;
int endIndex = startIndex + 3;
if (startIndex >= 0)
{
String substring = str.substring(startIndex, endIndex);
if (substring.equals(searchString))
{
return true;
}
}
}
// Recursive Cases
// We did find the search string over the break,so break the string into two equal(ish) pieces and check those
if(substringRec2(str.substring(0,halfWay -1), searchString))
return true;
if(substringRec2(str.substring(halfWay, str.length()), searchString))
return true;
return false;
}
Note - taken from one of my previous answers and modified - https://stackoverflow.com/a/21594554/3096507
Compare three boolean values and display the first one that is true.
Hey guys, I am trying to write a program that compares three boolean values and displays the first true one. I am comparing three words for their length, and it will display the longest. The error that I am getting is that my else tags aren't working. Take a look at the code.
//Check which word is bigger
if (len1 > len2)
word1bt2 = true;
if (len2 > len3)
word2bt3 = true;
if (len1 > len3)
word1bt3 = true;
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true);
System.out.println(wor1);
else if (word2bt3 == true);
System.out.println(wor2);
else System.out.println(wor3);
I have set boolean values for word1bt2, word2bt3 and word1bt3. In eclipse, I am getting a syntax error under the elses in my code above. Any help would be great!
if (word1bt2 == true && word1bt3 == true);
Is wrong, you need to remove the semicolon:
if (word1bt2 == true && word1bt3 == true)
Same for the elses
else (word2bt3 == true);
Is wrong too, it should be
else if (word2bt3 == true)
Side note: boolean values can be used as condition, so your if statements should be
if (word1bt2 && word1bt3) // The same as if (word1bt2 == true && word1bt3 == true)
How to compare three boolean values?
Dont!
If you find yourself needing to compare three variable you may as well cater for any number of variables immediately - there's no point hanging around - do it properly straight away.
public String longest(Iterator<String> i) {
// Walk the iterator.
String longest = i.hasNext() ? i.next() : null;
while (i.hasNext()) {
String next = i.next();
if (next.length() > longest.length()) {
longest = next;
}
}
return longest;
}
public String longest(Iterable<String> i) {
// Walk the iterator.
return longest(i.iterator());
}
public String longest(String... ss) {
// An array is iterable.
return longest(ss);
}
Remove the ; and change it with brackets {}.
if (word1bt2 && word1bt3) {
System.out.println(wor1);
} else if (word2bt3) {
System.out.println(wor2);
} else {
System.out.println(wor3);
}
Issue with the else blocks: use {} insteaad of () to enclose instructions...
Remove the ; at the first if!!!!! - Quite common mistake, with very puzzling results!
//Check which word is the longest
if (word1bt2 == true && word1bt3 == true) { //leave ; and always add bracket!
System.out.println(wor1);
}
else if(word2bt3 == true)
{
System.out.println(wor2);
}
else {
System.out.println(wor3);
}
if you need a condition in an else branch, you have to use if again - plain else won't have such a feature...
ALWAYS use brackets for bodies of if statements, loops, etc!!!
Be extremely careful NOT to use ; in the lines that don't behave well with it:
if statements
for loops
while() {...} loops' while statement
try this, if lenght are equal then s1 is considered as Bigger. Also i have not added null check
public class Test {
public static void main(String[] args) {
String word1 = "hi";
String word2 = "Hello";
String word3 = "Hell";
String Bigger = null;
if(word1.length() >= word2.length() && word1.length() >= word3.length() ){
Bigger = word1;
}else if(word2.length() >= word1.length() && word2.length() >= word3.length()){
Bigger = word2;
}else if(word3.length() >= word2.length() && word3.length() >= word1.length()){
Bigger = word3;
}
System.out.println(Bigger);
}
}
I have a class that checks whether a string is a palindrome or not. I have two questions.
1) Is this the most efficient way to check for palindrome?
2) Can this be implemented recursively?
public class Words {
public static boolean isPalindrome(String word) {
String pal = null;
word = word.replace(" ", "");
pal = new StringBuffer(word).reverse().toString();
if (word.compareTo(pal) == 0) {
return true;
} else {
return false;
}
}
}
Have a test class to test this... Doubt its needed but here it is anyways if anyone cares to try it out to be able to help me with any of the two questions above...
public class testWords {
public static void main(String[] args) {
if (Words.isPalindrome("a") == true) {
System.out.println("true");
} else {
System.out.println("false");
}
if (Words.isPalindrome("cat") == true) {
System.out.println("true");
} else {
System.out.println("false");
}
if (Words.isPalindrome("w o w") == true) {
System.out.println("true");
} else {
System.out.println("false");
}
if (Words.isPalindrome(" a ") == true) {
System.out.println("true");
} else {
System.out.println("false");
}
if (Words.isPalindrome("mom!") == true) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}
thanks in advance for any help and or input :)
To implement a 'palindrome check' recursively, you must compare if the first and last characters are the same. If they are not the same the string is most certainly not a palindrome. If they are the same the string might be a palindrome, you need to compare the 2nd character with the 2nd to last character, and so on until you have strictly less then 2 characters remaining to be checked in your string.
A recursive algorithm would look like this:
public static boolean isPalindrome(String word) {
//Strip out non-alphanumeric characters from string
String cleanWord = word.replaceAll("[^a-zA-Z0-9]","");
//Check for palindrome quality recursively
return checkPalindrome(cleanWord);
}
private static boolean checkPalindrome(String word) {
if(word.length() < 2) { return true; }
char first = word.charAt(0);
char last = word.charAt(word.length()-1);
if( first != last ) { return false; }
else { return checkPalindrome(word.substring(1,word.length()-1)); }
}
Note, that my recursion method is not most efficient approach, but
simple to understand
Marimuthu Madasamy has a more efficient recursive method, but is harder to understand
Joe F has listed an equivalently efficient iterative method
which is the best approach for implementation because it cannot cause a stack overflow error
Here is another recursive solution but using array which could give you some performance advantage over string in recursive calls (avoiding substring or charAt).
private static boolean isPalindrome(final char[] chars, final int from,
final int to) {
if (from > to) return true;
return chars[from] != chars[to] ? false
: isPalindrome(chars, from + 1, to - 1);
}
public static boolean isPalindrome(final String s) {
return isPalindrome(s.toCharArray(), 0, s.length() - 1);
}
The idea is that we keep track of two positions in the array, one at the beginning and another at the end and we keep moving the positions towards the center.
When the positions overlap and pass, we are done comparing all the characters and all the characters so far have matched; the string is palindrome.
At each pass, we compare the characters and if they don't match then the string is not palindrome otherwise move the positions closer.
It's actually sufficient to only check up to the middle character to confirm that it is a palindrome, which means you can simplify it down to something like this:
// Length of my string.
int length = myString.length();
// Loop over first half of string and match with opposite character.
for (int i = 0; i <= length / 2; i++) {
// If we find one that doesn't match then return false.
if (myString.charAt(i) != myString.charAt(length - 1 - i)) return false;
}
// They all match, so we have found a palindrome!
return true;
A recursive solution is very possible but it is not going to give you any performance benefit (and probably isn't as readable).
Can this be implemented Recursively?
YES
Here is example:
public static boolean palindrome(String str)
{
if (str.length()==1 || str.length == 0)
return true;
char c1 = str.charAt(0);
char c2 = str.charAt(str.length() - 1);
if (str.length() == 2)
{
if (c1 == c2)
return true;
else
return false;
}
if (c1 == c2)
return palindrome(str.substring(1,str.length() - 1));
else
return false;
}
My two cents. It's always nice to see the different ways people solve a problem. Of course this is not the most efficient algorithm memory or speed wise.
public static boolean isPalindrome(String s) {
if (s.length() <= 1) { // got to the middle, no need for more checks
return true;
}
char l = s.charAt(0); // first char
char r = s.charAt(s.length() - 1); // last char
if (l == r) { // same char? keep checking
String sub = s.substring(1, s.length() - 1);
return isPalindrome(sub);
}
return false;
}
The simplest way to check palindrome.
private static String palindromic(String word) {
if (word.length() <= 1) {
return "Polidramic";
}else if (word.charAt(0) != word.charAt(word.length() - 1)) {
return "Not Polidramic";
}
return palindromic(word.substring(1, word.length() - 1));
}