कैसे जांचें कि पायथन में दो सूचियां समान रूप से समान हैं या नहीं


145

उदाहरण के लिए, मेरे पास सूची है:

a[0] = [1, 1, 1, 0, 0]
a[1] = [1, 1, 0, 0, 1]
a[2] = [0, 1, 1, 1, 0]
# and so on

वे अलग-अलग प्रतीत होते हैं, लेकिन अगर यह माना जाता है कि प्रारंभ और अंत जुड़े हुए हैं, तो वे परिपत्र समान हैं।

समस्या यह है कि प्रत्येक सूची, जिसकी लंबाई मेरी 55 है और इसमें केवल तीन और 52 शून्य हैं। परिपत्र स्थिति के बिना, 26,235 (55 चुनिंदा 3) सूचियां हैं। हालांकि, यदि स्थिति 'परिपत्र' मौजूद है, तो बड़ी संख्या में परिपत्र समान सूचियां हैं

वर्तमान में मैं निम्नलिखित द्वारा परिपत्र पहचान की जाँच करता हूं:

def is_dup(a, b):
    for i in range(len(a)):
        if a == list(numpy.roll(b, i)): # shift b circularly by i
            return True
    return False

इस फ़ंक्शन को सबसे खराब स्थिति में 55 चक्रीय पारी संचालन की आवश्यकता होती है। और एक दूसरे के साथ तुलना करने के लिए 26,235 सूचियां हैं। संक्षेप में, मुझे 55 * 26,235 * (26,235 - 1) / 2 = 18,926,847,225 संगणनाएँ चाहिए। यह लगभग 20 गीगा है!

क्या कम गणनाओं के साथ इसे करने का कोई अच्छा तरीका है? या कोई भी डेटा प्रकार जो परिपत्र का समर्थन करता है ?


बस एक कूबड़: मुझे लगता है कि प्रत्यय के पेड़ यहां मदद कर सकते हैं। en.wikipedia.org/wiki/Suffix_tree । एक बनाने के लिए, en.wikipedia.org/wiki/Ukkonen%27s_algorithm
Rerito

1
@ मेहरदाद लेकिन किसी भी उत्तर की तुलना में बदतर चल रहा समय जो एक कैनोनिकल रूप में परिवर्तित होता है, एक पूर्णांक और दूर तक परिवर्तित होने की तुलना में सबसे खराब समय चल रहा है, डेविड ईसेनस्टैट की तुलना में कहीं अधिक खराब चल रहा समय।
विड्राक

2
सामान्य समस्या को हल करने की कोशिश करने वाले सभी उत्तर, लेकिन केवल 3 लोगों के साथ इस विशेष मामले में आप प्रत्येक सूची का प्रतिनिधित्व कर सकते हैं जिसमें 3 संख्याएं उनके बीच शून्य संख्या होती हैं। प्रश्न से सूची को [0,0,2], [0,2,0], [2,0,0] के रूप में दर्शाया जा सकता है। आप बस एक रन में सूची को कम कर सकते हैं और फिर कम सूची की जांच कर सकते हैं। यदि वे "समान रूप से समान हैं" तो मूल भी हैं।
abc667

1
मुझे लगता है कि स्टैक ओवरफ्लो को तब मतदान की आवश्यकता नहीं है। हमें केवल सभी समाधानों में कोड चलाना है, और उन्हें उस क्रम में प्रस्तुत करना है जिसमें वे समाप्त करते हैं।
दाऊद इब्न करीम

2
चूंकि अब तक इसका उल्लेख नहीं किया गया है, @ abc667, Veedrac, और Eisenstat द्वारा संदर्भित "विहित रूप" को रन लंबाई एनकोडिंग en.wikipedia.org/wiki/Run-length_encoding
डेविड लोवेल

जवाबों:


133

सबसे पहले, यह O(n)सूची की लंबाई के संदर्भ में किया जा सकता है आप देख सकते हैं कि यदि आप अपनी सूची को 2 बार ( [1, 2, 3]) दोहराएंगे, [1, 2, 3, 1, 2, 3]तो आपकी नई सूची निश्चित रूप से सभी संभावित चक्रीय सूचियों को पकड़ेगी।

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

list1 = [1, 1, 1, 0, 0]
list2 = [1, 1, 0, 0, 1]
print ' '.join(map(str, list2)) in ' '.join(map(str, list1 * 2))

मेरे ऑनलाइनर के बारे में कुछ स्पष्टीकरण: list * 2एक सूची को खुद से जोड़ देगा, map(str, [1, 2])सभी संख्याओं को स्ट्रिंग में ' '.join()बदल देगा और सरणी ['1', '2', '111']को एक स्ट्रिंग में बदल देगा '1 2 111'

जैसा कि कुछ लोगों ने टिप्पणियों में बताया है, ऑनलाइनर संभावित रूप से कुछ झूठी सकारात्मक बातें दे सकता है, इसलिए सभी संभावित किनारे मामलों को कवर करने के लिए:

def isCircular(arr1, arr2):
    if len(arr1) != len(arr2):
        return False

    str1 = ' '.join(map(str, arr1))
    str2 = ' '.join(map(str, arr2))
    if len(str1) != len(str2):
        return False

    return str1 in str2 + ' ' + str2

पीएस 1 जब समय की जटिलता के बारे में बोल रहा है, तो यह ध्यान देने योग्य है कि O(n)अगर समय पर प्रतिस्थापन पाया जा सकता है तो इसे प्राप्त किया जाएगा O(n)। यह हमेशा ऐसा नहीं होता है और आपकी भाषा में कार्यान्वयन पर निर्भर करता है ( हालांकि संभवतः यह उदाहरण के लिए रैखिक समय KMP में किया जा सकता है )।

पीएस 2 उन लोगों के लिए है जो डर स्ट्रिंग्स ऑपरेशन करते हैं और इस तथ्य के कारण सोचते हैं कि उत्तर अच्छा नहीं है। जटिलता और गति क्या महत्वपूर्ण है। यह एल्गोरिथ्म संभावित रूप से O(n)समय और O(n)स्थान पर चलता है जो इसे O(n^2)डोमेन की किसी भी चीज़ से बहुत बेहतर बनाता है । इसे अपने आप से देखने के लिए, आप एक छोटा बेंचमार्क चला सकते हैं (एक यादृच्छिक सूची पहला तत्व बनाता है और अंत में इसे इस तरह से चक्रीय सूची बनाता है। आप अपनी खुद की जोड़तोड़ करने के लिए स्वतंत्र हैं।

from random import random
bigList = [int(1000 * random()) for i in xrange(10**6)]
bigList2 = bigList[:]
bigList2.append(bigList2.pop(0))

# then test how much time will it take to come up with an answer
from datetime import datetime
startTime = datetime.now()
print isCircular(bigList, bigList2)
print datetime.now() - startTime    # please fill free to use timeit, but it will give similar results

मेरी मशीन पर 0.3 सेकंड। वास्तव में लंबे समय तक नहीं। अब इसके O(n^2)समाधान के साथ तुलना करने का प्रयास करें । जब यह इसकी तुलना कर रहा है, तो आप अमेरिका से ऑस्ट्रेलिया की यात्रा कर सकते हैं (संभवतः एक क्रूज जहाज द्वारा)


3
बस पैडिंग स्पेस (प्रत्येक स्ट्रिंग के पहले 1 और 1 के बाद) जोड़ देगा। Regexes के साथ चीजों को ओवरक्लंप करने की कोई आवश्यकता नहीं है। (निश्चित रूप से मैं मान रहा हूँ कि हम समान लंबाई की सूचियों की तुलना करते हैं)
Rerito

2
@ रेरिटो जब तक या तो सूची में स्ट्रिंग्स शामिल नहीं होते हैं, जिनमें स्वयं अग्रणी या अनुगामी स्थान हो सकते हैं। फिर भी टकराव पैदा कर सकता है।
एडम स्मिथ

12
मुझे यह उत्तर पसंद नहीं है। स्ट्रिंग ऑपरेशन बकवास ने मुझे इसे नापसंद किया और डेविड आइजनस्टैट के जवाब ने मुझे इसे नीचा दिखाने के लिए तैयार कर दिया। इस तुलना कर सकते हैं एक तार के साथ हे (एन) समय में किया जा लेकिन यह भी एक पूर्णांक के साथ हे (एन) समय में किया जा सकता [के रूप में की जरूरत 10k स्वयं नष्ट कर दिया], जो तेजी से होता है। बहरहाल, डेविड आइजनस्टैट का जवाब दिखाता है कि किसी भी तरह की तुलना करना व्यर्थ है क्योंकि जवाब की आवश्यकता नहीं है।
विड्रैक

7
@Veedrac तुम मुझसे मजाक कर रहे हो? क्या आपने कम्प्यूटेशनल जटिलता के बारे में सुना है? डेविड के उत्तर में O (n ^ 2) का समय लगता है और O (n ^ 2) केवल अपने सभी पुनरावृत्तियों को उत्पन्न करने के लिए जगह देता है, जो कि छोटे इनपुट के लिए भी 10 ^ 4 की लंबाई 22 सेकंड की तरह लगती है और जो जानता है कि कितना राम है। यह उल्लेख करने के लिए नहीं कि हमने अभी कुछ भी खोजना शुरू नहीं किया है (हमने अभी सभी चक्रीय घुमाव उत्पन्न किए हैं)। और मेरा स्ट्रिंग बकवास आपको 0.5 सेकंड से भी कम समय में 10 ^ 6 जैसे इनपुट के लिए एक पूर्ण परिणाम देता है। इसे स्टोर करने के लिए O (n) स्पेस की भी जरूरत होती है। तो कृपया निष्कर्ष में कूदने से पहले उत्तर को समझने में थोड़ा समय दें।
साल्वाडोर डाली

1
@ साल्वाडोरदाली आप बहुत (नरम) समय केंद्रित लगती हैं ;-)
e2-e4

38

आपकी अनुरोधित भाषा में इसका उत्तर देने के लिए अजगर में पर्याप्त ज्ञान नहीं है, लेकिन आपके प्रश्न के मापदंडों को देखते हुए, C / C ++ में, मैं शून्य और बिट्स को बिट्स में परिवर्तित करूँगा और उन्हें एक uint64_t के कम से कम महत्वपूर्ण बिट्स पर धकेलूंगा। यह आपको एक ही झपट्टा - 1 घड़ी में सभी 55 बिट्स की तुलना करने की अनुमति देगा।

बुरी तरह से तेज, और पूरी चीज चिप-कैश (209,880 बाइट्स) में फिट होगी। सभी 55 सूची सदस्यों को एक साथ स्थानांतरित करने के लिए हार्डवेयर समर्थन केवल एक सीपीयू रजिस्टर में उपलब्ध है। एक ही साथ सभी 55 सदस्यों की तुलना करने के लिए जाता है। यह सॉफ़्टवेयर समाधान के लिए समस्या की 1-फॉर -1 मैपिंग की अनुमति देता है। (और यदि आवश्यक हो तो SIMD / SSE 256 बिट रजिस्टरों का उपयोग करते हुए, 256 सदस्यों तक) परिणामस्वरूप कोड पाठक के लिए तुरंत स्पष्ट हो जाता है।

आप इसे पायथन में लागू करने में सक्षम हो सकते हैं, मुझे अभी यह अच्छी तरह से पता नहीं है कि यह संभव है या प्रदर्शन क्या हो सकता है।

उस पर सोने के बाद कुछ चीजें स्पष्ट हो गईं, और सभी बेहतर के लिए।

1.) बिट्स का उपयोग करके परिपत्र रूप से जुड़ी सूची को स्पिन करना इतना आसान है कि डाली की बहुत चालाक चाल आवश्यक नहीं है। 64-बिट रजिस्टर के अंदर मानक बिट शिफ्टिंग रोटेशन को बहुत सरलता से पूरा करेगा, और बिट ऑप्स के बजाय अंकगणित का उपयोग करके इस सभी अधिक पायथन को अनुकूल बनाने के प्रयास में।

2.) बिट शिफ्टिंग को 2 से भाग करके आसानी से पूरा किया जा सकता है।

3.) 0 या 1 के लिए सूची के अंत की जाँच करना modulo 2 द्वारा आसानी से किया जा सकता है।

4.) पूंछ से सूची के प्रमुख के लिए "0" चलना 2. द्वारा विभाजित किया जा सकता है क्योंकि यह अगर शून्य वास्तव में ले जाया गया था तो यह 55 वें बिट को झूठा बना देगा, जो पहले से ही बिल्कुल कुछ भी नहीं है।

5.) पूंछ से सूची के प्रमुख के लिए "1" चलना 2 से विभाजित करके और 18,014,398,509,481,984 जोड़कर किया जा सकता है - जो कि 55 वें बिट सच और बाकी सभी झूठे को चिह्नित करके बनाया गया मूल्य है।

6.) यदि किसी दिए गए रोटेशन के बाद लंगर और रचित uint64_t की तुलना TRUE है, तो TRUE को तोड़ें और वापस लौटाएँ।

मैं बार-बार रूपांतरण करने से बचने के लिए सूचियों के पूरे सरणी को सीधे सामने uint64_ts की एक सरणी में बदल दूंगा।

कोड को अनुकूलित करने की कोशिश में कुछ घंटे बिताने के बाद, विधानसभा भाषा का अध्ययन करते हुए मैं रनटाइम से 20% दाढ़ी बनाने में सक्षम था। मुझे यह जोड़ना चाहिए कि ओ / एस और एमएसवीसी कंपाइलर को कल के साथ-साथ मिड-डे अपडेट मिला। जो भी कारण / कारण के लिए, सी कंपाइलर उत्पादित कोड की गुणवत्ता में सुधार के बाद नाटकीय रूप से सुधार हुआ (11/15/2014)। रन-टाइम अब ~ 70 घड़ियां, 17 नैनोसेकंड एक लंगर की अंगूठी की रचना और तुलना करने के लिए एक परीक्षण रिंग के सभी 55 मोड़ के साथ और अन्य सभी के खिलाफ सभी रिंगों के एनएक्सएन 12.5 सेकंड में किया जाता है ।

यह कोड बहुत तंग है, लेकिन 4 रजिस्टर 99% समय के आसपास कुछ भी नहीं कर रहे हैं। असेंबली भाषा C कोड को लाइन के लिए लगभग लाइन से मेल खाती है। पढ़ने और समझने में बहुत आसान है। एक महान विधानसभा परियोजना अगर कोई खुद को सिखा रहा था कि।

हार्डवेयर हेज़वेल i7, MSVC 64-बिट, पूर्ण अनुकूलन है।

#include "stdafx.h"
#include "stdafx.h"
#include <string>
#include <memory>
#include <stdio.h>
#include <time.h>

const uint8_t  LIST_LENGTH = 55;    // uint_8 supports full witdth of SIMD and AVX2
// max left shifts is 32, so must use right shifts to create head_bit
const uint64_t head_bit = (0x8000000000000000 >> (64 - LIST_LENGTH)); 
const uint64_t CPU_FREQ = 3840000000;   // turbo-mode clock freq of my i7 chip

const uint64_t LOOP_KNT = 688275225; // 26235^2 // 1000000000;

// ----------------------------------------------------------------------------
__inline uint8_t is_circular_identical(const uint64_t anchor_ring, uint64_t test_ring)
{
    // By trial and error, try to synch 2 circular lists by holding one constant
    //   and turning the other 0 to LIST_LENGTH positions. Return compare count.

    // Return the number of tries which aligned the circularly identical rings, 
    //  where any non-zero value is treated as a bool TRUE. Return a zero/FALSE,
    //  if all tries failed to find a sequence match. 
    // If anchor_ring and test_ring are equal to start with, return one.

    for (uint8_t i = LIST_LENGTH; i;  i--)
    {
        // This function could be made bool, returning TRUE or FALSE, but
        // as a debugging tool, knowing the try_knt that got a match is nice.
        if (anchor_ring == test_ring) {  // test all 55 list members simultaneously
            return (LIST_LENGTH +1) - i;
        }

        if (test_ring % 2) {    //  ring's tail is 1 ?
            test_ring /= 2;     //  right-shift 1 bit
            // if the ring tail was 1, set head to 1 to simulate wrapping
            test_ring += head_bit;      
        }   else    {           // ring's tail must be 0
            test_ring /= 2;     // right-shift 1 bit
            // if the ring tail was 0, doing nothing leaves head a 0
        }
    }
    // if we got here, they can't be circularly identical
    return 0;
}
// ----------------------------------------------------------------------------
    int main(void)  {
        time_t start = clock();
        uint64_t anchor, test_ring, i,  milliseconds;
        uint8_t try_knt;

        anchor = 31525197391593472; // bits 55,54,53 set true, all others false
        // Anchor right-shifted LIST_LENGTH/2 represents the average search turns
        test_ring = anchor >> (1 + (LIST_LENGTH / 2)); //  117440512; 

        printf("\n\nRunning benchmarks for %llu loops.", LOOP_KNT);
        start = clock();
        for (i = LOOP_KNT; i; i--)  {
            try_knt = is_circular_identical(anchor, test_ring);
            // The shifting of test_ring below is a test fixture to prevent the 
            //  optimizer from optimizing the loop away and returning instantly
            if (i % 2) {
                test_ring /= 2;
            }   else  {
                test_ring *= 2;
            }
        }
        milliseconds = (uint64_t)(clock() - start);
        printf("\nET for is_circular_identical was %f milliseconds."
                "\n\tLast try_knt was %u for test_ring list %llu", 
                        (double)milliseconds, try_knt, test_ring);

        printf("\nConsuming %7.1f clocks per list.\n",
                (double)((milliseconds * (CPU_FREQ / 1000)) / (uint64_t)LOOP_KNT));

        getchar();
        return 0;
}

यहाँ छवि विवरण दर्ज करें


23
लोग "सल्वाडोर डाली के समाधान" के बारे में बात करते रहते हैं और मैं बस उलझन में यहाँ बैठा था, सोच रहा था कि क्या इसी नाम का चित्रकार भी एक गणितज्ञ था जो कुछ महत्वपूर्ण तरीकों से शास्त्रीय एल्गोरिदम में योगदान देता था। तब मुझे एहसास हुआ कि उस व्यक्ति का उपयोगकर्ता नाम है जिसने सबसे लोकप्रिय उत्तर पोस्ट किया है। मैं स्मार्ट आदमी नहीं हूं।
वुडरो बारलो

10k प्रतिनिधि के साथ किसी के लिए, और कार्यान्वयन यहाँ Numpy और वैश्वीकरण का उपयोग कर उपलब्ध हैउन <10k के लिए मिरर । मैं अपने उत्तर हटा दिया गया क्योंकि दाऊद Eisenstat का जवाब बाहर है कि आप तुलना करने की जरूरत नहीं है अंक बिल्कुल के रूप में आप सिर्फ अद्वितीय सूचियों सीधे उत्पन्न कर सकते हैं और मैं लोगों को अपने से कहीं बेहतर जवाब का उपयोग करने के लिए प्रोत्साहित करते हैं करना चाहते हैं।
विड्राक

@RocketRoy आपको क्यों लगता है कि पायथन में बिट संचालन नहीं होगा? हेक, मैं लिंक किए गए कोड में बिट संचालन का उपयोग करता हूं । मुझे अभी भी लगता है कि यह उत्तर अधिकतर अप्रमाणित है (डेविड आइजनस्टैट का जवाब पूरी बात के लिए 1ms है), लेकिन मुझे यह कथन अजीब लगा। एफडब्ल्यूआईडब्ल्यू, 262M- "सूचियों" की खोज करने के लिए Numpy में एक समान एल्गोरिथ्म "मेरे कंप्यूटर पर लगभग 15s लेता है (कोई मैच नहीं पाया जाता है), केवल सूची का घूर्णन बाहरी लूप में होता है, आंतरिक नहीं।"
विड्रैक

@Quincunx, C ++ के लिए सिंटैक्स रंग सही करने के लिए आपके संपादन के लिए धन्यवाद। अत्यधिक सराहनीय!

@RocketRoy कोई समस्या नहीं है। जब आप PPCG पर बहुत सारे सवालों के जवाब देते हैं , तो आप सीखते हैं कि सिंटेक्स कलरिंग कैसे की जाती है।
जस्टिन

33

लाइनों के बीच पढ़ना, ऐसा लगता है जैसे आप प्रत्येक 3 और 52 शून्य के साथ तार के प्रत्येक परिपत्र तुल्यता वर्ग के एक प्रतिनिधि की गणना करने की कोशिश कर रहे हैं। चलो एक घने प्रतिनिधित्व से विरल एक (तीन संख्याओं का सेट range(55)) में स्विच करें । इस प्रतिनिधित्व में, के परिपत्र पारी sसे kसमझ द्वारा दिया जाता है set((i + k) % 55 for i in s)। एक कक्षा में कोषगत न्यूनतम प्रतिनिधि हमेशा स्थिति 0. प्रपत्र का एक सेट को देखते हुए शामिल {0, i, j}साथ 0 < i < j, कक्षा में कम से कम के लिए अन्य उम्मीदवार हैं {0, j - i, 55 - i}और {0, 55 - j, 55 + i - j}। इसलिए, हमें (i, j) <= min((j - i, 55 - i), (55 - j, 55 + i - j))न्यूनतम होने के लिए मूल की आवश्यकता है । यहाँ कुछ गणना कोड है।

def makereps():
    reps = []
    for i in range(1, 55 - 1):
        for j in range(i + 1, 55):
            if (i, j) <= min((j - i, 55 - i), (55 - j, 55 + i - j)):
                reps.append('1' + '0' * (i - 1) + '1' + '0' * (j - i - 1) + '1' + '0' * (55 - j - 1))
    return reps

2
@SalvadorDali आपने उत्तर गलत समझा है (मैंने ऐसा तब तक किया जब तक उन्होंने इसे इंगित नहीं किया!)। यह सीधे "3 और 52 शून्य के साथ तार के प्रत्येक परिपत्र तुल्यता वर्ग का एक प्रतिनिधि उत्पन्न करता है"। उनका कोड सभी चक्रीय घुमाव उत्पन्न नहीं करता है। मूल कॉस्ट² टी (55² · 26235।) है। आपका कोड 55 code से 55 में सुधार करता है, इसलिए सिर्फ T (55 * 26235।) है। डेविड आइसेनस्टैट का जवाब 55² और 55 the के बीच है । 55 · 55 · 26235²। ¹ सभी मामलों में O (1) में वास्तविक लागत के रूप में यहां बड़ी-O शर्तों पर बात नहीं कर रहे हैं।
विड्रैक

1
@Veedrac लेकिन 99% पाठक जो भविष्य में इस सवाल पर आएंगे, उनके पास कोई बाधा नहीं होगी और मुझे विश्वास है कि मेरा जवाब उन्हें बेहतर लगेगा। बातचीत को आगे बढ़ाए बिना, मैं ओपी को यह बताने के लिए छोड़ दूंगा कि वह वास्तव में क्या चाहता है।
साल्वाडोर डाली

5
@SalvadorDali ओपी XY समस्या का शिकार हो गया लगता है । सौभाग्य से, सवाल ही स्पष्ट करता है कि शीर्षक क्या नहीं है, और डेविड लाइनों के बीच पढ़ने में सक्षम था। यदि यह वास्तव में मामला है, तो करने के लिए सही बात यह है कि शीर्षक को बदलने और शीर्षक का उत्तर देने और प्रश्न को अनदेखा करने के बजाय वास्तविक समस्या को हल करना है।
आरोन ड्यूफोर

1
@SalvadorDali, कवर के तहत आपका पायथन कोड C के स्ट्रैस () के बराबर कॉल कर रहा है, जो एक उप-स्ट्रिंग के लिए एक स्ट्रिंग खोजता है। बदले में वह strcmp () कॉल करता है, जो string2 में string2 के साथ प्रत्येक char की तुलना के लिए () लूप चलाता है। इसलिए, ओ (एन) जैसा दिखता है क्या ओ (एन * 55 * 55) विफलता को खोज रहा है। उच्च स्तरीय भाषाएं 2-धार वाली तलवार हैं। वे आपसे कार्यान्वयन विवरण छिपाते हैं, लेकिन फिर वे आपसे कार्यान्वयन विवरण भी छिपाते हैं। FWIW, सूची को संक्षिप्त करने के लिए आपकी अंतर्दृष्टि शानदार थी। तेजी से अभी भी uint8 के रूप में, और बिट्स के रूप में बहुत तेजी से - जो आसानी से हार्डवेयर में घुमाया जा सकता है।

2
@AleksandrDubinsky कंप्यूटर के लिए सरल, मानव के लिए अधिक जटिल। यह काफी तेज है।
डेविड आइजनस्टैट

12

पहले सरणी को दोहराएँ, फिर पहले के अंदर दूसरा सरणी खोजने के लिए Z एल्गोरिथ्म (O (n) समय) का उपयोग करें।

(नोट: आपको भौतिक रूप से पहले सरणी की प्रतिलिपि बनाने की आवश्यकता नहीं है। आप मिलान के दौरान बस चारों ओर लपेट सकते हैं।)

Z एल्गोरिदम के बारे में अच्छी बात यह है कि यह KMP, BM, आदि की तुलना में बहुत सरल है।
हालांकि, यदि आप महत्वाकांक्षी महसूस कर रहे हैं, तो आप रेखीय समय और निरंतर स्थान में स्ट्रिंग मिलान कर सकते हैं - strstrउदाहरण के लिए, यह ऐसा करता है। इसे लागू करना अधिक दर्दनाक होगा, हालांकि।


6

साल्वाडोर डाली के बहुत स्मार्ट समाधान के बाद, इसे संभालने का सबसे अच्छा तरीका यह सुनिश्चित करना है कि सभी तत्व एक ही लंबाई के हैं, साथ ही दोनों एलआईटीएस भी एक ही लंबाई के हैं।

def is_circular_equal(lst1, lst2):
    if len(lst1) != len(lst2):
        return False
    lst1, lst2 = map(str, lst1), map(str, lst2)
    len_longest_element = max(map(len, lst1))
    template = "{{:{}}}".format(len_longest_element)
    circ_lst = " ".join([template.format(el) for el in lst1]) * 2
    return " ".join([template.format(el) for el in lst2]) in circ_lst

सल्वाडोर डाली के उत्तर में अश्विनीचौधरी द्वारा सुझाए गए रेगेक्स समाधान की तुलना में यह तेज़ या धीमा होने पर कोई सुराग नहीं, जो पढ़ता है:

import re

def is_circular_equal(lst1, lst2):
    if len(lst2) != len(lst2):
        return False
    return bool(re.search(r"\b{}\b".format(' '.join(map(str, lst2))),
                          ' '.join(map(str, lst1)) * 2))

1
क्योंकि मैं मूल रूप से सिर्फ साल्वाडोर डाली के जवाब को टाल देता था और अश्विनी के परिवर्तनों को स्वरूपित करता था। इसमें से बहुत कम वास्तव में मेरा है।
एडम स्मिथ

1
इनपुट के लिए धन्यवाद। मुझे लगता है कि मैंने अपने संपादित समाधान में सभी संभावित मामलों को कवर किया है। अगर कुछ याद आ रहा है तो मुझे बताएं।
सल्वाडोर डाली

@ साल्वाडोरदाली आह, हां ... जांच कर रहे हैं कि तार एक ही लंबाई के हैं। मैं समर्थन करता हूं कि सबसे लंबे तत्व की तलाश करने वाली सूची के माध्यम से चलने की तुलना में आसान होगा, फिर str.format nपरिणामी स्ट्रिंग को प्रारूपित करने के लिए कई बार कॉल करना होगा। मैं समर्थन करता हूं .... :)
एडम स्मिथ

3

यह देखते हुए कि आपको इतनी तुलना करने की आवश्यकता है कि आपकी सूचियों के माध्यम से प्रारंभिक पास लेने के दौरान यह आपके लायक हो सकता है कि उन्हें किसी प्रकार के विहित रूप में परिवर्तित किया जा सकता है जिसकी तुलना आसानी से की जा सकती है?

क्या आप परिपत्र-विशिष्ट सूचियों का एक सेट प्राप्त करने की कोशिश कर रहे हैं? यदि ऐसा है तो आप उन्हें ट्यूपल्स में बदलने के बाद एक सेट में फेंक सकते हैं।

def normalise(lst):
    # Pick the 'maximum' out of all cyclic options
    return max([lst[i:]+lst[:i] for i in range(len(lst))])

a_normalised = map(normalise,a)
a_tuples = map(tuple,a_normalised)
a_unique = set(a_tuples)

डेविड वीसेनस्टैट को अपने वी.सिमिलर के जवाब को न बताने के लिए माफी।


3

आप इस तरह एक सूची को रोल कर सकते हैं:

list1, list2 = [0,1,1,1,0,0,1,0], [1,0,0,1,0,0,1,1]

str_list1="".join(map(str,list1))
str_list2="".join(map(str,list2))

def rotate(string_to_rotate, result=[]):
    result.append(string_to_rotate)
    for i in xrange(1,len(string_to_rotate)):
        result.append(result[-1][1:]+result[-1][0])
    return result

for x in rotate(str_list1):
    if cmp(x,str_list2)==0:
        print "lists are rotationally identical"
        break

3

सबसे पहले अपने लिस्ट एलिमेंट्स (कॉपी में अगर जरूरी हो तो) को उस रोटेटेड वर्जन में बदलें जो लेक्सिकली सबसे बड़ा हो।

फिर सूची की परिणामी सूची (मूल सूची स्थिति में एक सूचकांक को बनाए रखना) को क्रमबद्ध करें और क्रमबद्ध सूची को एकीकृत करें, मूल सूची में सभी डुप्लिकेट को आवश्यक के रूप में चिह्नित करें।


2

बी + बी में किसी भी लम्बे आकार के स्लाइस में माचिस की तलाश करने पर @ सल्वाडोरडाली के अवलोकन पर पिग्गीबैकिंग, यहां सिर्फ सूची संचालन का उपयोग करके एक समाधान है।

def rollmatch(a,b):
    bb=b*2
    return any(not any(ax^bbx for ax,bbx in zip(a,bb[i:])) for i in range(len(a)))

l1 = [1,0,0,1]
l2 = [1,1,0,0]
l3 = [1,0,1,0]

rollmatch(l1,l2)  # True
rollmatch(l1,l3)  # False

दूसरा दृष्टिकोण: [नष्ट]


पहला संस्करण O (n²) है और दूसरा इसके लिए काम नहीं करता है rollmatch([1, 0, 1, 1], [0, 1, 1, 1])
विड्राक

अच्छा पकड़, मैं इसे हटा दूँगा!
पॉल एमसीसीजी

1

एक पूर्ण, मुक्त उत्तर नहीं है, लेकिन तुलनाओं को कम करके अनुकूलन के विषय पर, मैं भी सामान्यीकृत अभ्यावेदन के बारे में सोच रहा था।

अर्थात्, यदि आपका इनपुट वर्णमाला {0, 1} है, तो आप अनुमत अनुमतियों की संख्या को काफी कम कर सकते हैं। पहली सूची को एक (छद्म-) सामान्यीकृत रूप में घुमाएं (आपके प्रश्न में वितरण को देखते हुए, मैं एक को चुनूंगा जहां 1 बिट्स में से एक बाईं तरफ चरम पर है, और 0 बिट्स में से एक चरम दाईं ओर है)। अब प्रत्येक तुलना से पहले, समान संरेखण पैटर्न के साथ संभावित पदों के माध्यम से क्रमिक रूप से अन्य सूची को घुमाएं।

उदाहरण के लिए, यदि आपके पास कुल चार 1 बिट्स हैं, तो इस संरेखण के साथ अधिकतम 4 क्रमांकन हो सकते हैं, और यदि आपके पास 1 बिट्स के क्लस्टर हैं, तो ऐसे क्लस्टर में प्रत्येक अतिरिक्त बिट पदों की मात्रा कम कर देता है।

List 1   1 1 1 0 1 0

List 2   1 0 1 1 1 0  1st permutation
         1 1 1 0 1 0  2nd permutation, final permutation, match, done

यह बड़े अक्षर और विभिन्न संरेखण पैटर्न के लिए सामान्यीकृत करता है; मुख्य चुनौती केवल कुछ संभव अभ्यावेदन के साथ एक अच्छा सामान्यीकरण खोजना है। आदर्श रूप से, यह एक एकल सामान्य प्रतिनिधित्व के साथ एक उचित सामान्यीकरण होगा, लेकिन समस्या को देखते हुए, मुझे नहीं लगता कि यह संभव है।


0

आगे RocketRoy के उत्तर पर बिल्डिंग: 64 बिट संख्या अहस्ताक्षरित करने के लिए सामने अपनी सभी सूचियों में कनवर्ट करें। प्रत्येक सूची के लिए, सबसे छोटे संख्यात्मक मान को खोजने के लिए उन 55 बिट्स को घुमाएँ।

अब आप प्रत्येक सूची के लिए एक एकल अहस्ताक्षरित 64 बिट मान के साथ बचे हैं जिसे आप अन्य सूचियों के मूल्य के साथ सीधे तुलना कर सकते हैं। फंक्शन is_circular_identical () अब आवश्यक नहीं है।

(संक्षेप में, आप अपनी सूचियों के लिए एक पहचान मूल्य बनाते हैं जो सूचियों के तत्वों के रोटेशन से प्रभावित नहीं होता है) यदि आपकी सूचियों में किसी की मनमानी संख्या हो तो भी यह काम करेगा।


0

यह साल्वाडोर डाली का एक ही विचार है, लेकिन स्ट्रिंग रूपांतरण की आवश्यकता नहीं है। असंभव बदलाव निरीक्षण से बचने के लिए KMP एक ही पुनर्प्राप्ति विचार है। उन्हें केवल KMPModified (list1, list2 + list2) कहते हैं।

    public class KmpModified
    {
        public int[] CalculatePhi(int[] pattern)
        {
            var phi = new int[pattern.Length + 1];
            phi[0] = -1;
            phi[1] = 0;

            int pos = 1, cnd = 0;
            while (pos < pattern.Length)
                if (pattern[pos] == pattern[cnd])
                {
                    cnd++;
                    phi[pos + 1] = cnd;
                    pos++;
                }
                else if (cnd > 0)
                    cnd = phi[cnd];
                else
                {
                    phi[pos + 1] = 0;
                    pos++;
                }

            return phi;
        }

        public IEnumerable<int> Search(int[] pattern, int[] list)
        {
            var phi = CalculatePhi(pattern);

            int m = 0, i = 0;
            while (m < list.Length)
                if (pattern[i] == list[m])
                {
                    i++;
                    if (i == pattern.Length)
                    {
                        yield return m - i + 1;
                        i = phi[i];
                    }
                    m++;
                }
                else if (i > 0)
                {
                    i = phi[i];
                }
                else
                {
                    i = 0;
                    m++;
                }
        }

        [Fact]
        public void BasicTest()
        {
            var pattern = new[] { 1, 1, 10 };
            var list = new[] {2, 4, 1, 1, 1, 10, 1, 5, 1, 1, 10, 9};
            var matches = Search(pattern, list).ToList();

            Assert.Equal(new[] {3, 8}, matches);
        }

        [Fact]
        public void SolveProblem()
        {
            var random = new Random();
            var list = new int[10];
            for (var k = 0; k < list.Length; k++)
                list[k]= random.Next();

            var rotation = new int[list.Length];
            for (var k = 1; k < list.Length; k++)
                rotation[k - 1] = list[k];
            rotation[rotation.Length - 1] = list[0];

            Assert.True(Search(list, rotation.Concat(rotation).ToArray()).Any());
        }
    }

उममीद है कि इससे मदद मिलेगी!


0

समस्या को सरल बनाना

  • समस्या में आइटमों की सूची शामिल है
  • मूल्य का डोमेन द्विआधारी है (0,1)
  • हम लगातार 1गणना करके समस्या को कम कर सकते हैं
  • और लगातार 0एक नकारात्मक गिनती में है

उदाहरण

A = [ 1, 1, 1, 0, 0, 1, 1, 0 ]
B = [ 1, 1, 0, 1, 1, 1, 0, 0 ]
~
A = [ +3, -2, +2, -1 ]
B = [ +2, -1, +3, -2 ]
  • इस प्रक्रिया के लिए आवश्यक है कि पहला आइटम और अंतिम आइटम अलग होना चाहिए
  • यह समग्र रूप से तुलना की मात्रा को कम करेगा

जाँच प्रक्रिया

  • यदि हम मानते हैं कि वे डुप्लिकेट हैं, तो हम मान सकते हैं कि हम क्या देख रहे हैं
  • मूल रूप से पहली सूची का पहला आइटम दूसरी सूची में कहीं मौजूद होना चाहिए
  • पहली सूची में, और उसी तरीके से अनुसरण किया जाता है
  • पिछली वस्तुओं को पहली सूची से अंतिम आइटम होना चाहिए
  • चूंकि यह परिपत्र है, आदेश समान है

पकड़

  • यहां सवाल यह है कि कहां से शुरू करें, तकनीकी रूप से lookupऔरlook-ahead
  • हम सिर्फ यह जाँचेंगे कि पहली सूची का पहला तत्व दूसरी सूची के माध्यम से कहाँ मौजूद है
  • लगातार तत्व की संभावना कम है कि हमने सूची को हिस्टोग्राम में मैप किया

छद्म कोड

FUNCTION IS_DUPLICATE (LIST L1, LIST L2) : BOOLEAN

    LIST A = MAP_LIST(L1)
    LIST B = MAP_LIST(L2)

    LIST ALPHA = LOOKUP_INDEX(B, A[0])

    IF A.SIZE != B.SIZE
       OR COUNT_CHAR(A, 0) != COUNT_CHAR(B, ALPHA[0]) THEN

        RETURN FALSE

    END IF

    FOR EACH INDEX IN ALPHA

        IF ALPHA_NGRAM(A, B, INDEX, 1) THEN

            IF IS_DUPLICATE(A, B, INDEX) THEN

                RETURN TRUE

            END IF

        END IF

    END FOR

    RETURN FALSE

END FUNCTION

FUNCTION IS_DUPLICATE (LIST L1, LIST L2, INTEGER INDEX) : BOOLEAN

    INTEGER I = 0

    WHILE I < L1.SIZE DO

        IF L1[I] != L2[(INDEX+I)%L2.SIZE] THEN

            RETURN FALSE

        END IF

        I = I + 1

    END WHILE

    RETURN TRUE

END FUNCTION

कार्य

  • MAP_LIST(LIST A):LIST एक नई सूची में सबसे महत्वपूर्ण सामग्री के रूप में एमएपी

  • LOOKUP_INDEX(LIST A, INTEGER E):LISTभारत की सूची में सूची में Eमौजूद इजाफे की सूची मौजूद हैA

  • COUNT_CHAR(LIST A , INTEGER E):INTEGERECOIST HOW MANY एक समय में एक अवसर OCCUR लेता हैA

  • ALPHA_NGRAM(LIST A,LIST B,INTEGER I,INTEGER N):BOOLEANपता लगाएं कि B[I]बराबर है A[0] N-GRAMमें दोनों दिशाओं


आखिरकार

यदि सूची का आकार बहुत बड़ा होने वाला है या यदि हम जिस चक्र से चक्र की जांच करना शुरू कर रहे हैं वह तत्व अक्सर उच्च होता है, तो हम निम्नलिखित कार्य कर सकते हैं:

  • शुरुआत करने के लिए पहली सूची में सबसे कम-लगातार आइटम देखें

  • रैखिक जांच से गुजरने की संभावना को कम करने के लिए एन-ग्राम एन पैरामीटर बढ़ाएं


0

प्रश्न में सूचियों के लिए एक कुशल, त्वरित-से-गणना "विहित रूप" के रूप में व्युत्पन्न किया जा सकता है:

  • तीन संख्याओं को प्राप्त करने के लिए लोगों के बीच शून्य की संख्या (रैप-अराउंड को अनदेखा करना) की गणना करें।
  • तीन नंबरों को घुमाएं ताकि सबसे बड़ी संख्या पहले हो।
  • पहली संख्या ( a) 18और 52(समावेशी) के बीच होनी चाहिए । इसे फिर से 0और के बीच में एनकोड करें 34
  • दूसरी संख्या ( b) के बीच 0और होनी चाहिए 26, लेकिन यह ज्यादा मायने नहीं रखती है।
  • तीसरा नंबर गिराएं, क्योंकि यह सिर्फ है 52 - (a + b)और कोई जानकारी नहीं जोड़ता है

विहित रूप पूर्णांक है b * 35 + a, जो बीच 0और 936(समावेशी) है, जो काफी कॉम्पैक्ट है ( 477कुल में परिपत्र-अद्वितीय सूची हैं)।


0

मैंने एक सीधा हल लिखा है जो दोनों सूचियों की तुलना करता है और प्रत्येक पुनरावृत्ति के लिए तुलनात्मक मूल्य के सूचकांक को बढ़ाता है (और चारों ओर लपेटता है)।

मैं अजगर को अच्छी तरह से नहीं जानता, इसलिए मैंने इसे जावा में लिखा, लेकिन यह वास्तव में सरल है इसलिए इसे किसी अन्य भाषा में अनुकूलित करना आसान होना चाहिए।

इसके द्वारा आप अन्य प्रकार की सूचियों की तुलना भी कर सकते हैं।

public class Main {

    public static void main(String[] args){
        int[] a = {0,1,1,1,0};
        int[] b = {1,1,0,0,1};

        System.out.println(isCircularIdentical(a, b));
    }

    public static boolean isCircularIdentical(int[] a, int[]b){
        if(a.length != b.length){
            return false;
        }

        //The outer loop is for the increase of the index of the second list
        outer:
        for(int i = 0; i < a.length; i++){
            //Loop trough the list and compare each value to the according value of the second list
            for(int k = 0; k < a.length; k++){
                // I use modulo length to wrap around the index
                if(a[k] != b[(k + i) % a.length]){
                    //If the values do not match I continue and shift the index one further
                    continue outer;
                }
            }
            return true;
        }
        return false;
    }
}

0

जैसा कि दूसरों ने उल्लेख किया है, एक बार जब आप किसी सूची के सामान्यीकृत रोटेशन को पाते हैं, तो आप उनकी तुलना कर सकते हैं।

कुछ काम करने वाला कोड जो ऐसा करता है, बेसिक विधि प्रत्येक सूची के लिए एक सामान्यीकृत रोटेशन खोजने और तुलना करने के लिए है:

  • प्रत्येक सूची पर एक सामान्यीकृत रोटेशन सूचकांक की गणना करें।
  • अपने आइटम के साथ दोनों सूचियों पर लूप करें, प्रत्येक आइटम की तुलना करें, यदि वे गलत मिलान करते हैं तो वापस लौटते हैं।

ध्यान दें कि यह विधि संख्याओं पर निर्भर नहीं है, आप स्ट्रिंग्स (किसी भी मान की तुलना की जा सकती है) की सूची में पास कर सकते हैं।

लिस्ट-इन-लिस्ट खोज करने के बजाय, हम जानते हैं कि हम चाहते हैं कि सूची न्यूनतम मूल्य के साथ शुरू हो - इसलिए हम न्यूनतम मूल्यों पर लूप कर सकते हैं, तब तक खोज करते हैं जब तक कि हमें यह पता न चल जाए कि किसका क्रमिक मान सबसे कम है, इसे आगे की तुलनाओं के लिए संग्रहीत करें जब तक हमारे पास सबसे अच्छा नहीं है।

सूचकांक की गणना करते समय जल्दी से बाहर निकलने के कई अवसर हैं, कुछ अनुकूलन पर विवरण।

  • सबसे अच्छा न्यूनतम मूल्य के लिए खोज छोड़ दें जब केवल एक हो।
  • न्यूनतम मान खोजना छोड़ें जब पिछला भी एक न्यूनतम मूल्य है (यह एक बेहतर मैच नहीं होगा)।
  • सभी मान समान होने पर खोज करना छोड़ें।
  • सूची के अलग-अलग न्यूनतम मूल्य होने पर जल्दी असफल हो जाना।
  • ऑफ़सेट मैच होने पर नियमित तुलना का उपयोग करें।
  • तुलना के दौरान सूचियों में से एक पर सूचकांक मूल्यों को लपेटने से बचने के लिए ऑफसेट समायोजित करें।

ध्यान दें कि पायथन में एक सूची-इन-सर्च अच्छी तरह से तेज हो सकती है, हालांकि मुझे एक कुशल एल्गोरिदम खोजने में दिलचस्पी थी - जिसका उपयोग अन्य भाषाओं में भी किया जा सकता है। इसके अलावा, नई सूची बनाने से बचने के लिए कुछ लाभ हैं।

def normalize_rotation_index(ls, v_min_other=None):
    """ Return the index or -1 (when the minimum is above `v_min_other`) """

    if len(ls) <= 1:
        return 0

    def compare_rotations(i_a, i_b):
        """ Return True when i_a is smaller.
            Note: unless there are large duplicate sections of identical values,
            this loop will exit early on.
        """
        for offset in range(1, len(ls)):
            v_a = ls[(i_a + offset) % len(ls)]
            v_b = ls[(i_b + offset) % len(ls)]
            if v_a < v_b:
                return True
            elif v_a > v_b:
                return False
        return False

    v_min = ls[0]
    i_best_first = 0
    i_best_last = 0
    i_best_total = 1
    for i in range(1, len(ls)):
        v = ls[i]
        if v_min > v:
            v_min = v
            i_best_first = i
            i_best_last = i
            i_best_total = 1
        elif v_min == v:
            i_best_last = i
            i_best_total += 1

    # all values match
    if i_best_total == len(ls):
        return 0

    # exit early if we're not matching another lists minimum
    if v_min_other is not None:
        if v_min != v_min_other:
            return -1
    # simple case, only one minimum
    if i_best_first == i_best_last:
        return i_best_first

    # otherwise find the minimum with the lowest values compared to all others.
    # start looking after the first we've found
    i_best = i_best_first
    for i in range(i_best_first + 1, i_best_last + 1):
        if (ls[i] == v_min) and (ls[i - 1] != v_min):
            if compare_rotations(i, i_best):
                i_best = i

    return i_best


def compare_circular_lists(ls_a, ls_b):
    # sanity checks
    if len(ls_a) != len(ls_b):
        return False
    if len(ls_a) <= 1:
        return (ls_a == ls_b)

    index_a = normalize_rotation_index(ls_a)
    index_b = normalize_rotation_index(ls_b, ls_a[index_a])

    if index_b == -1:
        return False

    if index_a == index_b:
        return (ls_a == ls_b)

    # cancel out 'index_a'
    index_b = (index_b - index_a)
    if index_b < 0:
        index_b += len(ls_a)
    index_a = 0  # ignore it

    # compare rotated lists
    for i in range(len(ls_a)):
        if ls_a[i] != ls_b[(index_b + i) % len(ls_b)]:
            return False
    return True


assert(compare_circular_lists([0, 9, -1, 2, -1], [-1, 2, -1, 0, 9]) == True)
assert(compare_circular_lists([2, 9, -1, 0, -1], [-1, 2, -1, 0, 9]) == False)
assert(compare_circular_lists(["Hello" "Circular", "World"], ["World", "Hello" "Circular"]) == True)
assert(compare_circular_lists(["Hello" "Circular", "World"], ["Circular", "Hello" "World"]) == False)

देखें: कुछ और परीक्षणों / उदाहरणों के लिए यह स्निपेट


0

आप यह देख सकते हैं कि क्या सूची A अपेक्षित O (N) समय में आसानी से सूची B के चक्रीय बदलाव के बराबर है।

मैं सूची ए के हैश की गणना करने के लिए एक बहुपद हैश फ़ंक्शन का उपयोग करता हूं, और सूची बी के प्रत्येक चक्रीय बदलाव जहां सूची बी की एक सूची में सूची ए के समान हैश है, मैं वास्तविक तत्वों की तुलना यह देखने के लिए करूंगा कि क्या वे समान हैं ।

इसका कारण यह है कि बहुपद हैश फ़ंक्शंस (जो बेहद सामान्य हैं!) के कारण, आप प्रत्येक साइकल शिफ्ट के हैश की गणना पिछले एक से लगातार समय में कर सकते हैं, इसलिए आप ओ में चक्रीय शिफ्ट के सभी के लिए हैश की गणना कर सकते हैं ( एन) समय।

यह इस तरह काम करता है:

मान लीजिए कि B में N तत्व हैं, तो B का हैश P का उपयोग करता है:

Hb=0;
for (i=0; i<N ; i++)
{
    Hb = Hb*P + B[i];
}

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

Hb=0;
for (i=0; i<N ; i++)
{
    Hb += B[i] * P^(N-1-i);  //^ is exponentiation, not XOR
}

ध्यान दें कि कैसे हर B [i] P ^ (N-1-i) से गुणा किया जाता है। यदि हम B को 1 से बाईं ओर शिफ्ट करते हैं, तो हर B [i] को पहले वाले को छोड़कर, एक अतिरिक्त P से गुणा किया जाएगा। चूंकि गुणन इसके अलावा वितरित करता है, हम सभी घटकों को एक बार में केवल पूरे हैश को गुणा करके गुणा कर सकते हैं, और फिर पहले तत्व के लिए कारक को ठीक कर सकते हैं।

B की बाईं पारी का हैश बस है

Hb1 = Hb*P + B[0]*(1-(P^N))

दूसरी बाईं पारी:

Hb2 = Hb1*P + B[1]*(1-(P^N))

और इसी तरह...

ध्यान दें: ऊपर दिए गए सभी गणित में कुछ मशीन शब्द आकार modulo का प्रदर्शन किया गया है, और आपको केवल एक बार P ^ N की गणना करनी होगी।


-1

इसे करने के लिए सबसे पायथोनिक तरीके से गोंद करने के लिए, सेट का उपयोग करें!

from sets import Set
a = Set ([1, 1, 1, 0, 0])
b = Set ([0, 1, 1, 1, 0]) 
c = Set ([1, 0, 0, 1, 1])
a==b
True
a==b==c
True

यह उसी क्रम में 0 और 1 की समान संख्या के साथ तार से मेल भी खाएगा
GeneralBecos

GeneralBecos: बस उन स्ट्रिंग्स का चयन करें और एक दूसरे चरण में ऑर्डर की जांच करें
लुईस

वे एक ही रैखिक क्रम में नहीं हैं। वे उसी 'सर्कुलर' क्रम में हैं। आप चरण 2 के रूप में जो वर्णन करते हैं, वह मूल समस्या है।
GeneralBecos
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.