patterncsharpMinor
Reverse a sentence quickly without pointers
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
My result is
"is name my Hello!"
My results on i7 4770S for 1000000 iterations is on average around 650ms.
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:
But the following alternative should be much faster:
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 reasons to use the
EDIT.
A new approach not using the
It is slightly less efficient than previous approach, but it is still very fast.
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
StringBuilderclass for accumulation of a result.
- The
String.LastIndexOfmethod 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.