2011-09-17 11 views
10

संभव डुप्लिकेट:
Creating multiple numbers with certain number of bits setबिटवाइस पारी सी में हर संभव क्रमपरिवर्तन उत्पन्न करने के लिए

मैं कुछ कोड है जिसके द्वारा एक सरणी में संख्या के प्रत्येक संभव संयोजन रखा जाएगा लिखने के लिए प्रयास कर रहा हूँ बिट्स को स्थानांतरित करना।

उदाहरण के लिए, मैं 3 बिट्स के सभी संभव संयोजनों को खोजने के लिए (जहां अधिकतम अंक के हो सकता है कर रहा है 6) सरणी शामिल करना चाहिए चाहता था:

000111 
001011 
001101 
001110 
010011 
010101 
010110 
011001 
011010 
011100 
100011

और इसी तरह ...

मैंने जो व्याख्या की है, जब अंतिम स्थिति बिट 1 है, तो हम संख्या 1 (x >> 1) को स्थानांतरित करते हैं और शुरुआत में 1 जोड़ते हैं। हालांकि, मुझे यकीन नहीं है कि बाकी को कैसे कोड करें। मैं इसे लिखने के लिए सी का उपयोग कर रहा हूँ।

इसके अलावा - जहां तक ​​मैं यह कह सकता हूं कि यह एक कोलेक्स अनुक्रम है, हालांकि, अगर मैं एक और अनुक्रम देता हूं तो मुझे सभी कान मिलेंगे जो मुझे एक ही अंत परिणाम देगा (के-बिट्स के सभी संभावित संयोजनों के साथ सरणी एन की बाधा)।

+4

डुबकी [बिट्स सेट की कुछ संख्या के साथ कई संख्याएं बनाना] [http://stackoverflow.com/questions/506807/creating-multiple-numbers-with-certain-number-of-bits-set), [जेनरेट करें के बिट्स सेट के साथ लम्बाई के सभी बाइनरी तार] (http://stackoverflow.com/questions/1851134/generate-all-binary-strings-of-length-n-with-k-bits-set)। – outis

उत्तर

6

आप अनुक्रमों को पुन: उत्पन्न करके इसे हल कर सकते हैं।

हमें एक पुनरावर्ती समारोह f(int index, int bits, int number) कि बिट और bits की संख्या की वर्तमान index में ले जाएगा रखने के लिए बायां को परिभाषित करते हैं, और number अब तक उत्पन्न। फिर, आपके पास वर्तमान बिट को 1 या 0 तक सेट करने का विकल्प है, और वहां से रिकर्सिंग का विकल्प है।

कुल मिलाकर, समय जटिलता ओ (दृश्यों की संख्या), या हे (एन बी चुनें), जहां एन अंकों की संख्या है होना चाहिए और बी के लिए 1.

समारोह सेट बिट्स की संख्या है

void f(int index, int bits, int number) { 
    if (index == 0) { 
     if (bits == 0) { // all required bits have been used 
      emit_answer(number); // chuck number into an array, print it, whatever. 
     } 
     return; 
    } 

    if (index-1 >= bits) { // If we can afford to put a 0 here 
     f(index-1, bits, number); 
    } 

    if (bits > 0) { // If we have any 1s left to place 
     f(index-1, bits-1, number | (1 << (index-1))); 
    } 
} 

// to call: 
f(6, 3, 0); 

N,B = 6,3 के लिए उत्पादन तुम्हारा मैच, और क्रमबद्ध क्रम में है: कुछ इस तरह चला जाता है। काम करने के उदाहरण से लिंक: http://codepad.org/qgd689ZM

+0

धन्यवाद @evgeny। इसके साथ खेला और कुछ चीजें सीखा। बस डुप्लिकेट के बारे में - रुचि रखने वालों के लिए, डुप्लिक लिंक का पालन करें और स्टैनफोर्ड संसाधन पढ़ें। मुझे बहुत मदद की। – hungrii

2

शायद अधिक कुशल तरीका है, लेकिन आप केवल संख्याओं के माध्यम से लूप कर सकते हैं और उन संख्याओं को अस्वीकार कर सकते हैं जिनके पास 3 की थोड़ी गिनती नहीं है? बिट गिनती के लिए this answer देखें।

+0

फिर आपको 2^एन संयोजनों से गुज़रना होगा जो बहुत धीमी हो सकती हैं। फिर फिर, उसे केवल 6 बिट्स के लिए इसकी आवश्यकता है, इसलिए यह ठीक होना चाहिए। – quasiverse

+0

यह बहुत धीमी है, ओ (2^एन) जैसे कि quasiverse ने बताया। मेरा समाधान किसी भी अपशिष्ट के बिना सभी वैध अनुक्रम उत्पन्न करना चाहिए। – evgeny

+1

ठीक है, यकीन है। यह ओ (2^6) है। हालांकि, मैं तर्क दूंगा कि यदि गति वास्तव में एक मुद्दा है तो वह समय से पहले संख्याओं की गणना कर सकता है और उन्हें बचा सकता है।तो यह ओ (1) होगा :- इस समाधान की पठनीयता को दूसरों के कुछ बनाम उल्लेख नहीं करना चाहिए। * शग * – dantswain

3

किसी भी फैंसी रिकर्सन की आवश्यकता नहीं है। कुछ सरल गणित पर्याप्त होंगे (एक मूल्य से एक विभाजन जो हमेशा दो की शक्ति होगी) आवश्यक है।

 
    Function nextBits(ByVal prevVal As Integer) 
     Dim lsOne As Integer = ((prevVal - 1) And Not prevVal) + 1 
     Dim nextZero As Integer = (prevVal + lsOne) And Not prevVal 
     Dim lowBits As Integer = ((nextZero \ lsOne \ 2) - 1) 
     Return prevVal + lsOne + lowBits 
    End Function 

अच्छा और आसान।

+2

उह ... मेरा दिमाग कोड से चोट पहुंचा रहा है। इसके अलावा, \ ऑपरेटर क्या है? और शायद यह बताता है कि यह काम क्यों मदद करेगा। – quasiverse

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