-5

I'm facing a problem where I have to reverse words in string by 1 recursive Method. I have tries and achieved my result by using Two Method, out them 1 is recursive and other is iterative. But I couldn't find exact solution (i.e. by 1 recursive Method) anywhere. If you have any then please refer. Otherwise its really challenging! I want to reverse "Hello My World" to "olleH yM dlroW"

Note: As its a kind of homework, So I can't use built-in Functions or try other ways. I have to do it as I've described in details.

        static string Rev(string str)
        {
        if (str[0] == str[str.Length - 1])
        {
            return "";
        }
        if (str[0] == ' ')
        {
            return temp;
        }
        return temp += Rev(str.Substring(1)) + str[0];
        }

This above Method only returns the string in reverse which is before space, then it terminates. I've also tried that Method which reverse the whole string like "Hello World" to "dlroW olleH"

Mursalin Malik
  • 57
  • 1
  • 12
  • Your desired result has nothing to do with positions. You're trying to reverse *individual words* in a string. – Panagiotis Kanavos Sep 05 '19 at 08:01
  • Can you elaborate on why "method should be recursive"? Seems like an artificial requirement - is this homework? Did you get any guidance on how/why it should recurse? – Jamiec Sep 05 '19 at 08:14
  • @Jamiec my requirement is recursion, so if you can answer, you are welcome! – Mursalin Malik Sep 05 '19 at 08:57
  • @PanagiotisKanavos position means that every word should remain at its own position, even after reversing .. so if you are taking in any other perception than you might be right at that – Mursalin Malik Sep 05 '19 at 09:04
  • @MursalinMalik you didn't even mention words in the title or question. Position in a string or any array means something very specific that has nothing to do with words. Notice how Jamiec's answer explains the problem *and* solves it in a single line. Once you rephrase your question you'll realize that you need to identify word boundaries first, reverse second. Doing so using recursion isn't a great idea. Is this schoolwork? – Panagiotis Kanavos Sep 05 '19 at 09:13
  • I ask "Why recursion" you answer "Because I need recursion". There's a joke there somewhere. – Jamiec Sep 05 '19 at 09:40
  • @Jamiec it isn't any kind of joke , my answer says that My requirement is recursion, so I can't change my requirement because you have not solution for that or you suggest me any alternative, requirement is requirement buddy, we can't change it – Mursalin Malik Sep 05 '19 at 09:50
  • @PanagiotisKanavos my Title was well elaborated in explanation, so there was not ambiguity in Question. and yes first we have to identify the boundaries, then we may proceed. and yeah I have to do it with requirement, its assigned to me as it is. – Mursalin Malik Sep 05 '19 at 09:53
  • Thanks @Jamiec , but its obvious from problem that its a very minor problem, so it must be a practice problem, nothing more than that. – Mursalin Malik Sep 05 '19 at 10:02
  • 1
    It's a *really bad* practice problem for recursion. It makes almost zero sense. Even something like Fibonacci using recursion is nuts as its so inefficient, but at least it demonstrates the point of recursion. – Jamiec Sep 05 '19 at 10:04
  • Yes obviously its a bad practice , that's why I've spent/wasted more that 30 hours on it. – Mursalin Malik Sep 05 '19 at 10:07
  • @MursalinMalik you wouldn't have to ask if it was minor. If you google for the *correct* question `reverse words using recursion` you'll find many examples, [like this one](https://stackoverflow.com/questions/24092355/recursively-reversing-words-in-a-string). As the solution says "it's not as easy as you thing". The trap is that you need to do *two* things - detect the boundary going forward and then reverse – Panagiotis Kanavos Sep 05 '19 at 10:08
  • @MursalinMalik btw a *very* important part of assignments is to make people understand how to ask questions and search for the answers. The search for `reverse words` can lead to `post order traversal` and that can lead you to implementations like [this one](http://csharpexamples.com/tag/postorder-traversal/). What if you used *two* recursive methods, one to find the words and one to reverse them? – Panagiotis Kanavos Sep 05 '19 at 10:17
  • @PanagiotisKanavos probably you didn't looked into answer/description, _as you are Title guy_.. :p That method just reverse **"Hello World"** to **"World Hello"** – Mursalin Malik Sep 05 '19 at 11:46
  • Yes, I've already done it with two Methods, and output was accurate. but I've to right an algo in a single Method – Mursalin Malik Sep 05 '19 at 11:48
  • @MursalinMalik on the contrary, I read both links, both codes, because you have to *find* the words and then *reverse* them. That's how I created a solution that doesn't use global state and still produces the desired result. I'll repeat it, the *most* important part of an assignment is to get you to ask the correct questions, think, search and try. If you hit a dead end perhaps you're asking for the wrong thing – Panagiotis Kanavos Sep 05 '19 at 12:00
  • @MursalinMalik you aren't supposed to just copy a solution. Instructors can google too and can easily find where your code came from. You have to break the problem into parts, solve each one then combine them – Panagiotis Kanavos Sep 05 '19 at 12:02
  • Absolutely there are two parts, and I've done it by splitting in two separate Methods, but problem arises when I want to get the whole result as desired in just one recursive method! – Mursalin Malik Sep 05 '19 at 12:26

4 Answers4

4

I want to reverse "Hello World" to "olleH dlroW"

Split the string on a space, and reverse each word. Then put the string back together with a space between each:

var input = "Hello world";
var result = String.Join(" ", 
                  input.Split(' ')
                       .Select(word => new string(word.Reverse().ToArray())));

Live example: https://rextester.com/CJF79825

Note that there are better and/or more efficient ways to reverse a string

Jamiec
  • 133,658
  • 13
  • 134
  • 193
1

There are probably many ways to do this; here's one example:

using System;
using System.Linq;

namespace Demo
{
    class Program
    {
        public static void Main(string[] args)
        {
            string text = "Hello World";
            Console.WriteLine(Reverse(text));  // Prints "olleH dlroW"
        }

        public static string Reverse(string text)
        {
            var words = text.Split(' ');

            return words.Length == 1 
                ? new string(words[0].Reverse().ToArray()) // Not recursive; using Enumerable.Reverse()
                : string.Join(" ", words.Select(Reverse)); // <- Here's the recursive call.
        }
    }
}

I have to say, though: This isn't the best question to illustrate recursion. I'd have gone for something more obvious such as calculating a factorial, or the Fibonacci sequence...

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
1

Looks like the actual question is how to reverse words in a string using recursion. Phrasing the question correctly is often 50% of actually solving it. Googling for reverse words with recursion returns several answers that show this is not an easy thing to do.

It requires two steps - one going forward to find the word boundaries and then one that backtracks to reverse the already identified word. I assume the point is to avoid loops entirely, so trying to find spaces using IndexOf is out of scope.

Reversing is easy - in fact the original code can be simplified a lot:

string Rev(string input)
{
    if (input.Length==0)
    {
        return input;
    }

    return Rev(input.Substring(1)) + input[0];
}

The problem with this function is that strings are immutable and every string operation allocates a new string that needs to be garbage-collected. It would be better to use Array.Reverse on the character array for this.

The second step is to find the words and transfer them from one call to the next. This similar question uses a stack to transfer the words, while this question splits a string into a head/tail when a space is discovered. The techniques can be combined, but instead of a stack we can use a string. Again, this wastes memory because it creates temporary strings.

string Rev(string input)
{
    if (input.Length==0)
    {
        return input;
    }

    return Rev(input.Substring(1)) + input[0];
}



string Word(string words,string head,string tail)
{   
    //Finished, return the final string.
    if(tail.Length==0)
    {
        return (words.Length==0)? Rev(head): words + " " + Rev(head);                
    }
    //Word boundary found
    if (tail[0]==' ')
    {
        //Add the revesed word to the words
        words=(words.Length==0)? Rev(head): words + " " + Rev(head);                
        head="";
        tail=tail.Substring(1);        
    }
    //No boundary, just copy one character from the tail to the head
    else
    {
        head=head + tail[0];
        tail=tail.Substring(1);       
    }

    return Word(words,head,tail);
}

Calling Word("","","Hello World Boo Soo") will return olleH dlroW ooB ooS.

Again, this is very wasteful.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
  • I appreciate your effort, and the way you delivered, but I have _already solved_ this with two Methods(Our procedure is different), this time I was looking for a recursive Method which covers everything in one Method. – Mursalin Malik Sep 05 '19 at 15:03
  • @MursalinMalik that's not what you asked though. – Panagiotis Kanavos Sep 05 '19 at 15:05
  • _Yes, I've already done it with two Methods, and output was accurate. but I've to right an algo in a single Method_ _Absolutely there are two parts, and I've done it by splitting in two separate Methods, but problem arises when I want to get the whole result as desired in just one recursive method!_ **You have read out these comments and even you have replied me, and yet you say I didn't asked this?** – Mursalin Malik Sep 06 '19 at 06:27
0

You need to split the string into individual words, before you can reverse them, rather than treating it as a whole string.

The below example should achieve what you are looking for

class Program
{
    static string temp = string.Empty;

    static void Main(string[] args)
    {
        string word = "Hello World";
        var words = word.Split(' ');
        var result = ReverseWords(words);
        Console.Write(result);
        Console.ReadKey();
    }

    static string ReverseWords(string[] words)
    {
        var reversedList = new List<string>();
        foreach (var word in words)
        {
            temp = string.Empty;
            reversedList.Add(Rev(word, 1));
            reversedList.Add(" ");
        }
        return string.Join("", reversedList);
    }

    static string Rev(string str, int count)
    {
        if (str[0] == str[str.Length - count])
        {
            return temp += str[0];
        }
        return temp += Rev(str.Substring(count), count++) + str[0];
    }
}
level_zebra
  • 1,503
  • 6
  • 25
  • 44