2009-04-24 23 views
11

पूर्णांक मानों के साथ स्ट्रिंग की सूची सॉर्ट करते समय मुझे एक अजीब समस्या का सामना करना पड़ रहा है। हालांकि कुछ मूल्यों को कुछ पात्रों के साथ पूर्ववर्ती किया जा सकता है।इंटीजर स्ट्रिंग्स को कैसे सॉर्ट करें?

उदा।

// B1, 5, 50, A10, 7, 72, B3, A1, A2 

मूल रूप से पृष्ठ संख्या रहे हैं और इस तरह के अनुसार क्रमबद्ध किया जाना चाहिए:

// A1, A2, A10, B1, B3, 5, 7, 50, 72 

लेकिन अगर मैं डिफ़ॉल्ट स्ट्रिंग तो छँटाई का उपयोग इस तरह के

// A1, A10, A2, B1, B3, 5, 50, 7, 72 

में इस के लिए कोई समाधान हल हो जाएगा सी#?

+0

आप इस 'NaturalStringComparer' उपयोग कर सकते हैं कि मैं एक साथ रखा और थोड़ा साफ (याद जहां मैं इसके लिए आधार मिल गया न करें) । यह Win32 फ़ंक्शन StrCmpLogicalW का उपयोग करता है जो स्कीज़ का उल्लेख है। http://my.opera.com/Svishy/blog/2009/03/02/natural-sorting – Svish

उत्तर

17

आप Alphanum algorithm के लिए देख रहे हैं। सौभाग्य से आपके लिए, कई कार्यान्वयन पहले से मौजूद हैं। here देखें।

+0

अल्फानम // 5, 7, 50, 72, ए 1, ए 2, ए 10, बी 1, बी 3 के बदले // ए 1 ... 5 – Carra

+2

यदि आप कुछ कोड नमूने से गुज़रते हैं, तो यह बताया गया है कि आप इसे अलग-अलग परिदृश्यों को समायोजित करने के लिए कैसे बदल देंगे। –

0

ठीक है, आप हमेशा Win32 API फ़ंक्शन StrCmpLogicalW को PInvoke कर सकते हैं जो वास्तव में आप चाहते हैं (यह एक्सेल एक्सप्लोरर फ़ाइल नामों को सॉर्ट करने के लिए उपयोग करता है)। एकमात्र संभावित नकारात्मक पक्ष यह है कि इस तरह का मामला असंवेदनशील है।

5

यह वह जगह है मैं यह कैसे हमारे आवेदन के लिए हल, आदेश में एक खिड़कियों निर्देशिका में तरह होगा:

public class NaturalSortComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     return StrCmpLogicalW(x, y); 
    } 

    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] 
    public static extern int StrCmpLogicalW(string x, string y); 
} 

उपयोग:

NaturalSortComparer comparer = new NaturalSortComparer(); 
    return comparer.Compare(string1, string2); 

लेकिन यह शायद आप वास्तव में क्या नहीं करना चाहता है:

// ए 1, ए 2, ए 10, बी 1, बी 3, 5, 7, 50, 72

इस दे देंगे

// 5, 7, 50, 72, A1, A2, ए 10, बी 1, बी 3

0
नहीं

, प्रदर्शन के बारे में यकीन है, और यकीन है कि यह अनुकूलित किया जा सकता है लेकिन यह काम करते हैं:

string[] sort(string[] data) 
{ 
    return data 
     .OrderBy(s => Regex.Match(s, @"^\D").Length == 0) 
     .ThenBy(s => Regex.Match(s, @"\D*").Value) 
     .ThenBy(s => Int32.Parse(Regex.Match(s, @"\d+").Value)).ToArray(); 
} 

var result = sort(new string[] { "B1", "5", "50", "A10", "7", "72", "B3", "A1", "A2" }); 
3

क्या आप देख रहे हैं एक प्राकृतिक क्रमबद्ध है।

जेफ एटवुड ने एक बार अपने ब्लॉग पर एक महान पोस्ट किया, जिसमें अवधारणा को समझाया गया और एल्गोरिदम के साथ अन्य स्रोतों को जोड़ने के लिए आप एक उदाहरण के रूप में ले सकते हैं।

Sorting for Humans : Natural Sort Order

1

यहाँ है कि आपके लिए आवश्यक आदेश में सॉर्ट होगा एक कस्टम comparer है। ध्यान दें कि इस कोड में कोई त्रुटि/सैनिटी चेक नहीं हैं: यह मानता है कि सभी स्ट्रिंग सही प्रारूप में होंगी।

public class MyComparer : IComparer<string> 
{ 
    public int Compare(string x, string y) 
    { 
     Match xMatch = Regex.Match(x, @"^(\D*)(\d+)$"); 
     Match yMatch = Regex.Match(y, @"^(\D*)(\d+)$"); 

     string xChars = xMatch.Groups[1].Value; 
     string yChars = yMatch.Groups[1].Value; 

     if ((xChars.Length == 0) && (yChars.Length > 0)) 
     { 
      return 1; 
     } 
     else if ((xChars.Length > 0) && (yChars.Length == 0)) 
     { 
      return -1; 
     } 
     else 
     { 
      int charsResult = xChars.CompareTo(yChars); 

      return (charsResult != 0) 
       ? charsResult 
       : int.Parse(xMatch.Groups[2].Value) 
        .CompareTo(int.Parse(yMatch.Groups[2].Value)); 
     } 
    } 
} 

तुम इतनी की तरह उपयोग कर सकते हैं:

List<string> testList = 
    new List<string>() { "B1","5","50","A10","7","72","B3","A1","A2" }; 

testList.Sort(new MyComparer()); // A1, A2, A10, B1, B3, 5, 7, 50, 72 
संबंधित मुद्दे