2012-11-21 11 views
5

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

आप अनुक्रम ऐसा है कि हर किरदार के एक और केवल एक अंकों मैचों में अंकों को स्ट्रिंग के वर्णों के बीच एक द्विभाजन मिल सकता है की जाँच की स्पष्ट तरीका क्या होगा।

उदाहरण के लिए, "aabbcc" 115,522 से मेल खाना चाहिए, लेकिन नहीं 123456 या 111111.

मैं दो dicts और पाश के साथ एक जटिल सेटअप है, लेकिन ऐसा करने का एक साफ तरीका है मैं सोच रहा हूँ, हो सकता है पायथन पुस्तकालयों से कुछ फ़ंक्शन का उपयोग करके।

+0

अगर एक = "abcabc" और ख = "123,127" क्या उम्मीद उत्पादन होगा?सही या गलत – raton

+0

झूठा, क्योंकि 'सी' मानचित्र 3 और 7 दोनों (या दूसरी तरफ, 3 और 7 दोनों मानचित्र 'सी' के लिए मानचित्र हैं)। एक विभाजन में, प्रत्येक तत्व में दूसरे सेट में एक और केवल एक मिलान तत्व होता है। –

उत्तर

6

मैं इस के लिए एक सेट का प्रयोग करेंगे:

In [9]: set("aabbcc") 
Out[9]: set(['a', 'c', 'b']) 

In [10]: set(zip("aabbcc", [1, 1, 5, 5, 2, 2])) 
Out[10]: set([('a', 1), ('c', 2), ('b', 5)]) 

दूसरे सेट लंबाई पहला सेट यदि और केवल यदि मानचित्रण surjective है के बराबर होगा।

यहाँ कोड है कि इस विचार

def is_bijection(seq1, seq2): 
    distinct1 = set(seq1) 
    distinct2 = set(seq2) 
    distinctMappings = set(zip(seq1, seq2)) 
    return len(distinct1) == len(distinctMappings) and len(distinct2) == len(distinctMappings) 

यह भी वापस आ जाएगी लागू करता है (अगर यह नहीं है, आप दूसरे सेट में एक ही नंबर, या इसके विपरीत को एक पत्र मानचित्रण की दो प्रतियां होगा) सच है कि एक अनुक्रम दूसरे की तुलना में छोटा है, लेकिन एक वैध मैपिंग पहले ही स्थापित हो चुकी है। यदि अनुक्रम एक ही लंबाई होनी चाहिए, तो आपको इसके लिए एक चेक जोड़ना चाहिए।

+0

हम्म, मुझे विश्वास नहीं है कि यह काम करता है? [1,1,1,1,1,1] के साथ आप (ए, 1), (बी, 1), (सी, 1) के साथ समाप्त होते हैं जिसमें 3 सेट होते हैं, बस दूसरे सेट की तरह। तो यह आपको एक पूर्ण प्रक्षेपण नहीं, एक प्रक्षेपण देता है। –

+0

सच है। मैंने शुरुआत में सिर्फ विचार प्रदान किया। संपादित संस्करण में कोड दोनों सेट की जांच करता है। – acjay

+0

त्वरित ऑफटॉप प्रश्न, एक == बी == सी' खराब अभ्यास माना जाता है? –

0
import itertools 

a = 'aabbcc' 
b = 112233 

z = sorted(zip(str(a), str(b))) 
x = all(
    gx == g0 
    for k, g in itertools.groupby(z, key=lambda x: x[0]) 
    for gx in g for g0 in g 
) 
print x 

या:

import itertools 

a = 'aabbcc' 
b = 112233 

z = zip(str(a), str(b)) 
x = all(
    (z1[0] == z2[0]) == (z1[1] == z2[1]) for z1 in z for z2 in z 
) 
print x 
0

वहाँ (छंटाई और itertools.groupby के साथ) यह करने के लिए एक और अधिक सुरुचिपूर्ण तरीका है, लेकिन मैं wayy कि अभी आंकड़ा बाहर करने के लिए नींद से deproved लिए कर रहा हूँ। लेकिन यह अभी भी काम करना चाहिए:

In [172]: S = "aabbcc" 

In [173]: L = [1, 1, 5, 5, 2, 2] 

In [174]: mapping = collections.defaultdict(list) 

In [175]: reverseMapping = collections.defaultdict(list) 

In [176]: for digit, char in zip(L, S): 
    mapping[digit].append(char) 
    reverseMapping[char].append(digit) 
    .....:  

In [177]: all(len(set(v))==1 for v in mapping.values()) and all(len(set(v))==1 for v in reverseMapping.values()) 
Out[177]: True 

In [181]: S = "aabbcc" 

In [182]: L = [1, 2, 3, 4, 5, 6] 

In [183]: mapping = collections.defaultdict(list) 

In [184]: reverseMapping = collections.defaultdict(list) 

In [185]: for digit, char in zip(L, S):                   
    mapping[digit].append(char) 
    reverseMapping[char].append(digit) 
    .....:  

In [186]: all(len(set(v))==1 for v in mapping.values()) and all(len(set(v))==1 for v in reverseMapping.values()) 
Out[186]: False 

आशा इस मदद करता है

0

इस आदेश का सम्मान करता है:,

>>> s = "aabbcc" 
>>> n = 115522 
>>> l1 = dict(zip(s, str(n))).items() 
>>> l2 = zip(s, str(n)) 
>>> l1 
[('a', '1'), ('c', '2'), ('b', '5')] 
>>> l2 
[('a', '1'), ('a', '1'), ('b', '5'), ('b', '5'), ('c', '2'), ('c', '2')] 
>>> not bool([i for i in l2 if i not in l1]) 
True 
>>> n = 115225 
>>> l1 = dict(zip(s, str(n))).items() 
>>> l2 = zip(s, str(n)) 
>>> not bool([i for i in l2 if i not in l1]) 
False 
0

के बाद से आप सामान्य रूप से केवल सेट के बीच bijections के बारे में बात करते हैं, मुझे लगता है अन्य उत्तर के विपरीत, कि अंकों के क्रम में अक्षरों के क्रम से मेल नहीं खाते हैं। यदि ऐसा है, तो एक छोटा, सुरुचिपूर्ण समाधान है, लेकिन इसे collections.Counter कक्षा की आवश्यकता है, जिसे पायथन 2.7 में पेश किया गया था। पुराने संस्करण के साथ फंसे लोगों के लिए, backport for 2.5+ है।

from collections import Counter 

def bijection_exists_between(a, b): 
    return sorted(Counter(a).values()) == sorted(Counter(b).values()) 

परीक्षण:

>>> bijection_exists_between("aabbcc", "123123") 
True 
>>> bijection_exists_between("aabbcc", "123124") 
False 

आपका उदाहरण, बल्कि किनारे मामलों पर प्रकाश कर रहे हैं क्योंकि आपके प्रश्न पढ़ने का एक और तरीका असमान होने के लिए अंकों की संख्या और अक्षरों की संख्या के लिए अनुमति देता है (यानी तुम देखो अद्वितीय अंकों के सेट के लिए अद्वितीय पात्रों के सेट से एक द्विभाजन, के लिए बहुत "aabbcc" जैसे "123333" पर biject होगा।)। यदि यह आप क्या मतलब है, बजाय इस संस्करण का उपयोग करें:

def bijection_exists_between(a, b): 
    return len(set(a)) == len(set(b)) 
+0

शायद मैं स्पष्ट नहीं था, थोड़ा एक विभाजन एक दो तरह का मानचित्रण है। आपके आखिरी उदाहरण में, 'ए' मानचित्र 1 और 2 दोनों के लिए, जहां 3 मानचित्र दोनों 'बी' और 'सी' के लिए हैं, इसलिए न केवल यह जैविक है, यह भी आकस्मिक या इंजेक्शन नहीं है। –

+0

@ एहसानकिआ आप एक अजीब तरीके से * बिजेक्शन * शब्द का उपयोग कर रहे हैं। एक विभाजन एक दो तरह का मानचित्रण है, हां, लेकिन यह केवल [सेट] (http://en.wikipedia.org/wiki/Set_ (गणित) के बीच मौजूद है)। एक स्ट्रिंग एक सेट नहीं है क्योंकि इसमें डुप्लिकेट मान हो सकते हैं। तो अपने प्रश्न का उत्तर देने के लिए इसे व्याख्या करने की आवश्यकता है, और मैंने दो पूर्ण मान्य ऐसी व्याख्याएं प्रस्तुत की हैं। मेरा आखिरी उदाहरण इस अर्थ में एक विभाजन है कि '123333' ({1, 2, 3) में अंकों के सेट पर' "एब्बैक" '({ए, बी, सी}) में वर्णों के सेट से एक विभाजन मौजूद है। })। –