2010-08-24 16 views
8

मैं az और के माध्यम से पत्र बयान मैं जैसे दृश्यों की एक सूची का निर्माण कर रहा हूँ के लिए नेस्ट के चार [26] है:एनटी क्रमपरिवर्तन चरण की गणना?

aaa, aaz... aba, abb, abz, ... zzy, zzz. 

वर्तमान में, सॉफ्टवेयर से सभी संभावित मानों की सूची बनाने के लिए लिखा है aaa-zzz और फिर एक अनुक्रमणिका बनाए रखता है, और उनमें से प्रत्येक के माध्यम से एक ऑपरेशन कर रहा है।

सूची स्पष्ट रूप से बड़ी है, यह हास्यास्पद रूप से बड़ी नहीं है, लेकिन यह उस बिंदु तक पहुंच गया है जहां स्मृति पदचिह्न बहुत बड़ा है (अन्य क्षेत्रों को भी देखा जा रहा है, लेकिन यह मुझे मिला है)।

मैं एक सूत्र तैयार करने की कोशिश कर रहा हूं जहां मैं इंडेक्स रख सकता हूं, लेकिन अनुक्रमों की सूची से दूर रहें और मौजूदा अनुक्रम के आधार पर वर्तमान अनुक्रम की गणना करें (जैसे अनुक्रमों के बीच संचालन के बीच का समय लंबा है)।

उदाहरण के लिए:

char[] characters = {a, b, c... z}; 
int currentIndex = 29; // abd 

public string CurrentSequence(int currentIndex) 
{ 
    int ndx1 = getIndex1(currentIndex); // = 0 
    int ndx2 = getIndex2(currentIndex); // = 1 
    int ndx3 = getIndex3(currentIndex); // = 3 

    return string.Format(
     "{0}{1}{2}", 
     characters[ndx1], 
     characters[ndx2], 
     characters[ndx3]); // abd 
} 

मैं एक सबसेट (एबीसी) का उपयोग कर एक छोटा सा उदाहरण बाहर काम कर रहा है और उस का उपयोग कर सापेक्ष डिविज़न में सूचकांक करने की कोशिश कर की कोशिश की है, लेकिन मैं मुसीबत आज सोच रही है और मैं कर रहा हूँ स्टम्प्ड।

मैं किसी भी तरह की मदद के लिए उत्तर नहीं मांग रहा हूं। शायद सही दिशा में एक किक?

+0

char [25] एक ..z पकड़ने के लिए पर्याप्त नहीं है। आप बफर ओवरफ्लो या कुछ के लिए जांचना चाह सकते हैं। – recursive

+0

आप वास्तव में क्या हासिल करने की कोशिश कर रहे हैं? – second

+0

@recursive: धन्यवाद, टाइपो। –

उत्तर

14

संकेत: इस बारे में सोचें कि आप आधार 10 के बजाय बेस 26 में और संख्याओं के बजाय अक्षरों के साथ कैसे प्रिंट करेंगे। एक मनमानी आधार में एक संख्या प्रदर्शित करने के लिए सामान्य एल्गोरिदम क्या है?

बिगाड़ने: (देखने के लिए सही स्क्रॉल)

                     int ndx1 = currentIndex/26/26 % 26; 
                         int ndx2 = currentIndex/26 % 26; 
                         int ndx3 = currentIndex % 26; 
+7

स्क्रॉलिंग –

6

कुछ इस तरह काम करना चाहिए, 26 वर्ण यह सोचते हैं:

public string CurrentSequence(int currentIndex) { 
    return characters[currentIndex/(26 * 26)] 
     + characters[(currentIndex/26) % 26] 
     + characters[currentIndex % 26]; 
} 
5

वाह, two questions in one day कार्तीय उत्पादों के माध्यम से हल किया जा सकता है कि । गजब का।

आप सूचकांक मूल्यों के सभी संयोजन उत्पन्न करने के लिए Eric Lippert's LINQ snippet का उपयोग कर सकते हैं। इस दृष्टिकोण के परिणामों के स्ट्रीमिंग सेट में परिणाम होता है, इसलिए उन्हें स्मृति में संग्रहण की आवश्यकता नहीं होती है। यह दृष्टिकोण कोड को बनाए रखने या कोड के साथ गणना करने से कोड उत्पन्न करने के तर्क को अच्छी तरह से अलग करता है।

सभी संयोजनों के लिए एरिक के कोड:

static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
    return sequences.Aggregate( 
    emptyProduct, 
    (accumulator, sequence) => 
     from accseq in accumulator 
     from item in sequence 
     select accseq.Concat(new[] {item}));     
} 

अब आप लिख सकते हैं:

public static IEnumerable<string> AllCodes() 
{ 
    char[] characters = {a, b, c... z}; 
    IEnumerable<char[]> codeSets = new[] { characters, characters, characters }; 

    foreach(var codeValues in codeSets.CartesianProduct()) 
    { 
    yield return 
     string.Format("{0}{1}{2}", codeValues[0], codeValues[1], codeValues[2]); 
    } 
} 

कोड ऊपर aaa से zzz करने के लिए सभी कोड तार का एक स्ट्रीमिंग का अनुक्रम उत्पन्न करता है।अब आप इस कहीं और उपयोग कर सकते हैं, जहां आप अपनी प्रसंस्करण प्रदर्शन:

foreach(var code in AllCodes()) 
{ 
    // use the code value somehow... 
} 
+1

का शानदार उपयोग यह समाधान आपको एक सूचकांक को कुशलता से देखने की अनुमति नहीं देता है, जो उपयोग केस है। – recursive

+2

@recursive। शायद। ओपेसी ओपी ने संकेत दिया था कि सॉफ़्टवेयर किसी भी तरह से सभी इंडेक्स के माध्यम से अपना रास्ता काम करता है। तो यह अभी भी सहायक हो सकता है। – LBushkin

+0

रिकर्सिव सही है लेकिन यह वास्तव में काफी उपयोगी है। मैंने एरिक के बारे में उस पोस्ट को देखा था, लेकिन इसे भूल गया था। +1 –

4

वहाँ अपनी समस्या को हल करने के लिए कई तरीके हैं, लेकिन एक विकल्प एक सूची में भंडारण के बजाय मक्खी पर अनुक्रम उत्पन्न करने के लिए है:

IEnumerable<String> Sequence() { 
    for (var c1 = 'a'; c1 <= 'z'; ++c1) 
    for (var c2 = 'a'; c2 <= 'z'; ++c2) 
     for (var c3 = 'a'; c3 <= 'z'; ++c3) 
     yield return String.Format("{0}{1}{2}", c1, c2, c3); 
} 

तो आप सभी स्ट्रिंग्स की गणना कर सकते हैं:

foreach (var s in Sequence()) 
    Console.WriteLine(s); 

इस कोड को बिल्कुल सूचकांकों का उपयोग नहीं करता है, लेकिन यह आप सरल का उपयोग कर तार के अनुक्रम के चारों ओर एक पाश बनाने की अनुमति देता कोड और तारों को संग्रहित किए बिना।

संबंधित मुद्दे