Reputation: 441
Recently I have been asked in a discussion to write an algorithm to implement reverse of words of a sentence (Not reverse of whole sentence) without using string operations such as Split/Replace/Reverse/Join except ToCharArray and Length. The below is what I could devise in 5min of time. Though the algorithm is working fine, it seems bit ugly style of implementation. Can some body help me by polishing the code.
string ReverseWords(string s)
{
string reverseString = string.Empty;
string word = string.Empty;
var chars = s.ToCharArray();
List<ArrayList> words = new List<ArrayList>();
ArrayList addedChars = new ArrayList();
Char[] reversedChars = new Char[chars.Length];
int i = 1;
foreach (char c in chars)
{
if (c != ' ')
{
addedChars.Add(c);
}
else
{
words.Add(new ArrayList(addedChars));
addedChars.Clear();
}
if (i == s.Length)
{
words.Add(new ArrayList(addedChars));
addedChars.Clear();
}
i++;
}
foreach (ArrayList a in words)
{
for (int counter = a.Count - 1; counter >= 0; counter--)
{
reverseString += a[counter];
}
if(reverseString.Length < s.Length)
reverseString += " ";
}
return reverseString;
}
Upvotes: 1
Views: 19818
Reputation: 4066
use stack in C#
string str = "ABCDEFG";
Stack<char> stack=new Stack<char>();
foreach (var c in str)
{
stack.Push(c);
}
char[] chars=new char[stack.Count];
for (int i = 0; i < chars.Length; i++)
{
chars[i]=stack.Pop();
}
var result=new string(chars); //GFEDCBA
Upvotes: 0
Reputation: 180
One of the Easiest Answer is as given Below please go through it,
public static string ReversewordString(string Name)
{
string output="";
char[] str = Name.ToCharArray();
for (int i = str.Length - 1; i >= 0; i--)
{
if (str[i] == ' ')
{
output = output + " ";
for (int j = i + 1; j < str.Length; j++)
{
if (str[j] == ' ')
{
break;
}
output=output+ str[j];
}
}
if (i == 0)
{
output = output +" ";
int k = 0;
do
{
output = output + str[k];
k++;
} while (str[k] != ' ');
}
}
return output;
}
Upvotes: 1
Reputation: 1
How about a simple recursive function that checks for a " " and then substring accordingly?
private static string rev(string inSent) {
if(inSent.IndexOf(" ") != -1)
{
int space = inSent.IndexOf(" ");
System.Text.StringBuilder st = new System.Text.StringBuilder(inSent.Substring(space+1));
return rev(st.ToString()) + " " + inSent.Substring(0, space);
}
else
{
return inSent;
}
}
Upvotes: 0
Reputation:
Well, you didn't say anything about the other LINQ extension methods :)
static string ReverseWordsWithoutSplit(string input)
{
var n = 0;
var words = input.GroupBy(curr => curr == ' ' ? n++ : n);
return words.Reverse().Aggregate("", (total, curr) => total + string.Concat(curr.TakeWhile(c => c != ' ')) + ' ');
}
Upvotes: 1
Reputation: 1
This version works in-place, without any intermediate data structures. First, it reverses the characters in each word. "me too" => "em oot". Then it reverses the whole string: "em oot" => "too me".
public static string ReverseWords(string s)
{
if (string.IsNullOrEmpty(s))
return s;
char[] chars = s.ToCharArray();
int wordStartIndex = -1;
for (int i = 0; i < chars.Length; i++)
{
if (!Char.IsWhiteSpace(chars[i]) && wordStartIndex < 0)
{
// Remember word start index
wordStartIndex = i;
}
else
if (wordStartIndex >= 0 && (i == chars.Length-1 || Char.IsWhiteSpace(chars[i + 1]))) {
// End of word detected, reverse the chacacters in the word range
ReverseRange(chars, wordStartIndex, i);
// The current word is complete, reset the start index
wordStartIndex = -1;
}
}
// Reverse all chars in the string
ReverseRange(chars, 0, chars.Length - 1);
return new string(chars);
}
// Helper
private static void ReverseRange(char[] chars, int startIndex, int endIndex)
{
for(int i = 0; i <= (endIndex - startIndex) / 2; i++)
{
char tmp = chars[startIndex + i];
chars[startIndex + i] = chars[endIndex - i];
chars[endIndex - i] = tmp;
}
}
Upvotes: 0
Reputation: 493
string temp = string.Empty;
string reversedString = string.Empty;
foreach (var currentCharacter in testSentence)
{
if (currentCharacter != ' ')
{
temp = temp + currentCharacter;
}
else
{
reversedString = temp + " " + reversedString;
temp = string.Empty;
}
}
reversedString = temp + " " + reversedString;
Upvotes: 0
Reputation: 11
There is a small bug in your code. Due to this, the output string would be displayed as yo are how hi!
, given the input string hi! how are you
. It's truncating the last char of the last word.
Change this:
spaceEncounter.Add(words.Length - 1);
To:
spaceEncounter.Add(words.Length);
Upvotes: 1
Reputation: 81
Kind of a polished version:-
string words = "hi! how are you!";
string reversedWords = "";
List<int> spaceEncounter = new List<int>();
spaceEncounter.Add(words.Length - 1);
for (int i = words.Length - 1; i > 0; i--)
{
if(words[i].Equals(' '))
{
spaceEncounter.Add(i);
for (int j = i+1; j < spaceEncounter[spaceEncounter.Count - 2]; j++)
reversedWords += words[j];
reversedWords += " ";
}
}
for (int i = 0; i < spaceEncounter[spaceEncounter.Count - 1]; i++)
reversedWords += words[i];
Upvotes: 2
Reputation: 1371
This is somewhat simpler:
string inp = "hai how are you?";
StringBuilder strb = new StringBuilder();
List<char> charlist = new List<char>();
for (int c = 0; c < inp.Length; c++ )
{
if (inp[c] == ' ' || c == inp.Length - 1)
{
if (c == inp.Length - 1)
charlist.Add(inp[c]);
for (int i = charlist.Count - 1; i >= 0; i--)
strb.Append(charlist[i]);
strb.Append(' ');
charlist = new List<char>();
}
else
charlist.Add(inp[c]);
}
string output = strb.ToString();
Upvotes: 6
Reputation: 75155
There is a relatively elegant solution which uses a LIFO stack.
Question however sounds like homework, so I'll only provide the pseudo code.
currWord = new LIFO stack of characters
while (! end of string/array)
{
c = next character in string/array
if (c == some_white_space_character) {
while (currWord not empty) {
c2 = currWord.pop()
print(c2)
}
print(c)
}
else
currWord.push(c)
}
Upvotes: 8