I'm trying to reverse a sentence like the following: The input:
my name is john. i am 23 years old.
The output:
.old years 23 am i .john is name my
I can't figure it out how to switch the dot at the end.
I tried using Split but it always return the dot at the end of the word.
string[] words = sentence.Split(' ');
Array.Reverse(words);
return string.Join(" ", words);
CodePudding user response:
Add extra logic to move period ('.') before the word starts, like
var sentence ="my name is john. i am 23 years old."; //Input string
string[] words = sentence.Split(' '); //Split sentence into words
Array.Reverse(words); //Revere the array of words
//If word starts with . then start your word with period and trim end.
var result = words.Select(x => x.EndsWith('.') ? $".{x.Trim('.')}" : x);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^This was missing
Console.WriteLine(string.Join(" ", result));
CodePudding user response:
You are reversing words separated by space (in old. the point is part of the word). If you want to reverse the points too you want to consider them as words (sperated by space):
public static class TextExtensions
{
public static string PointTrick(this string str) => str.Replace(".", " .");
public static string PointUntrick(this string str) => str.Replace(". ", ".");
public static string ReverseWords(this string str) => string.Join(" ", str.Split(" ").Reverse());
}
Those tests pass.
[TestClass]
public class SOTests
{
private string GetReversedWithPointTrick(string input) => input.PointTrick().ReverseWords().PointUntrick();
[TestMethod]
public void ReverseWordsTest()
{
var sut = "three two. one";
var expected = "one two. three";
var result = sut.ReverseWords();
Assert.AreEqual(expected, result);
}
[TestMethod]
public void ReverseWords_PointTrick_Test()
{
var sut = "my name is john. i am 23 years old.";
var expected = ".old years 23 am i .john is name my";
var result = GetReversedWithPointTrick(sut);
Assert.AreEqual(expected, result);
}
}
CodePudding user response:
You can try combination of Linq and Regular Expressions:
using System.Linq;
using System.Text.RegularExpressions;
...
string source = "my name is john. i am 23 years old.";
// .old years 23 am i .john is name my
string result = string.Join(" ", Regex
.Matches(source, @"\S ")
.Cast<Match>()
.Select(m => Regex.Replace(m.Value, @"^(.*?)(\p{P} )$", "$2$1"))
.Reverse());
Here we use two patterns: a simple one "\S " which matches any characters which are not whitespaces. The next pattern ^(.*?)(\p{P} )$ worth explaining:
^(.*?)(\p{P} )$
here
^ - anchor, start of the string
(.*?) - group #1: any symbols, but as few as possible
(\p{P} ) - group #2: one or more punctuation symbols
$ - anchor, end of the string
and when matched we swap these groups: "&2&1"
Demo:
private static string Solve(string source) => string.Join(" ", Regex
.Matches(source, @"\S ")
.Cast<Match>()
.Select(m => Regex.Replace(m.Value, @"^(.*?)(\p{P} )$", "$2$1"))
.Reverse());
...
string[] tests = new string[] {
"my name is john. i am 23 years old.",
"It's me, here am I!",
"Test...",
};
string report = string.Join(Environment.NewLine, tests
.Select(test => $"{test,-35} => {Solve(test)}"));
Console.Write(report);
Outcome:
my name is john. i am 23 years old. => .old years 23 am i .john is name my
It's me, here am I! => !I am here ,me It's
Test... => ...Test
CodePudding user response:
Because someone always has to post a LINQ version of these things
