C# - 如何使用最后一个字符对字符串列表进行排序,忽略特殊字符(如果有的话)

时间:2017-05-13 08:48:54

标签: c# string sorting generic-list

下面是我试图实现并能够对其进行排序但需要弄清楚忽略其中的特殊字符的逻辑

我的逻辑:

  • 列表中的反转字符串
  • 按升序排序
  • 再次撤回已排序的字符串&
  • 最后通过加入〜分隔符作为字符串返回。

        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请。

3 个答案:

答案 0 :(得分:2)

有了一点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);

ReverseStringComparer:

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);
    }
}

答案 1 :(得分:1)

没有正则表达式的解决方案:

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的反转逻辑(char.IsLetter(x))与SkipWhile!char.IsLetter(x))进行比较。

答案 2 :(得分:-1)

找到最后一个符号作为字母并按其排序。

public async Task ChangeProgressBarAsync(ProgressBar pb)
{
    MessageBox.Show(Thread.CurrentThread.ManagedThreadId + "    task");
    int count = 100;
    while (count-- > 0)
    {
        pb.Value++;
        await Task.Delay(10);
    }
}

不需要反向。