初步实现带有数字的字符串的排序(数字区别大小)

目录(?)[-]

  1. 描述
  2. 返回值
  3. 遵循于

问题

对于fss2,fss10,fss1,fss11,fss02排序,如果想对数字识别大小排序,传统排序是字典排序,不能达到目标,如下表:

散列 字典排序 目标排序
fss2 fss1 fss1
fss10 fss02 fss2
fss1 fss10 fss02
fss11 fss11 fss10
fss02 fss2 fss11

我们对字符串比较是对数字进行识别,数字就按数值大小排列。

1、假设比较单元,非数字字符就是一个比较单元;连续数字是一个比较单元。

2、数字前字符串连续相同。

3、数值相等但有前缀0若干个的,设定多的为大,升序排列靠下。

4、数字主要针对整数,可无限大,小数其实就是3个比较单元:数字、点、数字。

C源码

[cpp]  view plain  copy
 
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5.   
  6. #ifdef _UNICODE  
  7. #define LogicCompare LogicCompareW  
  8. #define findDigitEnd findDigitEndW  
  9. #else  
  10. #define LogicCompare LogicCompareA  
  11. #define findDigitEnd findDigitEndA  
  12. #endif  
  13.   
  14. int LogicCompareW(wchar_t *psza, wchar_t *pszb);  
  15. int LogicCompareA(char *psza, char *pszb);  
  16. wchar_t * findDigitEnd(wchar_t **pszBuffer);  
  17. char * findDigitEnd(char **pszBuffer);  
  18.   
  19. //unsigned....return the none-zero poniter or null-end and if find '0', it will move the input pointer.  
  20. wchar_t * findDigitEndW(wchar_t **pszBuffer)  
  21. {  
  22.     wchar_t *pszEnd = *pszBuffer;  
  23.     bool hasFirstZero = *pszEnd == _T('0');  
  24.     while (*pszEnd)  
  25.     {  
  26.         //high case firstly!  
  27.         if (*pszEnd < _T('0') || *pszEnd > _T('9'))  
  28.         {  
  29.             break;  
  30.         }  
  31.         else if (hasFirstZero && _T('0') == *pszEnd)  
  32.         {  
  33.             (*pszBuffer)++;  
  34.         }  
  35.         pszEnd++;  
  36.           
  37.     }  
  38.     return pszEnd;  
  39. }  
  40.   
  41. char * findDigitEndA(char **pszBuffer)  
  42. {  
  43.     char *pszEnd = *pszBuffer;  
  44.     bool hasFirstZero = *pszEnd == _T('0');  
  45.     while (*pszEnd)  
  46.     {  
  47.         //high case firstly!  
  48.         if (*pszEnd < _T('0') || *pszEnd > _T('9'))  
  49.         {  
  50.             break;  
  51.         }  
  52.         else if (hasFirstZero && _T('0') == *pszEnd)  
  53.         {  
  54.             (*pszBuffer)++;  
  55.         }  
  56.         pszEnd++;  
  57.   
  58.     }  
  59.     return pszEnd;  
  60. }  
  61.   
  62. //fang0001san022san: a alpha(f,a,...) is a compared unit, but a number(0001,022) will be condsided as one too.  
  63. int LogicCompareW(wchar_t *psza, wchar_t *pszb){  
  64.     wchar_t *paCur = psza, *pbCur = pszb;  
  65.     if (psza != NULL && NULL != pszb)  
  66.     {  
  67.         wchar_t *paDigitEnd, *pbDigitEnd;  
  68.         wchar_t *paNonZero, *pbNonZero;  
  69.         while (*paCur && *paCur){  
  70.             paNonZero = paCur;  
  71.             pbNonZero = pbCur;  
  72.             //allow for:    0    ...    0      1      2...  
  73.             //            paCur            paNonZero  
  74.             paDigitEnd = findDigitEndW(&paNonZero);  
  75.             pbDigitEnd = findDigitEndW(&pbNonZero);  
  76.   
  77.             //compare by number   
  78.             if (paDigitEnd > paCur && pbDigitEnd > pbCur)  
  79.             {                 
  80.                 int aDigitLength = paDigitEnd - paNonZero;  
  81.                 int bDigitLength = pbDigitEnd - pbNonZero;  
  82.                 //compare by digit   
  83.                 if (aDigitLength != bDigitLength)  
  84.                     return aDigitLength - bDigitLength;  
  85.                 //the number of their digit is same.  
  86.                 while (paNonZero < paDigitEnd){  
  87.                     if (*paNonZero != *pbNonZero)  
  88.                         return *paNonZero - *pbNonZero;  
  89.                     paNonZero++;  
  90.                     pbNonZero++;  
  91.                 }  
  92.   
  93.                 //if they are equal compared by number, compare the number of '0' when start with "0"   
  94.                 aDigitLength = paNonZero - paCur;  
  95.                 bDigitLength = pbNonZero - pbCur;  
  96.                 if (aDigitLength != bDigitLength)  
  97.                     return bDigitLength - aDigitLength;  
  98.                 paCur = paDigitEnd;  
  99.                 pbCur = pbDigitEnd;  
  100.             }  
  101.             else{  
  102.                 if (*paCur != *pbCur)  
  103.                     return *paCur - *pbCur;  
  104.                 paCur++;  
  105.                 pbCur++;  
  106.             }  
  107.         }  
  108.     }  
  109.     //last condtion should be never reached.  
  110.     return NULL == paCur ? -1 : NULL == pbCur ? -1 : *paCur - *pbCur;  
  111. }  
  112.   
  113. //fang0001san022san: a alpha(f,a,...) is a compared unit, but a number(0001,022) will be condsided as one too.  
  114. int LogicCompareA(char *psza, char *pszb){  
  115.     char *paCur = psza, *pbCur = pszb;  
  116.     if (psza != NULL && NULL != pszb)  
  117.     {  
  118.         char *paDigitEnd, *pbDigitEnd;  
  119.         char *paNonZero, *pbNonZero;  
  120.         while (*paCur && *paCur){  
  121.             paNonZero = paCur;  
  122.             pbNonZero = pbCur;  
  123.             //allow for:    0    ...    0      1      2...  
  124.             //            paCur            paNonZero  
  125.             paDigitEnd = findDigitEndA(&paNonZero);  
  126.             pbDigitEnd = findDigitEndA(&pbNonZero);  
  127.   
  128.             //compare by number   
  129.             if (paDigitEnd > paCur && pbDigitEnd > pbCur)  
  130.             {  
  131.                 int aDigitLength = paDigitEnd - paNonZero;  
  132.                 int bDigitLength = pbDigitEnd - pbNonZero;  
  133.                 //compare by digit   
  134.                 if (aDigitLength != bDigitLength)  
  135.                     return aDigitLength - bDigitLength;  
  136.                 //the number of their digit is same.  
  137.                 while (paNonZero < paDigitEnd){  
  138.                     if (*paNonZero != *pbNonZero)  
  139.                         return *paNonZero - *pbNonZero;  
  140.                     paNonZero++;  
  141.                     pbNonZero++;  
  142.                 }  
  143.   
  144.                 //if they are equal compared by number, compare the number of '0' when start with "0"   
  145.                 //ps note: paNonZero and pbNonZero can be added the above loop "while", but it is changed meanwhile.  
  146.                 //so, the following comparsion is ok.  
  147.                 aDigitLength = paNonZero - paCur;  
  148.                 bDigitLength = pbNonZero - pbCur;  
  149.                 if (aDigitLength != bDigitLength)  
  150.                     return bDigitLength - aDigitLength;  
  151.                 paCur = paDigitEnd;  
  152.                 pbCur = pbDigitEnd;  
  153.             }  
  154.             else{  
  155.                 if (*paCur != *pbCur)  
  156.                     return *paCur - *pbCur;  
  157.                 paCur++;  
  158.                 pbCur++;  
  159.             }  
  160.         }  
  161.     }  
  162.     //last condition should be never reached.  
  163.     return NULL == paCur ? -1 : NULL == pbCur ? -1 : *paCur - *pbCur;  
  164. }  
  165.   
  166. int LogicCompareWithPrint(TCHAR *psza, TCHAR *pszb){  
  167.     _tprintf(_T("LogicCompare : %s%*s%s%*s"), psza, 12 - _tcslen(psza), ",", pszb, 10 - _tcslen(pszb), " ");  
  168.     return LogicCompare(psza, pszb);  
  169. }  
  170.   
  171. int _tmain(int argc, _TCHAR* argv[])  
  172. {  
  173.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("a00011b01"), _T("a011b01")));  
  174.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("a0011"), _T("a02")));  
  175.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("a011b011"), _T("a011b11")));  
  176.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("a011b11"), _T("a011b2")));  
  177.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("a11"), _T("a2")));  
  178.   
  179.     _tprintf(_T("\t: %d\n"), LogicCompareWithPrint(_T("0"), _T("_")));  
  180.     _tprintf(_T("'0'(48) - '_'(95) = %d\n\n"), _T('0') - _T('_'));  
  181.   
  182.     TCHAR *values[] = {_T("ss1"), _T("f00000111111111111111111111111111111111111111111111111111111111"), _T("ss01"), _T("房-"), _T("f0001"),  
  183.         _T("ss_1"), _T("ss002"), _T("房-01s2"), _T("f111111111111111111111111111111111111111111111111111111111"), _T("房-01s10") };  
  184.     TCHAR **ppa = values;  
  185.     TCHAR **ppb;  
  186.     TCHAR **ppend= values+9;  
  187.     while (ppa < ppend){  
  188.         ppb = ppa+1;  
  189.         while (ppb <= ppend)  
  190.         {  
  191.             if (LogicCompare(*ppa, *ppb) > 0)  
  192.             {  
  193.                 TCHAR *pTemp = *ppa;  
  194.                 *ppa = *ppb;  
  195.                 *ppb = pTemp;  
  196.             }  
  197.             ppb++;  
  198.         }  
  199.         ppa++;  
  200.     }  
  201.     ppa = values;  
  202.   
  203.   
  204.     _tsetlocale(LC_ALL, _T("chs"));//LC_ALL = 0; make "wprintf" output a UNICODE string.  
  205.   
  206.     while (ppa <= ppend){  
  207.         _tprintf(_T("%s\n"), *ppa);  
  208.         ppa++;  
  209.     }  
  210.   
  211.     getchar();  
  212.     return 0;  
  213. }  

输出截图

案例输出(右边是windows-shell-对文件名逻辑排序(xp以上还是vista)的比较图):

以发现不同:下划线_和数字0

初步实现带有数字的字符串的排序(数字区别大小)_第1张图片初步实现带有数字的字符串的排序(数字区别大小)_第2张图片



Java实现

[java]  view plain  copy
 
  1. package san;  
  2.   
  3. import java.util.Arrays;  
  4. import java.util.Comparator;  
  5. import java.util.regex.Matcher;  
  6. import java.util.regex.Pattern;  
  7.   
  8. public class Demo {  
  9.   
  10.     public static void main(String[] args) {  
  11.         // TODO Auto-generated method stub  
  12.         String fileNames[] = { "fss01""fss2""fss01_22""fss3""fss1""fss10""fss20""fss4""fss30""fss21""fss12","fss01_3" };  
  13.         char chFileNames[][] = new char[fileNames.length][];  
  14.         String[] oldSortedNames = new String[fileNames.length];  
  15.         for (int i = 0; i < fileNames.length; i++) {  
  16.             chFileNames[i] = fileNames[i].toCharArray();  
  17.             oldSortedNames[i] = fileNames[i];  
  18.         }  
  19.   
  20.         // Arrays.sort(fileNames, StrLogicCmp);  
  21.         Arrays.sort(chFileNames, ChsLogicCmp);  
  22.         System.out.println("_Random_" + "\t" + "_Tradion_" + "\t" + "_Target_");  
  23.         String line;  
  24.         for (int i = 0; i < fileNames.length; i++) {  
  25.             line = fileNames[i] + (fileNames[i].length() >= 8 ? "\t" : "\t\t");  
  26.             line += oldSortedNames[i] + (oldSortedNames[i].length() >= 8 ? "\t" : "\t\t");  
  27.             line += new String(chFileNames[i]);  
  28.             System.out.println(line);  
  29.               
  30.         }  
  31.           
  32.           
  33.     }  
  34.       
  35.     static Comparator StrLogicCmp = new Comparator() {  
  36.   
  37.         @Override  
  38.         public int compare(String o1, String o2) {  
  39.             // TODO Auto-generated method stub  
  40.             return 0;  
  41.         }  
  42.           
  43.     };  
  44.       
  45.     // "f01s2s22", "f1s02s2"  
  46.     static Comparator<char[]> ChsLogicCmp = new Comparator<char[]>() {  
  47.         class Int{  
  48.             public int i;  
  49.         }  
  50.         public int findDigitEnd(char[] arrChar, Int at) {  
  51.             int k = at.i;  
  52.             char c = arrChar[k];  
  53.             boolean bFirstZero = (c == '0');  
  54.             while (k < arrChar.length) {  
  55.                 c = arrChar[k];  
  56.                 //first non-digit which is a high chance.  
  57.                 if (c > '9' || c < '0') {  
  58.                     break;  
  59.                 }  
  60.                 else if (bFirstZero && c == '0') {  
  61.                     at.i++;   
  62.                 }  
  63.                 k++;  
  64.             }  
  65.             return k;  
  66.         }  
  67.   
  68.         @Override  
  69.         public int compare(char[] a, char[] b) {  
  70.             if(a != null || b != null){  
  71.                 Int aNonzeroIndex = new Int();  
  72.                 Int bNonzeroIndex = new Int();  
  73.                 int aIndex = 0, bIndex = 0,   
  74.                 aComparedUnitTailIndex, bComparedUnitTailIndex;  
  75.       
  76. //              Pattern pattern = Pattern.compile("D*(d+)D*");  
  77. //              Matcher matcher1 = pattern.matcher(a);  
  78. //              Matcher matcher2 = pattern.matcher(b);  
  79. //              if(matcher1.find() && matcher2.find()) {  
  80. //                  String s1 = matcher1.group(1);  
  81. //                  String s2 = matcher2.group(1);  
  82. //              }  
  83.                       
  84.                 while(aIndex < a.length && bIndex < b.length){  
  85.                     //aIndex <   
  86.                     aNonzeroIndex.i = aIndex;  
  87.                     bNonzeroIndex.i = bIndex;  
  88.                     aComparedUnitTailIndex = findDigitEnd(a, aNonzeroIndex);  
  89.                     bComparedUnitTailIndex = findDigitEnd(b, bNonzeroIndex);  
  90.                     //compare by number   
  91.                     if (aComparedUnitTailIndex > aIndex && bComparedUnitTailIndex > bIndex)  
  92.                     {  
  93.                         int aDigitIndex = aNonzeroIndex.i;  
  94.                         int bDigitIndex = bNonzeroIndex.i;  
  95.                         int aDigit = aComparedUnitTailIndex - aDigitIndex;  
  96.                         int bDigit = bComparedUnitTailIndex - bDigitIndex;  
  97.                         //compare by digit   
  98.                         if(aDigit != bDigit)  
  99.                             return aDigit - bDigit;  
  100.                         //the number of their digit is same.  
  101.                         while (aDigitIndex < aComparedUnitTailIndex){  
  102.                             if (a[aDigitIndex] != b[bDigitIndex])  
  103.                                 return a[aDigitIndex] - b[bDigitIndex];  
  104.                             aDigitIndex++;  
  105.                             bDigitIndex++;  
  106.                         }  
  107.                         //if they are equal compared by number, compare the number of '0' when start with "0"   
  108.                         //ps note: paNonZero and pbNonZero can be added the above loop "while", but it is changed meanwhile.  
  109.                         //so, the following comparsion is ok.  
  110.                         aDigit = aNonzeroIndex.i - aIndex;  
  111.                         bDigit = bNonzeroIndex.i - bIndex;  
  112.                         if (aDigit != bDigit)  
  113.                             return aDigit - bDigit;  
  114.                         aIndex = aComparedUnitTailIndex;  
  115.                         bIndex = bComparedUnitTailIndex;  
  116.                     }else{  
  117.                         if (a[aIndex] != b[bIndex])  
  118.                             return a[aIndex] - b[bIndex];  
  119.                         aIndex++;  
  120.                         bIndex++;  
  121.                     }  
  122.                       
  123.                 }  
  124.                   
  125.             }  
  126.             return a.length - b.length;  
  127.         }  
  128.   
  129.     };  
  130. }  

输出结果

_Random_ _Tradion_ _Target_
fss01 fss01  fss1
fss2 fss2  fss01
fss01_22 fss01_22 fss01_3
fss3 fss3  fss01_22
fss1 fss1  fss2
fss10 fss10  fss3
fss20 fss20  fss4
fss4 fss4  fss10
fss30 fss30  fss12
fss21 fss21  fss20
fss12 fss12  fss21
fss01_3 fss01_3 fss30

引用

这里2001年就有了

#define _GNU_SOURCE /* 见 feature_test_macros(7) */

#include 

int strverscmp(const char *s1, const char *s2);

描述

经常有这样的文件  jan1 jan2 、……、 jan9 jan10 ,……并且感觉  ls (1) 排序为  jan1 jan10 、……、 jan2 、……、 jan9  是不正确的。为了改变这个情况,GNU 允许使用  -v  选项的  ls (1),它的实现使用  versionsort (3),这个函数使用了  strverscmp ()。

因此,strverscmp() 是比较两个字符串并发现“正确”的顺序,而 strcmp(3) 只是发现字典顺序。这个函数不使用区域选项 LC_COLLATE,也就是说它期待字符串是 ASCII 字符串。

这个函数做下面的事。如果两个字符串相同,返回 0。否则找出分界字符,两个字串在其前都相同而其它却不同。找出最大的连续不断的数字字符(开始于,或结束于)这个位置。如果一个或两个这个子串都是空的,则像 strcmp(3) 一样返回(字节值的数值顺序)。否则,比较两个数字串的数值,如果前面有十进制点则起始的一个或多个零也会被处理(因此有多个零的子串将比零的个数较少的串更小)。所以,这个顺序大概像 00000010100901910

返回值

strverscmp () 函数一个小于、等于或大于零的整数,如果发现  s1  小于、等于或大于  s2

遵循于

这个函数是 GNU 扩展。


源码

[cpp]  view plain  copy
 
  1. /** Compare strings while treating digits characters numerically. 
  2.    Copyright (C) 1997, 2002, 2005 Free Software Foundation, Inc. 
  3.    This file is part of the libiberty library. 
  4.    Contributed by Jean-François Bignolles , 1997. 
  5.  
  6.    Libiberty is free software; you can redistribute it and/or 
  7.    modify it under the terms of the GNU Lesser General Public 
  8.    License as published by the Free Software Foundation; either 
  9.    version 2.1 of the License, or (at your option) any later version. 
  10.  
  11.    Libiberty is distributed in the hope that it will be useful, 
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  14.    Lesser General Public License for more details. 
  15.  
  16.    You should have received a copy of the GNU Lesser General Public 
  17.    License along with the GNU C Library; if not, write to the Free 
  18.    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
  19.    02110-1301 USA.  */  
  20.   
  21. #include "libiberty.h"  
  22. #include "safe-ctype.h"  
  23.   
  24. /**  
  25. @deftypefun int strverscmp (const char *@var{s1}, const char *@var{s2}) 
  26. The @code{strverscmp} function compares the string @var{s1} against 
  27. @var{s2}, considering them as holding indices/version numbers.  Return 
  28. value follows the same conventions as found in the @code{strverscmp} 
  29. function.  In fact, if @var{s1} and @var{s2} contain no digits, 
  30. @code{strverscmp} behaves like @code{strcmp}. 
  31.  
  32. Basically, we compare strings normally (character by character), until 
  33. we find a digit in each string - then we enter a special comparison 
  34. mode, where each sequence of digits is taken as a whole.  If we reach the 
  35. end of these two parts without noticing a difference, we return to the 
  36. standard comparison mode.  There are two types of numeric parts: 
  37. "integral" and "fractional" (those  begin with a '0'). The types 
  38. of the numeric parts affect the way we sort them: 
  39.  
  40. @itemize @bullet 
  41. @item 
  42. integral/integral: we compare values as you would expect. 
  43.  
  44. @item 
  45. fractional/integral: the fractional part is less than the integral one. 
  46. Again, no surprise. 
  47.  
  48. @item 
  49. fractional/fractional: the things become a bit more complex. 
  50. If the common prefix contains only leading zeroes, the longest part is less 
  51. than the other one; else the comparison behaves normally. 
  52. @end itemize 
  53.  
  54. @smallexample 
  55. strverscmp ("no digit", "no digit") 
  56.     @result{} 0    // @r{same behavior as strcmp.} 
  57. strverscmp ("item#99", "item#100") 
  58.     @result{} <0   // @r{same prefix, but 99 < 100.} 
  59. strverscmp ("alpha1", "alpha001") 
  60.     @result{} >0   // @r{fractional part inferior to integral one.} 
  61. strverscmp ("part1_f012", "part1_f01") 
  62.     @result{} >0   // @r{two fractional parts.} 
  63. strverscmp ("foo.009", "foo.0") 
  64.     @result{} <0   // @r{idem, but with leading zeroes only.} 
  65. @end smallexample 
  66.  
  67. This function is especially useful when dealing with filename sorting, 
  68. because filenames frequently hold indices/version numbers. 
  69. @end deftypefun 
  70.  
  71. */  
  72.   
  73. /** states: S_N: normal, S_I: comparing integral part, S_F: comparing 
  74.            fractional parts, S_Z: idem but with leading Zeroes only */  
  75. #define  S_N    0x0  
  76. #define  S_I    0x4  
  77. #define  S_F    0x8  
  78. #define  S_Z    0xC  
  79.   
  80. /** result_type: CMP: return diff; LEN: compare using len_diff/diff */  
  81. #define  CMP    2  
  82. #define  LEN    3  
  83.   
  84.   
  85. /** Compare S1 and S2 as strings holding indices/version numbers, 
  86.    returning less than, equal to or greater than zero if S1 is less than, 
  87.    equal to or greater than S2 (for more info, see the Glibc texinfo doc).  */  
  88.   
  89. int  
  90. strverscmp (const char *s1, const char *s2)  
  91. {  
  92.   const unsigned char *p1 = (const unsigned char *) s1;  
  93.   const unsigned char *p2 = (const unsigned char *) s2;  
  94.   unsigned char c1, c2;  
  95.   int state;  
  96.   int diff;  
  97.   
  98.   /** Symbol(s)    0       [1-9]   others  (padding) 
  99.      Transition   (10) 0  (01) d  (00) x  (11) -   */  
  100.   static const unsigned int next_state[] =  
  101.     {  
  102.       /** state    x    d    0    - */  
  103.       /** S_N */  S_N, S_I, S_Z, S_N,  
  104.       /** S_I */  S_N, S_I, S_I, S_I,  
  105.       /** S_F */  S_N, S_F, S_F, S_F,  
  106.       /** S_Z */  S_N, S_F, S_Z, S_Z  
  107.     };  
  108.   
  109.   static const int result_type[] =  
  110.     {  
  111.       /** state   x/x  x/d  x/0  x/-  d/x  d/d  d/0  d/- 
  112.                  0/x  0/d  0/0  0/-  -/x  -/d  -/0  -/- */  
  113.   
  114.       /** S_N */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,  
  115.                  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,  
  116.       /** S_I */  CMP, -1,  -1,  CMP, +1,  LEN, LEN, CMP,  
  117.                  +1,  LEN, LEN, CMP, CMP, CMP, CMP, CMP,  
  118.       /** S_F */  CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,  
  119.                  CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,  
  120.       /** S_Z */  CMP, +1,  +1,  CMP, -1,  CMP, CMP, CMP,  
  121.                  -1,  CMP, CMP, CMP  
  122.     };  
  123.   
  124.   if (p1 == p2)  
  125.     return 0;  
  126.   
  127.   c1 = *p1++;  
  128.   c2 = *p2++;  
  129.   /** Hint: '0' is a digit too.  */  
  130.   state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));  
  131.   
  132.   while ((diff = c1 - c2) == 0 && c1 != '\0')  
  133.     {  
  134.       state = next_state[state];  
  135.       c1 = *p1++;  
  136.       c2 = *p2++;  
  137.       state |= (c1 == '0') + (ISDIGIT (c1) != 0);  
  138.     }  
  139.   
  140.   state = result_type[state << 2 | (((c2 == '0') + (ISDIGIT (c2) != 0)))];  
  141.   
  142.   switch (state)  
  143.     {  
  144.     case CMP:  
  145.       return diff;  
  146.         
  147.     case LEN:  
  148.       while (ISDIGIT (*p1++))  
  149.     if (!ISDIGIT (*p2++))  
  150.       return 1;  
  151.         
  152.       return ISDIGIT (*p2) ? -1 : diff;  
  153.         
  154.     default:  
  155.       return state;  
  156.     }  
  157. }  

你可能感兴趣的:(算法,java,基础)