2009-10-21 32 views
8

對於我的應用程序中的自然排序,我目前在shlwapi.dll中調用一個名爲StrCmpLogicalW的函數。我正在考慮嘗試在單聲道下運行我的應用程序,但當然我不能擁有這個P/Invoke的東西(據我所知,無論如何)。C#:在shlwapi.dll中實現或替代StrCmpLogicalW

是否有可能在某個地方看到該方法的實現,或者是否有一個好的,乾淨而高效的C#代碼片段來執行相同的操作?

我的代碼目前看起來是這樣的:

[SuppressUnmanagedCodeSecurity] 
internal static class SafeNativeMethods 
{ 
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] 
    public static extern int StrCmpLogicalW(string psz1, string psz2); 
} 

public class NaturalStringComparer : IComparer<string> 
{ 
    private readonly int modifier = 1; 

    public NaturalStringComparer() : this(false) {} 
    public NaturalStringComparer(bool descending) 
    { 
     if (descending) modifier = -1; 
    } 

    public int Compare(string a, string b) 
    { 
     return SafeNativeMethods.StrCmpLogicalW(a ?? "", b ?? "") * modifier; 
    } 
} 

所以,我正在尋找的是不使用外部函數上面的類的替代品。

+0

我剛剛發現這個[上自然排序的博客文章(http://www.interact-sw.co.uk/iangblog/2007/ 12/13 /自然排序)在C#中。這有什麼用處?迴應你的評論 - 我沒有詳細分析它自己,它看起來很有希望。必須有其他的自然排序的c#實現,也許你只需要找到一個並配置它? – ChrisF 2009-10-21 16:05:35

+0

剛剛讀完它實際上:P它似乎做我認爲應該,但它也似乎相當低效......我不知道,雖然......嘿嘿。 – Svish 2009-10-21 16:07:50

回答

10

我剛剛實施了C#自然字符串比較,也許有人會發現它有用:

public class NaturalComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     if (x == null && y == null) return 0; 
     if (x == null) return -1; 
     if (y == null) return 1; 

     int lx = x.Length, ly = y.Length; 

     for (int mx = 0, my = 0; mx < lx && my < ly; mx++, my++) 
     { 
     if (char.IsDigit(x[mx]) && char.IsDigit(y[my])) 
     { 
      long vx = 0, vy = 0; 

      for (; mx < lx && char.IsDigit(x[mx]); mx++) 
       vx = vx * 10 + x[mx] - '0'; 

      for (; my < ly && char.IsDigit(y[my]); my++) 
       vy = vy * 10 + y[my] - '0'; 

      if (vx != vy) 
       return vx > vy ? 1 : -1; 
     } 

     if (mx < lx && my < ly && x[mx] != y[my]) 
      return x[mx] > y[my] ? 1 : -1; 
     } 

     return lx - ly; 
    } 
} 
+0

它不完整,如果你有ex1,ex-3,ex2,那麼ex-3將變成最後一個。 pinvoke窗口函數自然排序算法,它像探險家一樣。 – 2017-04-04 10:14:40

0

我用正則表達式來刪除特殊字符。然後轉換爲int。然後我比較整數。

輸入:

 
List input = new List{ "6.04","6.01","6.03","6#04" };
預期輸出:

 
6.01 
6.03 
6.04 
6#04 
 

var output = input.OrderBy(s => s, new NaturalStringComparer()); 
      foreach (var sort in output) 
      { 
       Console.WriteLine(sort); 
      } 


public struct NaturalStringComparer : IComparer 
    { 
     public int Compare(string x, string y) 
     { 
      if (x == null && y == null) return 0; 
      if (x == null) return -1; 
      if (y == null) return 1; 

      int lx = x.Length, ly = y.Length; 

      int a = int.Parse(System.Text.RegularExpressions.Regex.Replace(x, @"\D+", "")); 
      int b = int.Parse(System.Text.RegularExpressions.Regex.Replace(y, @"\D+", "")); 

      return a.CompareTo(b); 
     } 
    } 
+0

請評論。如果你發現性能相關的問題。我做任何錯誤將字符串轉換爲int。 – 2017-04-24 09:37:05