patterncsharpMinor
Reversing each word of a string while keeping the case index
Viewed 0 times
casekeepingthewhileeachwordindexstringreversing
Problem
I was given a simple requirement for reversing a string. The requirement is as follows:
In any programming language, create an input that accepts "My name is Albert McDonald." and outputs the reversed value "Ym eman si Trebla DlAnodcm."
I got it to work like this:
Is there a better way in terms of lines of code and performance-wise?
In any programming language, create an input that accepts "My name is Albert McDonald." and outputs the reversed value "Ym eman si Trebla DlAnodcm."
I got it to work like this:
string expectedInput = "My name is Albert McDonald.";
//Prompt the user to enter "My name is Albert McDonald."
Console.WriteLine("Please enter the sentence \"" + expectedInput + "\"");
Console.WriteLine();
//Wait for the users input.
string inputText = Console.ReadLine();
//Convert the input to a char array.
List characters = inputText.ToList();
//Get the list of uppercase indexes
List upperIndexes = new List();
for (int index = 0; index < characters.Count; index++)
{
if (Char.IsUpper(characters[index]))
upperIndexes.Add(index);
}
//Remove the period at the end
inputText = inputText.Substring(0, inputText.Length - 1);
//Get the reversed array of words.
string[] words = inputText.Split(' ').Reverse().ToArray();
//Join the array back to a string.
string revesedWords = string.Join(" ", words);
//Reverse the entire string and make it all lower case.
string result = new string(revesedWords.Reverse().ToArray()).ToLower();
StringBuilder sb = new StringBuilder(result);
//Change the case of the original index
foreach (int index in upperIndexes)
{
char newCharacter = char.Parse(result.Substring(index, 1).ToUpper());
sb[index] = newCharacter;
}
//Output the resutlt
Console.WriteLine("Your name in reverse by word is: \"" + sb.ToString() + ".\"");
Console.WriteLine();
//Inform the user how to close the screen.
Console.WriteLine("Press any key to close the screen.");
Console.ReadLine();Is there a better way in terms of lines of code and performance-wise?
Solution
If you aim for fewer lines of code, you could of course put everything into a single line, but that would not helpful at all.
However, you could shorten your code a bit by using a simple regular expression and some linq-fu, something like:
I would not care about performance in this case, because it would be pointless.
Also, reversing a string with
However, you could shorten your code a bit by using a simple regular expression and some linq-fu, something like:
var s = yourInputString;
// split string into words
var splitted = Regex.Split(s, @"(\W)").Select(r => r.AsEnumerable()).ToArray();
// reverse each word
var reversed = splitted.Select(sp => sp.Reverse().ToArray());
// adjust case
var zipped = splitted.Zip(reversed, (a, b) => string.Join("", a.Select((c, i) => char.IsUpper(c) ?
char.ToUpper(b[i]) :
char.ToLower(b[i]))));
// join back to string
var result = string.Join("", zipped);I would not care about performance in this case, because it would be pointless.
Also, reversing a string with
Reverse().ToArray() will corrupt your string if it contains surrogate characters, but this is probably out of scope of your task.Code Snippets
var s = yourInputString;
// split string into words
var splitted = Regex.Split(s, @"(\W)").Select(r => r.AsEnumerable()).ToArray();
// reverse each word
var reversed = splitted.Select(sp => sp.Reverse().ToArray());
// adjust case
var zipped = splitted.Zip(reversed, (a, b) => string.Join("", a.Select((c, i) => char.IsUpper(c) ?
char.ToUpper(b[i]) :
char.ToLower(b[i]))));
// join back to string
var result = string.Join("", zipped);Context
StackExchange Code Review Q#25335, answer score: 7
Revisions (0)
No revisions yet.