I have a string which i have to split into substrings of equal length if possible. I have found this solution which will only work if the string length is a multiple of 4.
String myString = "abcdefghijklm";
String[] split = myString.split("(?<=\\G....)");
This will produce:
[abcd, efgh, ijkl, m]
What i need is to split "from the end of the string". My desired output should look like :
[a, bcde, fghi, jklm]
How do i achieve this?
This ought to do it:
String[] split = myString.split("(?=(....)+$)");
// or
String[] split = myString.split("(?=(.{4})+$)");
What it does is this: split on the empty string only if that empty string has a multiple of 4 chars ahead of it until the end-of-input is reached.
Of course, this has a bad runtime (O(n^2)). You can get a linear running time algorithm by simply splitting it yourself.
As mentioned by #anubhava:
(?!^)(?=(?:.{4})+$) to avoid empty results if string length is in multiples of 4
Regex are really unnecessary for this. I also don't think this is a good problem for recursion. The following is an O(n) solution.
public static String[] splitIt(String input, int splitLength){
int inputLength = input.length();
ArrayList<String> arrayList = new ArrayList<>();
int i = inputLength;
while(i > 0){
int beginIndex = i - splitLength > 0 ? i - splitLength : 0;
arrayList.add(0, input.substring(beginIndex, i));
i -= splitLength;
}
return arrayList.toArray(new String[0]);
}
No need to use a regular expression. Instead, you can recursively build a list of head strings and return the tail.
import java.util.*;
public class StringChunker {
public static void main(String[] args) {
String str = "abcdefghijklm";
System.out.println(Arrays.toString(chunk(str, 4))); // [abcd, efgh, ijkl, m]
System.out.println(Arrays.toString(chunk(str, 4, true))); // [a, bcde, fghi, jklm]
}
public static String[] chunk(String str, int size) throws IllegalArgumentException {
return chunk(str, size, false);
}
public static String[] chunk(String str, int size, boolean reverse) throws IllegalArgumentException {
return chunk(str, size, reverse, new ArrayList<String>());
}
private static String[] chunk(String str, int size, boolean reverse, List<String> chunks) throws IllegalArgumentException {
if (size < 1) {
throw new IllegalArgumentException("size must be greater than 0");
}
if (str.length() < size) {
if (reverse) {
chunks.add(0, str); // Reverse adds to the front of the list
} else {
chunks.add(str); // Add to the end of the list
}
return chunks.toArray(new String[chunks.size()]); // Convert to an array
} else {
String head, tail;
if (reverse) {
head = str.substring(str.length() - size, str.length());
tail = str.substring(0, str.length() - size);
chunks.add(0, head);
} else {
head = str.substring(0, size);
tail = str.substring(size);
chunks.add(head);
}
return chunk(tail, size, reverse, chunks);
}
}
}
Related
I want to print number of possible non-empty sequences of letters .
Eg.
String str="ABC";
Expected output is
A,B,C
AB,AC,BC,BA,CA,CB
ABC,ACB,BAC,BCA,CAB,CBA`
But i get the below output which is incorrect. How to fix my code
BB CC A AB ACC BC ABC AC B BBC CCC BCC C CBC CB
I have written the below code using Recurion
String tiles = "ABC";
Set<String> ans = new HashSet<>();
solve(tiles, 0, "", ans);
public static void solve(String tiles, int idx, String output, Set<String> ans) {
ans.add(output);
if (idx >= tiles.length()) {
return;
}
for (int i = idx; i < tiles.length(); i++) {
solve(tiles, idx + 1, output + tiles.charAt(i), ans);
}
}
This is how recursion tree would look like for str="AAB"
You need to ignore the first passing of the "" from output and then you need to ignore each letter you already passed through
public static void main(String[] args) {
String tiles = "ABC";
List<String> ans = new ArrayList<>();
solve(tiles, "", ans);
System.out.println(ans);
}
public static void solve(String tiles, String output, List<String> ans) {
if (!output.equals("")) ans.add(output);
for (int i = 0; i < tiles.length(); i++) {
String str = tiles.substring(0, i) + tiles.substring(i + 1);
solve(str, output + tiles.charAt(i), ans);
}
}
Output
[A, AB, ABC, AC, ACB, B, BA, BAC, BC, BCA, C, CA, CAB, CB, CBA]
you can try this
public class Permutation {
public static List<String> getPermutations(String str) {
Set<String> permutations = new HashSet<>();
permute(str, "", permutations);
return new ArrayList<>(permutations);
}
private static void permute(String string, String prefix, Set<String> permutations) {
if (string.length() == 0) {
permutations.add(prefix);
} else {
for (int i = 0; i < string.length(); i++) {
char charAt = string.charAt(i);
String remainingString = string.substring(0, i) + string.substring(i + 1);
permute(remainingString, prefix + charAt, permutations);
}
}
}
}
The "permute" method takes in 3 parameters: a string, a prefix string and a set of permutations.
The "permute" method takes in 3 parameters: a string, a prefix string and a set of permutations.
If the input string is not empty, it uses a for loop to iterate through the characters of the input string.
For each iteration, it gets the character at the current index, creates a new string by removing that character from the input string.
it then calls the permute method 3 times:
it then calls the permute method 3 times:
One with the original string and prefix
One with the remaining string and prefix
This way, the function explores all the possible permutations of the characters in the input string, including the option of not having one of the characters in the permutation and the permutation of positions, without including an empty string as an option.
Then you use like:
Permutation p = new Permutation();
List<String> permutations = p.getPermutations("abc");
Make 1 change:
Set<String> ans = new TreeSet<>(Comparators.comparing(String::length).thenComparing(s -> s));
It's a quite popular backtracking problem. You can find almost same problem here:
https://leetcode.com/problems/subsets/
The input are numbers instead of characters but the idea is the same.
You can switch to the solution tab and explore different answers:
https://leetcode.com/problems/subsets/solutions/
I have a string which I want to split after every n characters and store the same in an array of strings, but this should ignore all the whitespaces.
For example I have a string as follows,
String str = "This is a String which needs to be splitted after every 10 characters";
The output should be,
["This is a Str", "ing which nee", "ds to be split", "ted after ev", "ery 10 chara", "cters"]
(Edit) --> I am using the function below. How can I store this in an array of Strings.
As seen in the output it ignores indexes of all the whitespaces. Is there any way to do it in java.
public static String test(int cnt, String string) {
AtomicInteger n = new AtomicInteger(cnt);
return string
.chars()
.boxed()
.peek(value -> {
if (!Character.isWhitespace(value)) {
n.decrementAndGet();
}
})
.takeWhile(value -> n.get() >= 0)
.map(Character::toString)
.collect(Collectors.joining());
I have used a standard approach with looping through the string and counting chars:
public static void main(String[] args) throws ParseException {
String str = "This is a String which needs to be splitted after every 10 characters";
System.out.println(split(str, 10));
}
public static List<String> split(String string, int splitAfter) {
List<String> result = new ArrayList<String>();
int startIndex = 0;
int charCount = 0;
for (int i = 0; i < string.length(); i++) {
if (charCount == splitAfter) {
result.add(string.substring(startIndex, i));
startIndex = i;
charCount = 0;
}
// only count non-whitespace characters
if (string.charAt(i) != ' ') {
charCount++;
}
}
// check if startIndex is less than string length -> if yes, then last element wont be 10 characters long
if (startIndex < string.length()) {
result.add(string.substring(startIndex));
}
return result;
}
And the result differs slightly from what you posted, but looking at your expected result, it doesn't quite match the description anyways:
[This is a Str, ing which ne, eds to be spl, itted after, every 10 cha, racters]
I am trying to create a program that takes int t and String s from the user. String s will be split at the spaces and put into a String[] Strings. When t=1, the main method prints Strings, reverses its elements using recursion in method reverse that takes two ints (the indices of the ends) and a String array, then print the reversed String array. The code below compiled with no problems, but I got an ArrayIndexOutOfBounds error right when I hit enter inputting 1 for t. The error references lines 11 and 34, but I'm scratching my head because I can't see anything wrong.
import java.util.Scanner;
public class Recursion
{
public static String[] reverse(int m, int n, String[] str)
{
String[] p = new String[str.length];
if (m == n) return str;
else if (m > n) return str;
else
{
str[m] = p[n];
str[n] = p[m];
return reverse(m+1, n-1, str);
}
}
public static void main(String[] args)
{
Scanner enter = new Scanner(System.in);
System.out.print("t = ");
int t = enter.nextInt();
System.out.print("s = ");
String str = enter.nextLine();
String[] Strings = str.split(" ");
int k = Strings.length;
if (t == 1)
{
for (String s : Strings)
System.out.println(s);
System.out.println("The reversal is");
reverse(k-k, k, Strings);
for (String s : Strings)
System.out.println(s);
}
}
}
Array in java start from 0 to length -1
see Arrays for more details.
so passing k will throw ArrayIndexOutOfBounds use below code
reverse(0, k-1, Strings);
I'm writing an Android word app. My code includes a method that would find all combinations of the string and the substrings of a 7 letter string with a minimum of length 3. Then compare all available combination to every word in the dictionary to find all the valid words. I'm using a recursive method. Here's the code.
// Gets all the permutations of a string.
void permuteString(String beginningString, String endingString) {
if (endingString.length() <= 1){
if((Arrays.binarySearch(mDictionary, beginningString.toLowerCase() + endingString.toLowerCase())) >= 0){
mWordSet.add(beginningString + endingString);
}
}
else
for (int i = 0; i < endingString.length(); i++) {
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
permuteString(beginningString + endingString.charAt(i), newString);
}
}
// Get the combinations of the sub-strings. Minimum 3 letter combinations
void subStrings(String s){
String newString = "";
if(s.length() > 3){
for(int x = 0; x < s.length(); x++){
newString = removeCharAt(x, s);
permuteString("", newString);
subStrings(newString);
}
}
}
The above code runs fine but when I installed it on my Nexus s I realized that it runs a bit too slow. It takes a few seconds to complete. About 3 or 4 seconds which is unacceptable.
Now I've played some word games on my phone and they compute all the combinations of a string instantly which makes me believe that my algorithm is not very efficient and it can be improved. Can anyone help?
public class TrieNode {
TrieNode a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
TrieNode[] children = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z};
private ArrayList<String> words = new ArrayList<String>();
public void addWord(String word){
words.add(word);
}
public ArrayList<String> getWords(){
return words;
}
}
public class Trie {
static String myWord;
static String myLetters = "afinnrty";
static char[] myChars;
static Sort sort;
static TrieNode myNode = new TrieNode();
static TrieNode currentNode;
static int y = 0;
static ArrayList<String> availableWords = new ArrayList<String>();
public static void main(String[] args) {
readWords();
getPermutations();
}
public static void getPermutations(){
currentNode = myNode;
for(int x = 0; x < myLetters.length(); x++){
if(currentNode.children[myLetters.charAt(x) - 'a'] != null){
//availableWords.addAll(currentNode.getWords());
currentNode = currentNode.children[myLetters.charAt(x) - 'a'];
System.out.println(currentNode.getWords() + "" + myLetters.charAt(x));
}
}
//System.out.println(availableWords);
}
public static void readWords(){
try {
BufferedReader in = new BufferedReader(new FileReader("c://scrabbledictionary.txt"));
String str;
while ((str = in.readLine()) != null) {
myWord = str;
myChars = str.toCharArray();
sort = new Sort(myChars);
insert(myNode, myChars, 0);
}
in.close();
} catch (IOException e) {
}
}
public static void insert(TrieNode node, char[] myChars, int x){
if(x >= myChars.length){
node.addWord(myWord);
//System.out.println(node.getWords()+""+y);
y++;
return;
}
if(node.children[myChars[x]-'a'] == null){
insert(node.children[myChars[x]-'a'] = new TrieNode(), myChars, x=x+1);
}else{
insert(node.children[myChars[x]-'a'], myChars, x=x+1);
}
}
}
In your current approach, you're looking up every permutation of each substring. So for "abc", you need to look up "abc", "acb", "bac", "bca", "cab" and "cba". If you wanted to find all permutations of "permutations", your number of lookups is nearly 500,000,000, and that's before you've even looked at its substrings. But we can reduce this to one lookup, regardless of length, by preprocessing the dictionary.
The idea is to put each word in the dictionary into some data structure where each element contains a set of characters, and a list of all words containing (only) those characters. So for example, you could build a binary tree, which would have a node containing the (sorted) character set "abd" and the word list ["bad", "dab"]. Now, if we want to find all permutations of "dba", we sort it to give "abd" and look it up in the tree to retrieve the list.
As Baumann pointed out, tries are well suited to storing this kind of data. The beauty of the trie is that the lookup time depends only on the length of your search string - it is independent of the size of your dictionary. Since you'll be storing quite a lot of words, and most of your search strings will be tiny (the majority will be the 3-character substrings from the lowest level of your recursion), this structure is ideal.
In this case, the paths down your trie would reflect the character sets rather than the words themselves. So if your entire dictionary was ["bad", "dab", "cab", "cable"], your lookup structure would end up looking like this:
There's a bit of a time/space trade-off in the way you implement this. In the simplest (and fastest) approach, each Node contains just the list of words, and an array Node[26] of children. This allows you to locate the child you're after in constant time, just by looking at children[s.charAt(i)-'a'] (where s is your search string and i is your current depth in the trie).
The downside is that most of your children arrays will be mostly empty. If space is an issue, you can use a more compact representation like a linked list, dynamic array, hash table, etc. However, these come at the cost of potentially requiring several memory accesses and comparisons at each node, instead of the simple array access above. But I'd be surprised if the wasted space was more than a few megabytes over your whole dictionary, so the array-based approach is likely your best bet.
With the trie in place, your whole permutation function is replaced with one lookup, bringing the complexity down from O(N! log D) (where D is the size of your dictionary, N the size of your string) to O(N log N) (since you need to sort the characters; the lookup itself is O(N)).
EDIT: I've thrown together an (untested) implementation of this structure: http://pastebin.com/Qfu93E80
See here: How to find list of possible words from a letter matrix [Boggle Solver]
The idea behind the code in the answers is as follows:
Iterate over each word dictionary.
Iterate over each letter in the word, adding it to a string and adding the string each time to an array of prefixes.
When creating string combinations, test to see that they exist in the prefix array before branching any further.
static List<String> permutations(String a) {
List<String> result=new LinkedList<String>();
int len = a.length();
if (len<=1){
result.add(a);
}else{
for (int i=0;i<len; i++){
for (String it:permutations(a.substring(0, i)+a.substring(i+1))){
result.add(a.charAt(i)+it);
}
}
}
return result;
}
I don't think adding all permutations is necessary. You can simply encapsulate the string into a PermutationString:
public class PermutationString {
private final String innerString;
public PermutationString(String innerString) {
this.innerString = innerString;
}
#Override
public int hashCode() {
int hash = 0x00;
String s1 = this.innerString;
for(int i = 0; i < s1.length(); i++) {
hash += s1.charAt(i);
}
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PermutationString other = (PermutationString) obj;
int nChars = 26;
int[] chars = new int[nChars];
String s1 = this.innerString;
String s2 = other.innerString;
if(s1.length() != s2.length()) {
return false;
}
for(int i = 0; i < s1.length(); i++) {
chars[s1.charAt(i)-'a']++;
}
for(int i = 0; i < s2.length(); i++) {
chars[s2.charAt(i)-'a']--;
}
for(int i = 0; i < nChars; i++) {
if(chars[i] != 0x00) {
return false;
}
}
return true;
}
}
A PermutationString is a string, but where two PermutationStrings are equal if they have the same frequency of characters. Thus new PermutationString("bad").equals(new PermutationString("dab")). This also holds for the .hashCode(): if the strings are permutations of each other, they will generate the same .hashCode().
Now you can simply a HashMap<PermutationString,ArrayList<String>> as follows:
HashMap<PermutationString,ArrayList<String>> hm = new HashMap<PermutationString,ArrayList<String>>();
String[] dictionary = new String[] {"foo","bar","oof"};
ArrayList<String> items;
for(String s : dictionary) {
PermutationString ps = new PermutationString(s);
if(hm.containsKey(ps)) {
items = hm.get(ps);
items.add(s);
} else {
items = new ArrayList<String>();
items.add(s);
hm.put(ps,items);
}
}
So now we iterate over all possible words in the dictionary, construct a PermutationString as key, and if the key already exists (that means that there is already a word with the same character frequencies), we simply add our own word to it. Otherwise, we add a new ArrayList<String> with the single word.
Now that we have filled up the hm with all permutations (but not that much keys), you can query:
hm.get(new PermutationString("ofo"));
This will return an ArrayList<String> with "foo" and "oof".
Testcase:
HashMap<PermutationString, ArrayList<String>> hm = new HashMap<PermutationString, ArrayList<String>>();
String[] dictionary = new String[]{"foo", "bar", "oof"};
ArrayList<String> items;
for (String s : dictionary) {
PermutationString ps = new PermutationString(s);
if (hm.containsKey(ps)) {
items = hm.get(ps);
items.add(s);
} else {
items = new ArrayList<String>();
items.add(s);
hm.put(ps, items);
}
}
Assert.assertNull(hm.get(new PermutationString("baa")));
Assert.assertNull(hm.get(new PermutationString("brr")));
Assert.assertNotNull(hm.get(new PermutationString("bar")));
Assert.assertEquals(1,hm.get(new PermutationString("bar")).size());
Assert.assertNotNull(hm.get(new PermutationString("rab")));
Assert.assertEquals(1,hm.get(new PermutationString("rab")).size());
Assert.assertNotNull(hm.get(new PermutationString("foo")));
Assert.assertEquals(2,hm.get(new PermutationString("foo")).size());
Assert.assertNotNull(hm.get(new PermutationString("ofo")));
Assert.assertEquals(2,hm.get(new PermutationString("ofo")).size());
Assert.assertNotNull(hm.get(new PermutationString("oof")));
Assert.assertEquals(2,hm.get(new PermutationString("oof")).size());
Use a Trie
Instead of testing all N! possibilities, you only follow prefix trees that lead to a result. This will significanlty reduce the amount of strings that you're checking against.
Well, you can extend your dictionary entities with array letters[] where letters[i] stays for times that i-th letter of alphabet used in this word. It'll take some additional memory, not far much than it is used now.
Then, for each word which permutations you want to check, you'll need to count number of distinct letters too and then traverse through dictiory with easy comparison procedure. If for all letters for word from dictionary number of occurrences less or equal than for word we are checking - yes, this word can be represented as permutation of substring, otherwise - no.
Complexity: it'll took O(D * maxLen) for precalculation, and O(max(N, D)) for each query.
I have been messing around with recursion today. Often a programming technique that is not used enough.
I set out to recursively reverse a string. Here's what I came up with:
//A method to reverse a string using recursion
public String reverseString(String s){
char c = s.charAt(s.length()-1);
if(s.length() == 1) return Character.toString(c);
return c + reverseString(s.substring(0,s.length()-1));
}
My question: is there a better way in Java?
The best way is not to use recursion. These stuff are usually used to teach students the recursion concept, not actual best practices. So the way you're doing it is just fine. Just don't use recursion in Java for these kind of stuff in real world apps ;)
PS. Aside what I just said, I'd choose "" as the base case of my recursive function:
public String reverseString(String s){
if (s.length() == 0)
return s;
return reverseString(s.substring(1)) + s.charAt(0);
}
If you're going to do this, you want to operate on a character array, because a String is immutable and you're going to be copying Strings all over the place if you do it that way.
This is untested and totally stream of consciousness. It probably has an OB1 somewhere. And very not-Java.
public String reverseString(String s)
{
char[] cstr = s.getChars();
reverseCStr(cstr, 0, s.length - 1);
return new String(cstr);
}
/**
* Reverse a character array in place.
*/
private void reverseCStr(char[] a, int s, int e)
{
// This is the middle of the array; we're done.
if (e - s <= 0)
return;
char t = a[s];
a[s] = a[e];
a[e] = t;
reverseCStr(a, s + 1, e - 1);
}
You don't want to nest too deeply. Divide-and-conquer is the way to go. Also reduces total size of temporary strings and is amenable to parallelisation.
public static String reverseString(String str) {
int len = str.length();
return len<=1 ? str : (
reverseString(str.substring(len/2))+
reverseString(str.substring(0, len/2))
);
}
(Not tested - this is stackoverflow.)
String.concat instead of + would improve performance at the expense of clarity.
Edit: Just for fun, a tail-recursion friendly version of the naive algorithm.
public static String reverseString(String str) {
return reverseString("", str);
}
private static String reverseString(String reversed, String forward) {
return forward.equals("") ? reversed : (
reverseString(reversed+forward.charAt(0), forward.substring(1))
);
}
Correct handling of surrogate pairs is left to the interested reader.
here is my recursive reverse function that is working fine
public static String rev(String instr){
if(instr.length()<=1){
return instr;
} else {
return (instr.charAt(instr.length()-1)+rev(instr.substring(0,instr.length()-1)) );
}
}
Just for the heck of it, here's a tail-recursive method using StringBuilder (which is generally recommended over manipulating Strings).
public String reverseString(String s_) {
StringBuilder r = new StringBuilder();
StringBuilder s = new StringBuilder(s_);
r = reverseStringHelper(r, s);
return r.toString();
}
private StringBuilder reverseStringHelper(StringBuilder r, StringBuilder s) {
if (s.length() == 0)
return r;
else
return reverseStringHelper(r.append(s.charAt(0)), s.deleteCharAt(0));
}
Untested, I haven't dealt with Java in many years, but this should be about right.
If you're writing real code (not learning recursion), use StringBuilder's reverse() method. The Java Tutorial gives this example:
String palindrome = "Dot saw I was Tod";
StringBuilder sb = new StringBuilder(palindrome);
sb.reverse(); // reverse it
System.out.println(sb);
It depends on what you define as "better". :-) Seriously, though; your solution essentially uses the maximum depth of recursion; if stack size is of a concern for your definition of "better", then you'd be better off using something like this:
public String reverseString(String s) {
if (s.length() == 1) return s;
return reverseString(s.substring(s.length() / 2, s.length() -1) + reverseString(0, s.length() / 2);
}
This is what I've found to work and use recursive. You can pass str.length() as strLength argument
private static String reverse(String str, int strLength) {
String result = "";
if(strLength > 0)
result = str.charAt(strLength - 1) + reverse(str, strLength - 1);
return result;
}
In Java, since the String is immutable, the String concatenation would be more complex than it looks like.
For every concatenation, it creates a new string copying the contents of original String resulting in a linear complexity O(n) where n is the length of the string, so for m such operations it is O(m*n), we can say it is of quadratic complexity O(n^2).
We can use a StringBuilder which has O(1) complexity for each append. Below is the recursive program using StringBuilder. This uses only n/2 stack frames, so it has less space complexity than the normal recursive call which would be like s.charAt(s.length-1) + reverse(s.subString(0, s.length-2);
public class StringReverseRecursive {
public static void main(String[] args) {
String s = "lasrever gnirts fo noitatnemelpmi evisrucer a si sihT";
StringBuilder sb = new StringBuilder(s);
reverse(s, sb, 0, sb.length() - 1);
System.out.println(sb.toString());
}
public static void reverse(String s, StringBuilder sb, int low, int high) {
if (low > high)
return;
sb.setCharAt(low, s.charAt(high));
sb.setCharAt(high, s.charAt(low));
reverse(s, sb, ++low, --high);
}
}
That's definitely how I'd go about recursively reversing a string (although it might be nice to extend it to the case of an empty string in your condition.) I don't think there is any fundamentally better way.
EDIT: It may be more efficient to operate on a character array and pass a "cutoff" length down the chain of recursion, if you get my drift, rather than making substrings. However, this is not really worth nitpicking about, since it's not a terribly efficient technique in the first place.
You capture the basic idea, but extracting the last character doesn't improve clarity. I'd prefer the following, others might not:
public class Foo
{
public static void main(String[] argv) throws Exception
{
System.out.println(reverse("a"));
System.out.println(reverse("ab"));
System.out.println(reverse("abc"));
}
public final static String reverse(String s)
{
// oft-repeated call, so reduce clutter with var
int length = s.length();
if (length <= 1)
return s;
else
return s.substring(length - 1) + reverse(s.substring(0, length - 1));
}
}
As Mehrdad noted, it's best not to use recursion. If you do use it, though, you might as well keep both the first and last character each call, thus halving the number of recursive calls. That is,
public String reverseString(String s){
int len = s.length();
if (len <= 1) {
return s;
}
char fst = s.charAt(0);
char lst = s.charAt(len - 1);
return lst + reverseString(s.substring(1, len - 2)) + fst;
}
This also handles the case of the empty string. Perhaps passing along a StringBuilder with the appropriate capacity would speed things up even more, but that's left as an exercise to the reader ;)
You can try with an external variable, and add 1 by 1 all chars:
public static String back="";
public static String reverseString(String str){
if(str.length()==0){
return back;
}else {
back+=str.charAt(str.length()-1);
lees(str.substring(0,str.length()-1));
return back;
}
}
Here is my immutable version:
String reverse(String str) {
if(str.length()<2) return str;
return reverse(str.substring(1)) +str.charAt(0);
}
and tail recursive version:
String reverseTail(String str) {
if(str.length()<2) return str;
return str.charAt(str.length()-1)+ reverseTail(str.substring(0,str.length()-1));
In this context, this is totally unnecessary, but you can simulate recursion and avoid recursion depth issues if you make your own stack.
You can iterative implement recursion, which may be necessary when you have algorithms which are inherently recursive, but also need to run them for big problem sizes.
String recIterReverse (String word){
Stack <String> stack = new Stack <String> ();
stack.push(word);
String result = "";
while (!stack.isEmpty()){
String temp = stack.pop();
result = temp.charAt(0) + result;
if (temp.length() > 1){
stack.push(temp.substring(1));
}
}
return result;
}
function call:
//str:string to be reversed,i=0,j=str.length-1
public void reverseString(String str,int i,int j)
{
if(i==j)
{
System.out.println(str);
return;
}
char x=str.charAt(i);
str=str.replace(str.charAt(i),str.charAt(j));
str=str.replace(str.charAt(j),x);
i++;j--;
reverseString(str,i,j);
}
this method works too..
Try the following:
public class reverse2
{
public static void main(String name)
{
String revname=new StringBuffer(name).reverse().toString();
System.out.println("original string " + name + " and the reverse of it is " + revname);
}
}
public static String rev(String name){
if(name.length()>=1){
System.out.print(name.charAt(name.length()-1));
return rev(name.substring(0,name.length()-1));
}
else{
return ""+name.substring(0);
}
}
String rev="";
public String reverseString(String s){
if (s.length()==0) return "";
return rev+s.substring(s.length()-1,s.length())+reverseString(s.substring(0, s.length()-1));
}
public String reverseString (String s) {
if (s != null && s.length () > 0 ) {
rev = rev + s.substring (s.length () - 1);
reverseString (s.substring (0, s.length () - 1));
}
return rev;
}
public class StringUtility {
public static void main(String[] args) {
StringUtility stringUtility = new StringUtility();
String input = "santosh123";
int middle = input.length() / 2;
middle = middle - 1;
System.out.println(stringUtility.stringReverse(input, middle));
}
public String stringReverse(String input, int middle) {
if (middle == -1) {
System.out.println("if");
return input;
} else {
System.out.println("else");
input = swapChar(input, middle);
middle = middle - 1;
return stringReverse(input, middle);
}
}
private String swapChar(String input, int middle) {
StringBuilder str = new StringBuilder(input);
char begin = str.charAt(middle);
int endIndex = input.length() - middle - 1;
char end = str.charAt(endIndex);
str.setCharAt(middle, end);
str.setCharAt(endIndex, begin);
System.out.println(str + " " + middle + " " + endIndex);
return str.toString();
}
}
If you think less code is good then....
static String reverse(String str){
return str.length()>=2 ? str.charAt(str.length()-1) + reverse(str.substring(0,str.length()-1)) : str ;
}
There are about 20 answers already but I'll just throw in my recursive algorithm as well. It may be a little verbose but it is at least readable.
public static String reverseString(String str) {
return reverseString("", str);
}
private static String reverseString(String result, String original) {
if (original.length() == 0) {
return result;
} else {
int length = original.length();
String lastLetter = original.substring(length - 1, length);
original = original.substring(0, length - 1);
return reverseString(result + lastLetter, original);
}
}
The code basically recursively takes the end of the string and moves it in front. For example if the string we want to reverse is "jam," then each time the helper method is called, result and original strings are as follows:
// result: original:
// "" jam
// m ja
// ma j
// maj ""
Reverse String using the recursive method call.
Sample Code
public static String reverseString(String s) {
if (s.length() == 0) {
return s;
}
else {
return s.charAt(s.length() - 1) + reverseString(s.substring(0, s.length() - 1));
}
}
This is my solution,I saw in many solutions above we are getting the string length but ideally we don't need that. The Zen is to use recursion, just chop the first char of string and pass the rest to recursive method. Yay!! we got the solution.
private static void printReverse(String str) {
if (!str.isEmpty()) {
String firstChar = str.substring(0, 1); //Get first char of String
String newstr = str.substring(0, 0) + str.substring(1); // Get remaining string
printReverse(newstr); // Recursion magic
System.out.print(firstChar); //Output
}
}
public static String reverse(String s){
int n = s.length()-1;
if(n >=0)
return s.substring(s.length()-1)+ReverseString(s.substring(0,n--));
else return "";
}