HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Reverse a sentence quickly without pointers

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
quicklywithoutreversesentencepointers

Problem

I am trying to reverse a sentence contained in a string and return a string in the quickest way possible using the least amount of memory. Also I don't want to use any unsafe code, so no pointers are allowed. Please let me know if anything can be improved.

My input example is

string mystring = "Hello! my name is";


My result is


"is name my Hello!"

My results on i7 4770S for 1000000 iterations is on average around 650ms.

public static string ReverseTheString(string MyString)
{

    int Length = MyString.Length;
    Char[] NormalArray = new char[Length];
    Char[] FinalArray = new char[Length];

    for (int i = 0; i  ReversedArray = new Stack();

    for (int i = 0; i  0)
                {
                    char[] temparray = new char[AlphaCount];
                    int tempindex = i - AlphaCount;
                    for (int j = tempindex, k = 0; k  0)
                {
                    char[] temparray = new char[SpacesCount];
                    int tempindex = i + 1 - SpacesCount;
                    for (int j = tempindex, k = 0; k  0)
                {
                    char[] temparray = new char[SpacesCount];
                    int tempindex = i - SpacesCount;
                    for (int j = tempindex, k = 0; k  0)
                {
                    char[] temparray = new char[AlphaCount];
                    int tempindex = i + 1 - AlphaCount;
                    for (int j = tempindex, k = 0; k  0)
    {
        char[] temparray = ReversedArray.Pop();

        for (int j = 0; j < temparray.Length; j++)
        {
            FinalArray[Pos] = temparray[j];
            Pos++;
        }
    }

    return new string(FinalArray);
}

Solution

The shortest code I can produce is:

private static string Reverse(string input)
{
    return String.Join(" ", input.Split(' ').Reverse());
}


But the following alternative should be much faster:

private static string Reverse(string input)
{
    // Create a new StringBuilder and allocate the same space as in the input string:
    StringBuilder builder = new StringBuilder(input.Length);

    // Declare 2 index variables:
    int index;
    int lastIndex = input.Length;

    // Iterate from the end to the start of the string
    // while the ' ' char is found:
    while ((index = input.LastIndexOf(' ', lastIndex - 1)) != -1)
    {
        builder.Append(input, index + 1, lastIndex - index - 1).Append(' ');
        lastIndex = index;
    }
    // Last iteration (for the first token in the input string):
    if (lastIndex != index)
    {
        builder.Append(input, 0, lastIndex);
    }
    return builder.ToString();
}


The main idea is to iterate from the end of the input string to the beginning, looking for the space char.

Also it makes sense to rely on the .NET built-in methods as much as possible.

Therefore I used:

  • The StringBuilder class for accumulation of a result.



  • The String.LastIndexOf method for searching for the space char.



The reasons to use the StringBuilder:

  • It is very effecient.



  • It contains the Append(string value, int startIndex, int count) method which copies specified substring to the inner buffer directly (without creating an intermediate substring from the input string).



EDIT.

A new approach not using the StringBuilder class and with the same main idea:

private static string Reverse(string inputString)
{
    // Get array of chars from the inputString,
    // and allocate the same space in the output array:
    char[] input = inputString.ToCharArray();
    char[] output = new char[input.Length];

    // Declare 3 index variables:
    int index;
    int lastIndex = input.Length;
    int outputIndex = 0;

    // Iterate from the end to the start of the string
    // while the ' ' char is found:
    while ((index = inputString.LastIndexOf(' ', lastIndex - 1)) != -1)
    {
        Array.Copy(input, index + 1, output, outputIndex, lastIndex - index - 1);
        outputIndex += lastIndex - index;
        output[outputIndex - 1] = ' ';
        lastIndex = index;
    }
    // Last iteration (for the first token in the input string):
    if (lastIndex != index)
    {
        Array.Copy(input, 0, output, outputIndex, lastIndex);
    }
    return new string(output);
}


It is slightly less efficient than previous approach, but it is still very fast.

Code Snippets

private static string Reverse(string input)
{
    return String.Join(" ", input.Split(' ').Reverse());
}
private static string Reverse(string input)
{
    // Create a new StringBuilder and allocate the same space as in the input string:
    StringBuilder builder = new StringBuilder(input.Length);

    // Declare 2 index variables:
    int index;
    int lastIndex = input.Length;

    // Iterate from the end to the start of the string
    // while the ' ' char is found:
    while ((index = input.LastIndexOf(' ', lastIndex - 1)) != -1)
    {
        builder.Append(input, index + 1, lastIndex - index - 1).Append(' ');
        lastIndex = index;
    }
    // Last iteration (for the first token in the input string):
    if (lastIndex != index)
    {
        builder.Append(input, 0, lastIndex);
    }
    return builder.ToString();
}
private static string Reverse(string inputString)
{
    // Get array of chars from the inputString,
    // and allocate the same space in the output array:
    char[] input = inputString.ToCharArray();
    char[] output = new char[input.Length];

    // Declare 3 index variables:
    int index;
    int lastIndex = input.Length;
    int outputIndex = 0;

    // Iterate from the end to the start of the string
    // while the ' ' char is found:
    while ((index = inputString.LastIndexOf(' ', lastIndex - 1)) != -1)
    {
        Array.Copy(input, index + 1, output, outputIndex, lastIndex - index - 1);
        outputIndex += lastIndex - index;
        output[outputIndex - 1] = ' ';
        lastIndex = index;
    }
    // Last iteration (for the first token in the input string):
    if (lastIndex != index)
    {
        Array.Copy(input, 0, output, outputIndex, lastIndex);
    }
    return new string(output);
}

Context

StackExchange Code Review Q#78065, answer score: 7

Revisions (0)

No revisions yet.