C# - 如何通过忽略末尾的特殊字符来使用最后一个字符对字符串列表进行排序
C# - How to sort a list of strings using last character by ignoring special character if any at the end
以下是我尝试实现并能够对其进行排序但需要找出忽略其中特殊字符的逻辑
我的逻辑:
- 列表中的反转字符串
- 升序排列
- 再次反向排序字符串 &
最终通过加入 ~ 分隔符作为字符串返回。
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2",
"Mango","Apples", "Grape$", "Guava" };
List<String> sortList = new List<String>();
List<String> outputList = new List<String>();
foreach (String str in inputLst)
{
sortList.Add(new String(str.ToCharArray().Reverse().ToArray()));
}
sortList.Sort();
foreach (String str in sortList)
{
outputList.Add(new String(str.ToCharArray().Reverse().ToArray()));
}
Return String.Join("~", outputList);
我得到的输出是Bananas!~Grape$~Cherry2~Guava~Mango~Apples
预期输出应为 Guava~Grape$~Mango~Bananas!~Apples~Cherry2
谁能建议我通过忽略特殊字符按最后一个字符对列表进行排序的优化解决方案?在这里,我使用了 2 个列表来进行字符串反转,可以用更有效的方式完成吗?
注意:不使用 LINQ pls.
使用一点 LINQ 和 Regex,这可以相对简单地实现:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => new string(Regex.Replace(s, "[^a-zA-Z]", "")
.Reverse()
.ToArray()))
.ToList();
var output = String.Join("~", outputList);
编辑: 非 LINQ 方法:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango", "Apples", "Grape$", "Guava" };
inputList.Sort(new ReverseStringComparer());
var output = String.Join("~", inputList);
反向字符串比较器:
class ReverseStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
string a = new string(Regex.Replace(x, "[^a-zA-Z]", "").Reverse().ToArray());
string b = new string(Regex.Replace(y, "[^a-zA-Z]", "").Reverse().ToArray());
return a.CompareTo(b);
}
}
没有正则表达式的解决方案:
string foo()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().SkipWhile( x => !char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().SkipWhile(x => !char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
要按照评论中的建议跳过所有非字母字符(不仅是在字符串的开头),只需使用 Where
而不是 SkipWhile
,如下所示:
string bar()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().Where( x => char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().Where(x => char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
注意 Where
与 SkipWhile
(!char.IsLetter(x)
) 相比具有相反的逻辑 (char.IsLetter(x)
)。
找到最后一个符号是字母并按它排序。
var inputList = new List<string>() {
"Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => s.Last(c => char.IsLetter(c)));
Console.WriteLine(string.Join("~", outputList));
不需要反转。
以下是我尝试实现并能够对其进行排序但需要找出忽略其中特殊字符的逻辑
我的逻辑:
- 列表中的反转字符串
- 升序排列
- 再次反向排序字符串 &
最终通过加入 ~ 分隔符作为字符串返回。
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" }; List<String> sortList = new List<String>(); List<String> outputList = new List<String>(); foreach (String str in inputLst) { sortList.Add(new String(str.ToCharArray().Reverse().ToArray())); } sortList.Sort(); foreach (String str in sortList) { outputList.Add(new String(str.ToCharArray().Reverse().ToArray())); } Return String.Join("~", outputList);
我得到的输出是Bananas!~Grape$~Cherry2~Guava~Mango~Apples
预期输出应为 Guava~Grape$~Mango~Bananas!~Apples~Cherry2
谁能建议我通过忽略特殊字符按最后一个字符对列表进行排序的优化解决方案?在这里,我使用了 2 个列表来进行字符串反转,可以用更有效的方式完成吗? 注意:不使用 LINQ pls.
使用一点 LINQ 和 Regex,这可以相对简单地实现:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => new string(Regex.Replace(s, "[^a-zA-Z]", "")
.Reverse()
.ToArray()))
.ToList();
var output = String.Join("~", outputList);
编辑: 非 LINQ 方法:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango", "Apples", "Grape$", "Guava" };
inputList.Sort(new ReverseStringComparer());
var output = String.Join("~", inputList);
反向字符串比较器:
class ReverseStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
string a = new string(Regex.Replace(x, "[^a-zA-Z]", "").Reverse().ToArray());
string b = new string(Regex.Replace(y, "[^a-zA-Z]", "").Reverse().ToArray());
return a.CompareTo(b);
}
}
没有正则表达式的解决方案:
string foo()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().SkipWhile( x => !char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().SkipWhile(x => !char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
要按照评论中的建议跳过所有非字母字符(不仅是在字符串的开头),只需使用 Where
而不是 SkipWhile
,如下所示:
string bar()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().Where( x => char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().Where(x => char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
注意 Where
与 SkipWhile
(!char.IsLetter(x)
) 相比具有相反的逻辑 (char.IsLetter(x)
)。
找到最后一个符号是字母并按它排序。
var inputList = new List<string>() {
"Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => s.Last(c => char.IsLetter(c)));
Console.WriteLine(string.Join("~", outputList));
不需要反转。