How to recursively remove a character from a string? - java

How do I remove a target character from string using RECURSION?
I know it begins like:
public static String removeChar(String str, char target) {
if (str.length() == 0) {
return str;
} else {
if (str.charAt(0) == target) {
return removeChar(/*what goes in here?*/)
}
return removeChar(/*what goes in here?*/)
}
}
thank you!!

The idea is that if the first character is equal to the target character, you simply return the result of removeChar() applied on the rest of the String (i.e. the String without the first character), which removes the first character.
On the other hand, if the first character is not equal to the target character, you return a String starting with the original first character and ending with the result of applying removeChar() on the rest of the String.
public static String removeChar(String str, char target) {
if(str.length() == 0) {
return str;
} else {
if(str.charAt(0) == target) {
// remote the first character, and apply the recursive method to
// the rest of the String
return removeChar(str.substring(1),target);
} else {
// don't remote the first character, and apply the recursive method to
// the rest of the String
return str.charAt(0) + removeChar(str.substring(1),target);
}
}
}

You could use the following code inside the else-block:
if(str.charAt(0) == target) {
return removeChar(str.substring(1), target);
}
return charAt(0) + removeChar(str.substring(1), target);
But I don't see a need to use recursion here, you could just use
str.replace(target, '');

You check the index of the 1st occurrence of the char and remove it from that position:
public static String removeChar(String str, char target) {
int index = str.indexOf(target);
if (index < 0)
return str;
else {
return removeChar(str.substring(0, index) + str.substring(index + 1), target);
}
}
public static void main(String[] args) {
String str = "0123045607890";
System.out.println(removeChar(str, '0'));
}
will print:
123456789

I suggest this solution.
function isLetter(str) {
return str.length === 1 && str.match(/[A-Z]/i);
}
function removeLetters(str) {
//console.log(str);
let val = str.substr(0, 1);
console.log(val);
if (isLetter(val)) {
return removeLetters(str.substr(1))
} else {
console.log("Return", str);
return str;
}
}

Related

What is wrong with my method isReverse

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;
}

Using recursion to find a character in a string

I am trying to find the first occurrence of a letter in a string. For example, p in apple should return 1. Here is what I have:
// Returns the index of the of the character ch
public static int indexOf(char ch, String str) {
if (str == null || str.equals("")) {
return -1;
} else if(ch == str.charAt(0)) {
return 1+ indexOf(ch, str.substring(1));
}
return indexOf(ch, str.substring(1));
}
It just doesn't seem to be returning the correct value.
I'll give you some hints:
When you've found the letter, you don't need to recurse further. Additionally, think about what you should be returning in this case.
When do you recurse, also think about what the function should return.
Is there anything special you need to do if the recursive call returns -1?
Your attempt was good, but not quite there. Here is a correct implementation based off yours:
public static int indexOf(char ch, String str) {
// Returns the index of the of the character ch
if (str == null || str.equals("")) {
// base case: no more string to search; return -1
return -1;
} else if (ch == str.charAt(0)) {
// base case: ch is at the beginning of str; return 0
return 0;
}
// recursive step
int subIndex = indexOf(ch, str.substring(1));
return subIndex == -1 ? -1 : 1 + subIndex;
}
There were two problems with your attempt:
In the else if part, you had found the character, so the right thing to do was stop the recursion, but you were continuing it.
In your last return statement, you needed to be adding 1 to the recursive call (if the character was eventually found), as a way of accumulating the total index number.
Here's another variation. Instead of calling substring you could modify the function a bit to pass the next index to check. Notice that the recursion is initiated with index 0. (You could actually start on any index. There is also some error checking in case the letter isn't found. Looking for x in apple will return -1.)
public static void main(String []args){
System.out.println("Index: " + indexOf('e', "apple", 0));
System.out.println("Index: " + indexOf('x', "apple", 0));
System.out.println("Index: " + indexOf('p', "Mississippi", 3));
System.out.println("Index: " + indexOf('p', "Mississippi", 908));
}
public static int indexOf(char ch, String str, int idx) {
// check for garbage data and incorrect indices
if (str == null || str.equals("") || idx > str.length()-1)
return -1;
// check to see if we meet our condition
if (ch == str.charAt(idx))
return idx;
// we don't match so we recurse to check the next character
return indexOf(ch, str, idx+1);
}
Output:
Index: 4
Index: -1
Index: 8
Index: -1
Well if we must use recursion then try this:
class RecursiveFirstIndexOf {
public static void main(String[] args) {
System.out.println(indexOf('p', "apple", 0));
}
static int indexOf(char c, String str, int currentIdx) {
if (str == null || str.trim().isEmpty()) {
return -1;
}
return str.charAt(0) == c ? currentIdx : indexOf(c, str.substring(1), ++currentIdx);
}}
Why not doing it straight forward?
public static void main(String[] args) {
String str = "abcdef";
for (int idx = 0; idx < str.length(); idx++) {
System.out.printf("Expected %d, found %d\n", idx, indexOf(str.charAt(idx), str, 0));
}
System.out.printf("Expected -1, found %d\n", indexOf(str.charAt(0), null, 0));
}
public static int indexOf(char ch, String str, int index) {
if (str == null || index >= str.length()) return -1;
return str.charAt(index) == ch ? index : indexOf(ch, str, ++index);
}
OUTPUT:
Expected 0, found 0
Expected 1, found 1
Expected 2, found 2
Expected 3, found 3
Expected 4, found 4
Expected 5, found 5
Expected -1, found -1
first of all : Recursion has two pillars, Base Case and General Case.
Base Case (the termination point) is the one where Recursion terminates and General Case as the name implies is where the program keeps executing until it finds Base Case
you may try this example, where count is a global static variable
public static int indexOf(char ch, String str)
{
// Returns the index of the of the character ch
if (str == null || str.Equals("")) //Base Case
{
if (count != 0)
{
if(str.Length == 0)
return -1;
return count;
}
else
return -1;
}
else if (ch == str.CharAt(0)) //Base Case
return 1 + count;
count++;
return indexOf(ch, str.Substring(1)); //General Case
}

Return true if string cointains "xyz" not preceeded by a period?

I'm trying to solve this CodingBat problem:
Return true if the given string contains an appearance of "xyz" where the xyz is not directly preceeded by a period (.). So "xxyz" counts but "x.xyz" does not.
xyzThere("abcxyz") → true
xyzThere("abc.xyz") → false
xyzThere("xyz.abc") → true
My attempt:
public boolean xyzThere(String str) {
boolean res = false;
if(str.contains(".xyz") == false && str.contains("xyz")){
res = true;
}
return res;
}
The problem is that is passes all the tests except the one below because it contains two instances of xyz:
xyzThere("abc.xyzxyz")
How can I make it pass all tests?
public static boolean xyzThere(String str) {
int i = -1;
while ((i = str.indexOf("xyz", i + 1 )) != -1) {
if (i == 0 || (str.charAt(i-1) != '.')) {
return true;
}
}
return false;
}
Alternatively, you could replace all occurrences of ".xyz" in the string with "", then use the .contains method to verify that the modified string still contains "xyz". Like so:
return str.replace(".xyz", "").contains("xyz");
public boolean xyzThere(String str) {
return(!str.contains(".xyz") && str.contains("xyz"));
}
Edit: Given that ".xyzxyz" should return true, the solution should be:
public boolean xyzThere(String str) {
int index = str.indexOf(".xyz");
if(index >= 0) {
return xyzThere(str.substring(0, index)) || xyzThere(str.substring(index + 4));
} else return (str.contains("xyz"));
}
The below code worked fine for me:
if '.xyz' in str:
return xyz_there(str.replace('.xyz',''))
elif 'xyz' in str:
return True
return False
Ok, I know everyone is eager to share their expertise but straight giving the kid the answer does little good.
#EnTHuSiAsTx94
I was able to pass all of the tests with three statements. Here is a hint: Try using the string replace method. Here is the method signature:
String replace(CharSequence target, CharSequence replacement)
On a minor note, the first condition in your if statement can be simplified from:
str.contains(".xyz") == false
to:
!str.contains(".xyz")
The contains method already returns true or false, so there is no need for the explicit equals comparison.
public boolean xyzThere(String str) {
return str.startsWith("xyz") || str.matches(".*[^.]xyz.*");
}
You can use the equivalent java code for the following solution:
def xyz_there(str):
pres = str.count('xyz')
abs = str.count('.xyz')
if pres>abs:
return True
else:
return False
Ok, let's translate your question into a regexp:
^ From the start of the string
(|.*[^\.]) followed by either nothing or any amount of any chars and and any char except .
xyz and then xyz
Java code:
public static boolean xyzThere(String str) {
return str.matches("^(|.*[^\\.])xyz");
}
boolean flag = false;
if(str.length()<=3){
flag = str.contains("xyz");
}
for (int i = 0; i < str.length()-3; i++) {
if (!str.substring(i, i+3).equals("xyz") &&
str.substring(i, i+4).equals(".xyz")) {
flag=false;
}else{
if(str.contains("xyz")) flag=true;
}
}
return flag;
public boolean xyzThere(String str) {
boolean res=false;
if(str.length()<3)res=false;
if(str.length()==3){
if(str.equals("xyz"))res=true;
else res=false;
}
if(str.length()>3){
for(int i=0;i<str.length()-2;i++){
if(str.charAt(i)=='x' && str.charAt(i+1)=='y' && str.charAt(i+2)=='z'){
if(i==0 || str.charAt(i-1)!='.')res=true;
}
}
}
return res;
}
public class XyzThereDemo {
public static void main(String[] args) {
System.out.println(xyzThere("abcxyz"));
System.out.println(xyzThere("abc.xyz"));
System.out.println(xyzThere("xyz.abc"));
}
public static boolean xyzThere(String str) {
int xyz = 0;
for (int i = 0; i < str.length() - 2; i++) {
if (str.charAt(i) == '.') {
i++;
continue;
}
String sub = str.substring(i, i + 3);
if (sub.equals("xyz")) {
xyz++;
}
}
return xyz != 0;
}
}
Another method
public boolean xyzThere(String str) {
if(str.startsWith("xyz")) return true;
for(int i=0;i<str.length()-3;i++) {
if(str.substring(i+1,i+4).equals("xyz") && str.charAt(i)!='.') return true;
}
return false;
}
public boolean xyzThere(String str) {
if (str.startsWith("xyz")){
return true;
}
for (int i = 0; i < str.length()-2; i++) {
if (str.subSequence(i, i + 3).equals("xyz") && !(str.charAt(i-1) == '.')) {
return true;
}
}
return false;
}
This is the best possible and easiest way to solve this question with very simple logic:
def xyz_there(str):
for i in range(len(str)):
if str[i-1]!= '.' and str[i:i+3]=='xyz' :
return True
return False
public boolean xyzThere(String str) {
boolean flag = false;
if (str.startsWith("xyz"))
{
return true;
}
for (int i = 0; i < str.length() - 3; i++)
{
if (str.charAt(i) != '.' && str.charAt(i + 1) == 'x'
&& str.charAt(i + 2) == 'y' && str.charAt(i + 3) == 'z')
{
flag = true;
break;
}
}
return flag;
}
def xyz_there(str1):
for i in range(len(str1)):
if str1[i-1] != '.' and str1[i:i+3] == 'xyz':
return True
else:
return False
def xyz_there(str):
if '.xxyz' in str:
return'.xxyz' in str
if '.' in str:
a=str.replace(".xyz","")
return 'xyz' in a
if '.' not in str:
return 'xyz' in str
'''python
def xyz_there(str):
dot=str.find('.') # if period is present in str if not dot==-1
if dot==-1: # if yes dot will show position of period
return 'xyz' in str
elif dot!=-1: #if period is present at position dot
if 'xyz' in str[:dot]:
return True
while str[dot+1:].find('.')!=-1: #while another period is present
if '.xyz' in str[dot+1:]==False: # .xyz will not be counted
return True
else:
dot=dot+str[dot+1:].find('.')+2 #now dot=previous dot+new dot+2
else:
return 'xyz' in str[dot+2:]
'''
def xyz_there(str):
list = [i for i in range(len(str)) if str.startswith('xyz', i)]
if list == []:
return False
else:
found = 0
for l in list:
if str[l-1:l+3] != ".xyz":
found += 1
if found >=1:
return True
else:
return False
simple solution just by replace and check the "xyz " in a thats it
def xyz_there(str):
a=str.replace('.xyz','')
return 'xyz' in a

Recursive Function : Check for palindrome in Java

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));
}

How to check if a string is numeric? [duplicate]

This question already has answers here:
How to check if a String is numeric in Java
(41 answers)
Closed 6 years ago.
I have a gpa program, and it works with the equalsIgnoreCase() method which compares two strings, the letter "a" to the user input, which checks if they put "a" or not. But now I want to add an exception with an error message that executes when a number is the input. I want the program to realize that the integer input is not the same as string and give an error message. Which methods can I use to compare a type String variable to input of type int, and throw exception?
Many options explored at http://www.coderanch.com/t/405258/java/java/String-IsNumeric
One more is
public boolean isNumeric(String s) {
return s != null && s.matches("[-+]?\\d*\\.?\\d+");
}
Might be overkill but Apache Commons NumberUtils seems to have some helpers as well.
If you are allowed to use third party libraries, suggest the following.
https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/math/NumberUtils.html
NumberUtils.isDigits(str:String):boolean
NumberUtils.isNumber(str:String):boolean
Use this
public static boolean isNum(String strNum) {
boolean ret = true;
try {
Double.parseDouble(strNum);
}catch (NumberFormatException e) {
ret = false;
}
return ret;
}
You can also use ApacheCommons StringUtils.isNumeric - http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html#isNumeric(java.lang.String)
Simple method:
public boolean isBlank(String value) {
return (value == null || value.equals("") || value.equals("null") || value.trim().equals(""));
}
public boolean isOnlyNumber(String value) {
boolean ret = false;
if (!isBlank(value)) {
ret = value.matches("^[0-9]+$");
}
return ret;
}
Use below method,
public static boolean isNumeric(String str)
{
try
{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
If you want to use regular expression you can use as below,
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumeric(String string) {
if (string == null || string.isEmpty()) {
return false;
}
int i = 0;
int stringLength = string.length();
if (string.charAt(0) == '-') {
if (stringLength > 1) {
i++;
} else {
return false;
}
}
if (!Character.isDigit(string.charAt(i))
|| !Character.isDigit(string.charAt(stringLength - 1))) {
return false;
}
i++;
stringLength--;
if (i >= stringLength) {
return true;
}
for (; i < stringLength; i++) {
if (!Character.isDigit(string.charAt(i))
&& string.charAt(i) != '.') {
return false;
}
}
return true;
}
I wrote this little method lastly in my program so I can check if a string is numeric or at least every single char is a number.
private boolean isNumber(String text){
if(text != null || !text.equals("")) {
char[] characters = text.toCharArray();
for (int i = 0; i < text.length(); i++) {
if (characters[i] < 48 || characters[i] > 57)
return false;
}
}
return true;
}
You can use Character.isDigit(char ch) method or you can also use regular expression.
Below is the snippet:
public class CheckDigit {
private static Scanner input;
public static void main(String[] args) {
System.out.print("Enter a String:");
input = new Scanner(System.in);
String str = input.nextLine();
if (CheckString(str)) {
System.out.println(str + " is numeric");
} else {
System.out.println(str +" is not numeric");
}
}
public static boolean CheckString(String str) {
for (char c : str.toCharArray()) {
if (!Character.isDigit(c))
return false;
}
return true;
}
}
Here's how to check if the input contains a digit:
if (input.matches(".*\\d.*")) {
// there's a digit somewhere in the input string
}
To check for all int chars, you can simply use a double negative.
if (!searchString.matches("[^0-9]+$")) ...
[^0-9]+$ checks to see if there are any characters that are not integer, so the test fails if it's true. Just NOT that and you get true on success.

Categories