2012-11-21 6 views
5

문자열 S와 숫자 L의 시퀀스가 ​​len (S) = len (L) 인 경우를 가정 해 봅시다.문자와 숫자 사이의 가능한 비유치 찾기

문자열의 문자와 시퀀스의 숫자 사이에 바이어스를 찾을 수있는 가장 깨끗한 방법은 각 문자가 하나의 숫자와 일치하도록하는 것입니다. 어쩌면,

예를 들어, "AABBCC는"115522과 일치해야하지만 123456 또는

111111 나는 두 dicts 및 루프와 복잡한 설정을 가지고 있지만, 이렇게 깨끗한 방법이 있는지 궁금하네요 파이썬 라이브러리의 일부 함수를 사용합니다.

+0

a = "abcabc"및 b = "123127"인 경우 예상되는 출력은 무엇입니까?참 또는 거짓 – raton

+0

거짓은 'c'가 3과 7 (또는 다른 방법으로, 3과 7이 모두 'c'에 매핑 됨)에 매핑되기 때문입니다. bijection에서 각 요소는 다른 집합에 하나의 일치 요소 만 포함합니다. –

답변

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) 

이도 돌아갑니다 아이디어를 구현하는 코드입니다 (그렇지 않은 경우, 동일한 두 번째 세트의 수, 또는 그 반대에 문자 매핑의 두 사본이됩니다) 1 개의 순서가 다른 것보다 짧지 만 유효한 매핑이 이미 설정되어있는 경우는 true 시퀀스의 길이가 동일해야하는 경우 해당 시퀀스를 확인해야합니다.

+0

흠, 나는 이것이 효과가 있다고 생각하지 않는다? [1,1,1,1,1,1]을 사용하면 다른 세트와 마찬가지로 (a, 1), (b, 1), (c, 1)로 끝납니다. 이렇게하면 전체 분사가 아닌 총격을 줄 수 있습니다. –

+0

참. 나는 처음에 그 아이디어를 제공했다. 편집 된 버전의 코드는 두 세트를 모두 확인합니다. – acjay

+0

빠른 질문 중,'a == b == c'는 나쁜 습관이라고 생각하십니까? –

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

을하는 데 도움이 : 다른 답변과는 달리,

일반적 만 세트 사이 bijections에 대해 이야기하기 때문에
>>> 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

, 나는 가정을, 숫자의 주문이 글자의 순서와 일치 할 필요는 없습니다. 그렇다면 짧고 우아한 해결책이 있지만 파이썬 2.7에서 소개 된 collections.Counter 클래스가 필요합니다. 오래된 버전의 사람들에게는 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

어쩌면 나는 명확하지 않았다. 조금은 bijection이 양방향 매핑이다. 마지막 예제에서 'a'는 1과 2로 매핑됩니다. 여기서 3은 'b'와 'c'모두에 매핑되므로 독 립적이지 않을뿐만 아니라 사상 또는 주입도 아닙니다. –

+0

@EhsanKia 당신은 이상한 방법으로 * bijection *이라는 용어를 사용하고 있습니다. bijection은 양방향 매핑입니다. 그렇지만 [집합] (http://en.wikipedia.org/wiki/Set_ (mathematics)) 사이에만 존재합니다. 문자열은 중복 값을 포함 할 수 있으므로 집합이 아닙니다. 그래서 당신의 질문에 답하기 위해서는 그것을 해석 할 필요가 있습니다. 그리고 나는 두 가지의 유효한 해석을 제시했습니다. 마지막 예는''aabbcc ''({a, b, c})의 문자 세트에서'123333'의 {{1, 2, 3} }). –