Recursive removal of characters in Java - java

As an exercise, the code block below intends to recursively go through a string and remove all the of the "x" characters. It does that, but I would like to keep track of the newStr without passing it as a parameter in the method. Is there anyway to move it into the method body?
Thanks!
public static String deathToX(String str, String newStr) {
//look for x char
if(str.substring(0, 1).equals("x")) {
//do nothing
} else {
//add non-x char to newStr
newStr += str.charAt(0);
}
if(str.length() == 1) {
return newStr;
}
return deathToX(str.substring(1), newStr);
}
public static void main(String[] args) {
System.out.println("Return: " + deathToX("xnoxmore", ""));
}

Well, you could change the code to:
public static String deathToX(String str)
{
// Termination case
if (str.length() == 0)
{
return str;
}
// Work out whether or not we want the first character
String prefix = str.startsWith("x") ? "" : str.substring(0, 1);
// Let the recursive call handle the rest of the string, and return
// the prefix (empty string or the first character) followed by the
// x-stripped remainder.
return prefix + deathToX(str.substring(1));
}
Is that the sort of thing you were thinking of?
Of course, this is a horribly inefficient way of doing string manipulation, but I assume you're more interested in the recursive nature of things.

I would like to keep track of the newStr without passing it as a parameter in the method.
Why? Passing the intermediary result into the function is often required in functional-style recursive programming. What I do is make a function that handles the bulk of the work and accepts the accumulator, and make a wrapper function that calls the previous one with the required starter value:
private static String deathToX0(String str, String newStr) {
// the original implementation
}
public static String deathToX(String str) {
return deathToX(str, "");
}
As an aside, you might not want to use a String for the intermediate result because of the copying involved. A StringBuilder would be faster.

The short answer is yes... with recursion typically on the way down the tree you work out the bit at each level in this case blank or the current character. So the return statement should call itself recursively then at the bottom of the tree the answer you wanted is reconstructed by adding together the sections at each level.
public static String deathToX(String str){
if (!str.isEmpty()){
return (str.substring(0, 1).equals("x") ? "" : str.substring(0, 1)) + deathToX(str.substring(1));
}else{
return "";
}
}
public static void main(String[] args){
System.out.println("Return: " + deathToX("xnoxmore"));
}
In the sample above I used the shorthand if format to put it all on one line but you could expand it out. You should be able to see that the recursive function recurses on the return statement and I put in a special case for the last level. If you were to split it and put this levels answer in a local variable e.g. tmp then you would use:
return tmp + deathToX(str.substring(1));
Remember recursion means that the current execution is only paused until the lower ones finish so you can happily store info to recover on your way back up. Hope this helps :)

public class solution {
// Return the changed string
public static String removeX(String input){
if(input.equals("") || input.equals("x"))
return "";
String returnStr="";
removeX(input.substring(1));
for(int i=0;i<input.length();i++)
{
if(input.charAt(i)=='x')
continue;
else
returnStr+=input.charAt(i);
}
return returnStr;
}
}
This is my approach. This code goes to the end of the string, if it gets X as last string, it returns ""(nothing), then it checks the whole substring for "x", if its present in the string, it will continue, else it will append rest character to that string and it goes on.
Finally returns the updated string.!
Hope this helps..!! well, this is my first contribution here :)

Related

recursion moving char to the end of the string

i need to get a string and rearrange it with recursion by getting char and by that char i have to move that char everywhere on the string to the end
like "Hello world!" ,'l' => "Heo word!lll"
i have problems understading the recursion way of thinking
so i started with this:
public static String ChToLast (String str, char ch){
if(str.indexOf(ch)== -1){
return str;
}else{
if(str.indexOf(0) == ch){
return str;
}
}
thank you for your help :)
Recursion is the practise of reusing your method inside itself. In this case, I will provide a solution to explain what happens:
public static String chrToLast(String str, char ch) {
//This if statement details the end condition
if(str.length() < 1) {
return "";
}
String newString = str.substring(1); //Create new string without first character
if(str.indexOf(ch) == 0) { //This happens when your character is found
return chrToLast(newString, ch) + ch;
} else { //This happens with all other characters
return str.charAt(0) + chrToLast(newString, ch);
}
}
If you execute:
chrToLast("Hello, World!", 'l')
This will result in the desired result: Heo, Word!lll
Process
In general, this method works by checking which character is currently the first in the given string, and then deciding what to do. If the first character is the same as the one your looking for (l), it will then remove that character from the string and use chrToLast on that new string. But, it also adds the character it found to the end of the result by using + ch. It continues to do this until there are no more characters left, which is what the end condition is for.
The end condition
The end condition returns an empty string "" because that is what is called the base case of the algorithm. You can think of a recursive algorithm as something solving a problem by calling itself a number of times. By calling themselves, recursive algorithms move towards a base. In this particular case, it does that by subtracting one character off the string each time the method is executed. Once there are no characters left, it reaches the base case which is "", where the string is finally empty and no characters can be subtracted anymore. (Hence it returns nothing as it's final state)
I hope this answers your question. It's important to understand this concept, as it is very powerful. Try to study the code and comment if something's not clear.
Something that can also help is by executing this code in an IDE and using the debugger to walk through its execution. You can then see for yourself what the flow of the program is, and see the value of the variables in play.
If you use recursion, it will be pretty expensive call for the result you are expecting. Lot of movement of String or charArray elements, eitherway you do. I don't see its a wiser choice. I would do it this way, it will be of space complexity O(2n) & performance complexity O(n).
public class Solve {
public static void main(String[] args) {
System.out.println(ChToLast("Hello world!", 'l'));
}
public static String ChToLast(String str, char ch) {
char[] chars = str.toCharArray();
char[] modChars = new char[chars.length];
int i = 0;
for(char element : chars){
if(ch != element){
modChars[i++] = element;
}
}
Arrays.fill(modChars, i, chars.length , ch);
return new String(modChars);
}
}
If you use while loop and write a method to check if that string means perfect statement then that may work for you
Here you would need some help of NLP concept to check everytime if arranged chars are making any statement or are grammatically correct.
This will help

How can I compute the previous and next chars?

My goal is to return a string that is made up of characters that are 1 before and 1 after each character in the given string in the ASCII table.
For example, dog should return cenpfh.
public String encrypt(String s) {
if (s.length() == 1) {
String one = "";
one += (s.charAt(0)-1) + (s.charAt(0)+1);
return one;
} else { .. }
}
This is the code I have so far, and I have no idea how to continue. This doesn't even work for a single character, for example, "172" is returned for "V". Could anyone point me in the right direction? Really stumped right now.
If you have to use recursion, you can try something like that:
public static String encrypt(final String s) {
if (s.length() == 1) {
final char c = s.charAt(0);
return new String(new char[] {(char) (c - 1), (char) (c + 1)});
} else {
return encrypt(s.substring(0, 1)) + encrypt(s.substring(1));
}
}
the main idea here:
if input length is 1 symbol - we know what to do and just perform "encryption"
if input length is more than 1 symbol - we split string into "first symbol" and "rest of the string" and call itself on both parts
This is fairly tricky stuff for a beginner, but it's good stuff to encounter early and understand.
"" + 172
results in the string "172"
"" + 'V'
results in the string "V".
V and 172 are both represented internally as the same number, so what's the difference? The difference is that the compiler keeps track of the type of the value. 'V' has a type of char. 172 has a type of int.
When you perform an expression using a mixture of types, the compiler has to decide what the type of the result is. This will influence how that result is handled by routines such String concatenation.
As it happens when you subtract an int from a char, the type of the result is an int (the Java spec tells you this).
You can get around it by casting the type to something else.
(char) 172 is 'V'
(int) 'V' is 172.
So:
one += (char) (s.charAt(0)-1) + (char)(s.charAt(0)+1);
Recursion is a separate topic. Recursion works for handling sequences (a String is a sequence of characters) when you can do a chunk of work on a part of the sequence, leaving you with a new, shorter sequence, that you can do the same job on -- until finally you have the simplest case, which you simply return.
The simplest case, the one where the method returns without recursively calling itself, is called the terminating case. You need at least one terminating case, otherwise the recursive method will keep calling itself until Java runs out of memory for storing method states.
You have chosen your terminating case as being a one char string. I would instead pick a zero length string:
public void encrypt(String s) {
if("".equals(s)) {
return "";
} else {
// do something with a string that's guaranteed >1 char
}
Now you just have to work out how to replace that comment, by using up the guaranteed one char, and calling encrypt() to handle what's left.
public void encrypt(String s) {
if("".equals(s)) {
return "";
} else {
return encodeOneChar(s.charAt(0)) +
encrypt(x.substring(1));
}
}
That's it:
when called with an empty string, encode() returns an empty string.
when called with a non-empty string, encode processes the first char
and calls itself to deal with a string that's one shorter.
Some languages, like Haskell, make recursion easier to understand, by representing the cases as pattern matching statements.
encrypted "" == ""
encrypted s == encryptChar(head(s)) + encrypted(tail(s))
(that's not real Haskell, but it illustrates the pattern.)
Recursion isn't quite as easy to read in Java, but the pattern is still there. if(terminating case) { return answer for terminating case } else { calculate something, call self, return combined result }
I'll leave you to implement private String encodeOneChar(char c)
Note that recursion isn't a good solution to your actual task in Java -- except in the sense that your goal is to understand recursion.
There is no recursion needed. Just iterate over input chars and collect result in a StringBuilder:
public static String encrypt(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
sb.append((char)(c - 1)).append((char)(c + 1));
}
return sb.toString();
}
Note that explicit cast to char is required here, because s.charAt(i) - 1 evaluates to int and without cast is processed by overloaded append(int i) method.
Okay, recursion. Here I split input into 2 halves and process each by using the same encryptRecursively() method, then join results. Each part, when passed to the method, is again split into 2 parts, etc, until size becomes 0 or 1 (thus we get a very simple implementation of Divide and Conquer):
public static String encryptRecursively(String s) {
if (s.isEmpty())
return "";
else if (s.length() == 1) {
char c = s.charAt(0);
return new String(new char[] { (char)(c - 1), (char)(c + 1) });
} else {
int mid = s.length() / 2;
return encryptRecursively(s.substring(0, mid)) // process first half of input
+ encryptRecursively(s.substring(mid)); // second half
}
}
You don't need a recursion but a simple for-loop through all chars in the word. You get the value of char with s.charAt(...), but you have to convert it back to char for the desired resut. Append them to StringBuilder and return its String as the output of the method:
public static String encrypt(String s) {
StringBuilder sb = new StringBuilder();
for (int i=0; i<s.length(); i++) {
char a = (char)(s.charAt(i)-1);
char b = (char)(s.charAt(i)+1);
sb.append(a).append(b);
}
return sb.toString();
}
Here is the recursion method as demanded:
public static String encrypt(String s) {
if (s.length() == 1) {
StringBuilder sb = new StringBuilder();
char a = (char)(s.charAt(0)-1);
char b = (char)(s.charAt(0)+1);
return sb.append(a).append(b).toString();
} else {
return encrypt(s.substring(0, 1)) + encrypt(s.substring(1, s.length()));
}
You can try this:
one += (char)(((int)s.charAt(0))-1);
one += (char)(((int)s.charAt(0))+1);
Input:
V
Output:
UW

Removing leading zero in java code

May I know how can I remove the leading zero in JAVA code? I tried several methods like regex tools
"s.replaceFirst("^0+(?!$)", "") / replaceAll("^0*", "");`
but it's seem like not support with my current compiler compliance level (1.3), will have a red line stated the method replaceFirst(String,String)is undefined for the type String.
Part of My Java code
public String proc_MODEL(Element recElement)
{
String SEAT = "";
try
{
SEAT = setNullToString(recElement.getChildText("SEAT")); // xml value =0000500
if (SEAT.length()>0)
{
SEAT = SEAT.replaceFirst("^0*", ""); //I need to remove leading zero to only 500
}
catch (Exception e)
{
e.printStackTrace();
return "501 Exception in proc_MODEL";
}
}
}
Appreciate for help.
If you want remove leading zeros, you could parse to an Integer and convert back to a String with one line like
String seat = "001";// setNullToString(recElement.getChildText("SEAT"));
seat = Integer.valueOf(seat).toString();
System.out.println(seat);
Output is
1
Of course if you intend to use the value it's probably better to keep the int
int s = Integer.parseInt(seat);
System.out.println(s);
replaceFirst() was introduced in 1.4 and your compiler pre-dates that.
One possibility is to use something like:
public class testprog {
public static void main(String[] args) {
String s = "0001000";
while ((s.length() > 1) && (s.charAt(0) == '0'))
s = s.substring(1);
System.out.println(s);
}
}
It's not the most efficient code in the world but it'll get the job done.
A more efficient segment without unnecessary string creation could be:
public class testprog {
public static void main(String[] args) {
String s = "0001000";
int pos = 0;
int len = s.length();
while ((pos < len-1) && (s.charAt(pos) == '0'))
pos++;
s = s.substring(pos);
System.out.println(s);
}
}
Both of those also handle the degenerate cases of an empty string and a string containing only 0 characters.
Using a java method str.replaceAll("^0+(?!$)", "") would be simple;
First parameter:regex -- the regular expression to which this string is to be matched.
Second parameter: replacement -- the string which would replace matched expression.
As stated in Java documentation, 'replaceFirst' only started existing since Java 1.4 http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#replaceFirst(java.lang.String,%20java.lang.String)
Use this function instead:
String removeLeadingZeros(String str) {
while (str.indexOf("0")==0)
str = str.substring(1);
return str;
}

How do you check to compare a string value to each element in an array?

So I have a String Array (sConsonantArray) and have all of the consonants stored in it.
String[] sConsonantArray = new String[] {"q","w","r","t","p","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m"};
I need to check if the second last value of a word (sWord) equals a value in the array and I don't know how to call each value in the array to compare the letters other than doing sConsonantArray[5] (checking them each one at a time). I am looking for an easier way to call them, thanks for your help. Also, it doesn't appear that the (&&) operator will work, other suggestions would be appreciated.
else if (sWord.substring(sWord.length()-2,sWord.length()-1).equals(sConsonantArray I DONT KNOW WHAT TO PUT HERE)) && (sWord.substring(sWord.length()-1,sWord.length()).equalsIgnoreCase("o"))
{
System.out.println("The plural of " + sWord + " is " + (sWord + "es"));
}
It seems to me that it would be simpler to have the consonants as a string and then use charAt:
private static final String CONSONANTS = "bcdfgh...z";
if (CONSONANTS.indexOf(word.charAt(word.length() - 2)) {
...
}
If you really want to use an array, you could change your array to be in order and then call Arrays.binarySearch. Another alternative would be to create a HashSet<String> of the consonants and use contains on that.
Try something like
else if (Arrays.asList(sConsonantArray).contains(
sWord.substring(sWord.length()-2,sWord.length()-1))
&& (sWord.substring(sWord.length()-1,sWord.length()).equalsIgnoreCase("o"))) {
// do something
}
or Write a small Util method
public static boolean isInConstants(String yourString){
String[] sConsonantArray = new String[] {"q","w...}
for (String item : sConsonantArray) {
if (yourString.equalsIgnoreCase(item)) {
return true;
}
}
return false;
}

Is there an existing library method that checks if a String is all upper case or lower case in Java?

I know there are plenty of upper() methods in Java and other frameworks like Apache commons lang, which convert a String to all upper case.
Are there any common libraries that provide a method like isUpper(String s) and isLower(String s), to check if all the characters in the String are upper or lower case?
EDIT:
Many good answers about converting to Upper and comparing to this. I guess I should have been a bit more specific, and said that I already had thought of that, but I was hoping to be able to use an existing method for this.
Good comment about possible inclusion of this in apache.commons.lang.StringUtils.
Someone has even submitted a patch (20090310). Hopefully we will see this soon.
https://issues.apache.org/jira/browse/LANG-471
EDIT:
What I needed this method for, was to capitalize names of hotels that sometimes came in all uppercase. I only wanted to capitalize them if they were all lower or upper case.
I did run in to the problems with non letter chars mentioned in some of the posts, and ended up doing something like this:
private static boolean isAllUpper(String s) {
for(char c : s.toCharArray()) {
if(Character.isLetter(c) && Character.isLowerCase(c)) {
return false;
}
}
return true;
}
This discussion and differing solutions (with different problems), clearly shows that there is a need for a good solid isAllUpper(String s) method in commons.lang
Until then I guess that the myString.toUpperCase().equals(myString) is the best way to go.
Now in StringUtils isAllUpperCase
This if condition can get the expected result:
String input = "ANYINPUT";
if(input.equals(input.toUpperCase())
{
// input is all upper case
}
else if (input.equals(input.toLowerCase())
{
// input is all lower case
}
else
{
// input is mixed case
}
Not a library function unfortunately, but it's fairly easy to roll your own. If efficiency is a concern, this might be faster than s.toUpperCase().equals(s) because it can bail out early.
public static boolean isUpperCase(String s)
{
for (int i=0; i<s.length(); i++)
{
if (!Character.isUpperCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Edit: As other posters and commenters have noted, we need to consider the behaviour when the string contains non-letter characters: should isUpperCase("HELLO1") return true or false? The function above will return false because '1' is not an upper case character, but this is possibly not the behaviour you want. An alternative definition which would return true in this case would be:
public static boolean isUpperCase2(String s)
{
for (int i=0; i<s.length(); i++)
{
if (Character.isLowerCase(s.charAt(i)))
{
return false;
}
}
return true;
}
Not that i know.
You can copy the string and convert the copy to lower/upper case and compare to the original one.
Or create a loop which checks the single characters if the are lower or upper case.
This method might be faster than comparing a String to its upper-case version as it requires only 1 pass:
public static boolean isUpper(String s)
{
for(char c : s.toCharArray())
{
if(! Character.isUpperCase(c))
return false;
}
return true;
}
Please note that there might be some localization issues with different character sets. I don't have any first hand experience but I think there are some languages (like Turkish) where different lower case letters can map to the same upper case letter.
Guava's CharMatchers tend to offer very expressive and efficient solutions to this kind of problem.
CharMatcher.javaUpperCase().matchesAllOf("AAA"); // true
CharMatcher.javaUpperCase().matchesAllOf("A SENTENCE"); // false
CharMatcher.javaUpperCase().or(CharMatcher.whitespace()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaUpperCase().or(CharMatcher.javaLetter().negate()).matchesAllOf("A SENTENCE"); // true
CharMatcher.javaLowerCase().matchesNoneOf("A SENTENCE"); // true
A static import for com.google.common.base.CharMatcher.* can help make these more succinct.
javaLowerCase().matchesNoneOf("A SENTENCE"); // true
Try this, may help.
import java.util.regex.Pattern;
private static final String regex ="^[A-Z0-9]"; //alpha-numeric uppercase
public static boolean isUpperCase(String str){
return Pattern.compile(regex).matcher(str).find();
}
with this code, we just change the regex.
I realise that this question is quite old, but the accepted answer uses a deprecated API, and there's a question about how to do it using ICU4J. This is how I did it:
s.chars().filter(UCharacter::isLetter).allMatch(UCharacter::isUpperCase)
If you expect your input string to be short, you could go with myString.toUpperCase().equals(myString) as you suggested. It's short and expressive.
But you can also use streams:
boolean allUpper = myString.chars().noneMatch(Character::isLowerCase);
You can use java.lang.Character.isUpperCase()
Then you can easily write a method that check if your string is uppercase (with a simple loop).
Sending the message toUpperCase() to your string and then checking if the result is equal to your string will be probably slower.
Here's a solution I came up with that's a bit universal as it doesn't require any libraries or special imports, should work with any version of Java, requires only a single pass, and should be much faster than any regex based solutions:
public static final boolean isUnicaseString(String input) {
char[] carr = input.toCharArray();
// Get the index of the first letter
int i = 0;
for (; i < carr.length; i++) {
if (Character.isLetter(carr[i])) {
break;
}
}
// If we went all the way to the end above, then return true; no case at all is technically unicase
if (i == carr.length) {
return true;
}
// Determine if first letter is uppercase
boolean firstUpper = Character.isUpperCase(carr[i]);
for (; i < carr.length; i++) {
// Check each remaining letter, stopping when the case doesn't match the first
if (Character.isLetter(carr[i]) && Character.isUpperCase(carr[i]) != firstUpper) {
return false;
}
}
// If we didn't stop above, then it's unicase
return true;
}

Categories

Resources