天天看點

檔案名智能排序(按照數字大小排序)

有時候需要将檔案名按照數字大小排序,而不是按照字母順序排序,例如:

Traditional Sort

Alphanum

   在Windows XP及以後的系統中,通過修改系統資料庫,或者使用組政策(實質上還是修改系統資料庫),可以控制使用哪種排序方式,進行檔案名排序。在

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Explorer下面建立

DWORD鍵:NoStrCmpLogical,然後設定值為1,禁止使用智能排序;設定為0,啟用智能排序。

程式實作智能排序,有人已經寫了,在這轉一下C#實作。最後的參考清單中的網址上,有各種語言的實作方法。

<code>/*</code>

<code> </code><code>* The Alphanum Algorithm is an improved sorting algorithm for strings</code>

<code> </code><code>* containing numbers.  Instead of sorting numbers in ASCII order like</code>

<code> </code><code>* a standard sort, this algorithm sorts numbers in numeric order.</code>

<code> </code><code>*</code>

<code> </code><code>* The Alphanum Algorithm is discussed at http://www.DaveKoelle.com</code>

<code> </code><code>* Based on the Java implementation of Dave Koelle's Alphanum algorithm.</code>

<code> </code><code>* Contributed by Jonathan Ruckwood &lt;[email protected]&gt;</code>

<code> </code><code>* Adapted by Dominik Hurnaus &lt;[email protected]&gt; to</code>

<code> </code><code>*   - correctly sort words where one word starts with another word</code>

<code> </code><code>*   - have slightly better performance</code>

<code> </code><code>* This library is free software; you can redistribute it and/or</code>

<code> </code><code>* modify it under the terms of the GNU Lesser General Public</code>

<code> </code><code>* License as published by the Free Software Foundation; either</code>

<code> </code><code>* version 2.1 of the License, or any later version.</code>

<code> </code><code>* This library is distributed in the hope that it will be useful,</code>

<code> </code><code>* but WITHOUT ANY WARRANTY; without even the implied warranty of</code>

<code> </code><code>* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</code>

<code> </code><code>* Lesser General Public License for more details.</code>

<code> </code><code>* You should have received a copy of the GNU Lesser General Public</code>

<code> </code><code>* License along with this library; if not, write to the Free Software</code>

<code> </code><code>* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</code>

<code> </code><code>*/</code>

<code>using</code> <code>System;</code>

<code>using</code> <code>System.Collections;</code>

<code>using</code> <code>System.Text;</code>

<code> </code><code>* Please compare against the latest Java version at http://www.DaveKoelle.com</code>

<code> </code><code>* to see the most recent modifications</code>

<code>namespace</code> <code>AlphanumComparator</code>

<code>{</code>

<code>    </code><code>public</code> <code>class</code> <code>AlphanumComparator : IComparer</code>

<code>    </code><code>{</code>

<code>        </code><code>private</code> <code>enum</code> <code>ChunkType {Alphanumeric, Numeric};</code>

<code>        </code><code>private</code> <code>bool</code> <code>InChunk(</code><code>char</code> <code>ch, </code><code>char</code> <code>otherCh)</code>

<code>        </code><code>{</code>

<code>            </code><code>ChunkType type = ChunkType.Alphanumeric;</code>

<code>            </code><code>if</code> <code>(</code><code>char</code><code>.IsDigit(otherCh))</code>

<code>            </code><code>{</code>

<code>                </code><code>type = ChunkType.Numeric;</code>

<code>            </code><code>}</code>

<code>            </code><code>if</code> <code>((type == ChunkType.Alphanumeric &amp;&amp; </code><code>char</code><code>.IsDigit(ch))</code>

<code>                </code><code>|| (type == ChunkType.Numeric &amp;&amp; !</code><code>char</code><code>.IsDigit(ch)))</code>

<code>                </code><code>return</code> <code>false</code><code>;</code>

<code>            </code><code>return</code> <code>true</code><code>;</code>

<code>        </code><code>}</code>

<code>        </code><code>public</code> <code>int</code> <code>Compare(</code><code>object</code> <code>x, </code><code>object</code> <code>y)</code>

<code>            </code><code>String s1 = x </code><code>as</code> <code>string</code><code>;</code>

<code>            </code><code>String s2 = y </code><code>as</code> <code>string</code><code>;</code>

<code>            </code><code>if</code> <code>(s1 == </code><code>null</code> <code>|| s2 == </code><code>null</code><code>)</code>

<code>                </code><code>return</code> <code>0;</code>

<code>            </code><code>int</code> <code>thisMarker = 0, thisNumericChunk = 0;</code>

<code>            </code><code>int</code> <code>thatMarker = 0, thatNumericChunk = 0;</code>

<code>            </code><code>while</code> <code>((thisMarker &lt; s1.Length) || (thatMarker &lt; s2.Length))</code>

<code>                </code><code>if</code> <code>(thisMarker &gt;= s1.Length)</code>

<code>                </code><code>{</code>

<code>                    </code><code>return</code> <code>-1;</code>

<code>                </code><code>}</code>

<code>                </code><code>else</code> <code>if</code> <code>(thatMarker &gt;= s2.Length)</code>

<code>                    </code><code>return</code> <code>1;</code>

<code>                </code><code>char</code> <code>thisCh = s1[thisMarker];</code>

<code>                </code><code>char</code> <code>thatCh = s2[thatMarker];</code>

<code>                </code><code>StringBuilder thisChunk = </code><code>new</code> <code>StringBuilder();</code>

<code>                </code><code>StringBuilder thatChunk = </code><code>new</code> <code>StringBuilder();</code>

<code>                </code><code>while</code> <code>((thisMarker &lt; s1.Length) &amp;&amp; (thisChunk.Length==0 ||InChunk(thisCh, thisChunk[0])))</code>

<code>                    </code><code>thisChunk.Append(thisCh);</code>

<code>                    </code><code>thisMarker++;</code>

<code>                    </code><code>if</code> <code>(thisMarker &lt; s1.Length)</code>

<code>                    </code><code>{</code>

<code>                        </code><code>thisCh = s1[thisMarker];</code>

<code>                    </code><code>}</code>

<code>                </code><code>while</code> <code>((thatMarker &lt; s2.Length) &amp;&amp; (thatChunk.Length==0 ||InChunk(thatCh, thatChunk[0])))</code>

<code>                    </code><code>thatChunk.Append(thatCh);</code>

<code>                    </code><code>thatMarker++;</code>

<code>                    </code><code>if</code> <code>(thatMarker &lt; s2.Length)</code>

<code>                        </code><code>thatCh = s2[thatMarker];</code>

<code>                </code><code>int</code> <code>result = 0;</code>

<code>                </code><code>// If both chunks contain numeric characters, sort them numerically</code>

<code>                </code><code>if</code> <code>(</code><code>char</code><code>.IsDigit(thisChunk[0]) &amp;&amp; </code><code>char</code><code>.IsDigit(thatChunk[0]))</code>

<code>                    </code><code>thisNumericChunk = Convert.ToInt32(thisChunk.ToString());</code>

<code>                    </code><code>thatNumericChunk = Convert.ToInt32(thatChunk.ToString());</code>

<code>                    </code><code>if</code> <code>(thisNumericChunk &lt; thatNumericChunk)</code>

<code>                        </code><code>result = -1;</code>

<code>                    </code><code>if</code> <code>(thisNumericChunk &gt; thatNumericChunk)</code>

<code>                        </code><code>result = 1;</code>

<code>                </code><code>else</code>

<code>                    </code><code>result = thisChunk.ToString().CompareTo(thatChunk.ToString());</code>

<code>                </code><code>if</code> <code>(result != 0)</code>

<code>                    </code><code>return</code> <code>result;</code>

<code>            </code><code>return</code> <code>0;</code>

<code>    </code><code>}</code>

<code>}</code>

本文轉自 h2appy  51CTO部落格,原文連結:http://blog.51cto.com/h2appy/1375457,如需轉載請自行聯系原作者

繼續閱讀