views:

203

answers:

5

writing a recursive string reverse function out of curiosity, but having a bit of problem with XOR there. The whole point of this function, is to not use iterator, which is why it is a recursive function. this is not homework, just curiosity.

    private static char[] ReverseNL(char[] arr, int index)
    {
        var len = arr.Length;
        if (index > 0)
            arr[len - index] ^= arr[index - 1];
        return index-- < 1 ? arr : ReverseNL(arr, index);
    }

it seems to jamble the first part of my string

"hey there stack!" becomes "I♫→A ←E↨reht yeh"

it is always the first half of the phrase that gets jumbled...

UPDATE..

i suppose XOR wasn't really needed here.. so used basic assignment, also got rid of return.

    private static void ReverseNL(char[] arr, int index) {
        var len = arr.Length;
        if (index > 0 && index > len / 2) {
            var c = arr[len - index];
            arr[len - index] = arr[index - 1];
            arr[index - 1] = c;
            index--;
            ReverseNL(arr, index);
        }
    }
A: 

In this particular example, I'd rather do this:

return arr.Reverse();
Matthew Abbott
thanks, but i did not ask for the best way to reverse a string.. this is just a curiosity exercise
Sonic Soul
You really missed the homework tag
Henk Holterman
Surely a homework result should be asking for the most concise answer possible...
Matthew Abbott
@Matthew: No, homework is about doing something yourself.
Henk Holterman
this is not homework. i was once asked this at a interview but was not required to write the code.. so writing it out of curiosity now.
Sonic Soul
@Sonic Soul, In my mind, that still falls under the realm of 'homework'. You need a slight nudge in the right direction to get you back on track, not a full answer to the problem.
strager
+5  A: 

Recursion is almost always used to make problems simpler. Recursive algorithms are typically functional in nature as well (though they don't have to be).

In the case of reversing a string (or a char[]), "simpler" means "operating on a smaller array".

For example, you can reduce as follows:

"test"
"est"   't'
"st"    'e'
"t"     's'
""      't'

(On the left is the data reduced; on the right is the cut data).

In pseudocode, you can perform the reduction as follows:

char[] reverse(char[] data) {
    if (data.Count() == 0) {
        return new char[] { };
    }

    char cut = data.First();
    char[] rest = data.Skip(1);

    char [] restReversed = reverse(rest);

    // ???
}

I'll leave it up to you to figure out what needs to be done next with the data you have.

strager
A: 

The XOR has to be called twice to swap a pair of elements. It is only getting called once on the first half of the array. (In edit: strictly speaking, it's only getting called once for each assignment, so net effect is like doing a two-XOR swap on half the array.)

TechNeilogy
Oh that's creative, I wouldn't have come up with doing it that way..
Jimmy Hoffa
+3  A: 

If you want a solution which uses XOR and recursion, try this:

private static void ReverseNL(char[] arr, int index)
{
    if (index <arr.Length/2)
    {
        arr[index] ^= arr[arr.Length - index-1];
        arr[arr.Length - index-1] ^= arr[index ];
        arr[index] ^= arr[arr.Length - index-1];
        ReverseNL(arr,++index);
    }
}

You don't need to return anything, since everything is done in the array. Of course you could just remove the XOR-part and just swap the elements, but this is much cooler. ;)

(edit: index should start at 0)

Marcus Johansson
Of course this fails to reverse the string "abba" properly.
strager
I guess you commented that before i made the edit?
Marcus Johansson
+2  A: 

Likely not to be the most efficient, but this should give you some ideas on how to get the recursion working ...

    static string ReverseNL (string s)
    {
        if ((s == null) || (s.Length <= 1))
        {
            return s;
        }
        return ReverseNL(s.Substring(1)) + s[0];
    }

    static void Main(string[] args)
    {
        string src = "The quick brown fox";
        Console.WriteLine(src);
        src = ReverseNL(src);
        Console.WriteLine(src);
    }
Edward Leno
that works too, very nice, thanks
Sonic Soul
actually i think this is my favorite solution, as it is only 3 lines. simple and elegant.
Sonic Soul