zoukankan      html  css  js  c++  java
  • c#实现自然排序效果,按1,2,11而不是1,11,12,区分字母文字和数字

    排序有时候要考虑后缀。这样看起来比较自然。

    参考了codeproject上一篇文章:http://www.codeproject.com/Articles/22978/Implementing-the-NET-IComparer-interface-to-get-a

    然后自己写了个简单的,考虑到主要思想是上面那个文章上的,所以不做太多解释。代码如下:

      1 using System;
      2 using System.Collections;
      3 using System.Collections.Generic;
      4 using System.Linq;
      5 using System.Text;
      6 using System.Text.RegularExpressions;
      7 
      8 namespace StringOrder
      9 {
     10     class Program
     11     {
     12         static void Main(string[] args)
     13         {
     14             string[] array = new string[] {  "2.1", "2.001" };
     15 
     16             string[] array2 = array.OrderBy(a => a, new StringCompare1()).ToArray();
     17             Console.Read();
     18 
     19            
     20         }
     21     }
     22     public class StringCompare1 : IComparer<string>
     23     {
     24         public int Compare(string x, string y)
     25         {
     26 
     27             StringParser sx = new StringParser(x);
     28             StringParser sy = new StringParser(y);
     29             while (sx.TokenType != StringParser.ETokenType.Nothing || sy.TokenType != StringParser.ETokenType.Nothing)
     30             {
     31                 if (sx.TokenType == StringParser.ETokenType.Numberic && sy.TokenType == StringParser.ETokenType.Numberic)
     32                 {
     33                     return decimal.Compare(sx.DoubleValue,sy.DoubleValue);
     34                 } 
     35                 if (string.Compare(sx.StringValue, sy.StringValue) != 0)
     36                 {
     37                     return string.Compare(sx.StringValue, sy.StringValue);
     38                 }
     39                 else
     40                 {
     41                     sx.NextToken();
     42                     sy.NextToken();
     43                 }
     44             }
     45             return 0;
     46         }
     47     }
     48 
     49     public class StringParser
     50     {
     51         private string _value;
     52         private char _curChar;
     53         private int _curIndex = 0;
     54         private int _length;
     55         private ETokenType _tokenType = ETokenType.Character;
     56         public ETokenType TokenType { get { return _tokenType; } }
     57 
     58         private string _stringValue;
     59         public string StringValue { get { return _stringValue; } }
     60 
     61         private decimal _doubleValue;
     62         public decimal DoubleValue { get { return _doubleValue; } }
     63 
     64 
     65         public StringParser(string val)
     66         {
     67             _value = val;
     68             _length = val.Length;
     69             NextChar();
     70             NextToken();
     71         }
     72 
     73         public void NextToken()
     74         {
     75             if (_curChar == '')
     76             {
     77                 _tokenType = ETokenType.Nothing;
     78                 _stringValue = null;
     79             }
     80             else if (char.IsDigit(_curChar))
     81             {
     82                 int startIndex = _curIndex;
     83                 while (char.IsDigit(_curChar) || _curChar == '.')
     84                 {
     85                     NextChar();
     86                 }
     87                 string temp = _value.Substring(startIndex-1, _length - startIndex+1);
     88                 if (decimal.TryParse(temp, out _doubleValue))
     89                 {
     90                     _tokenType = ETokenType.Numberic;
     91                 }
     92                 else
     93                 {
     94                     _tokenType = ETokenType.Character; 
     95                 } 
     96                 _stringValue = temp;
     97             }
     98             else if (char.IsLetter(_curChar))
     99             {
    100                 _tokenType = ETokenType.Character;
    101                 int startIndex = _curIndex;
    102                 while (char.IsLetter(_curChar))
    103                 {
    104                     NextChar();
    105                 }
    106                 _stringValue = _value.Substring(startIndex-1,_curIndex-startIndex);
    107             }
    108             else
    109             {
    110                 NextChar();
    111             }
    112         }
    113 
    114         private void NextChar()
    115         {
    116             if (_curIndex >= _length)
    117             {
    118                 _curChar = '';
    119                 return;
    120             }
    121             else
    122             {
    123                 _curChar = _value[_curIndex];
    124                 _curIndex += 1;
    125             }
    126            
    127         }
    128         public enum ETokenType
    129         {
    130             Nothing,
    131             Character,
    132             Numberic,
    133         }
    134     }
    135 }
    View Code


    另可参考:

    http://www.codeproject.com/Articles/22175/Sorting-Strings-for-Humans-with-IComparer

    感谢每一位阅读此篇文章的人,希望可以帮到你。

  • 相关阅读:
    C和指针 第十七章 经典数据类型 堆栈 队列 二叉树
    C和指针 第十六章 习题
    C和指针 第十六章 标准函数库 信号
    C和指针 第十六章 标准函数库 本地跳转setjmp.h
    C和指针 第十六章 标准函数库
    C和指针 第十五章 习题
    C和指针 第十五章 二进制I/O
    C和指针 第十五章 文件I/O
    C和指针 第十五章 输入输出缓冲
    C和指针 第十五章 错误报告perror和exit
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/5504170.html
Copyright © 2011-2022 走看看