2012-10-25 19 views
5

मैं कई अन्य अतः सवाल (और google'd टन) है कि कर रहे हैं यह करने के लिए 'similar'-ish को देखा है, लेकिन उनमें से कोई भी मेरे सवाल का सही फिट करने के लिए लग रहे हैं।अजगर अद्वितीय स्ट्रिंग निर्माण

मैं, एक गैर निश्चित लंबाई, अनन्य टेक्स्ट बनाने के लिए कोशिश कर रहा हूँ केवल एक स्ट्रिंग मेरे द्वारा निर्दिष्ट में पात्रों हैं। जैसे पूंजी और लोअर केस ए-जेए-जेड पात्रों से बना है। (इस उदाहरण के लिए मैं केवल एक, b, और c लोअर केस का उपयोग)

def next(index, validCharacters = 'abc'): 
    return uniqueShortAsPossibleString 

सूचकांक तर्क एक सूचकांक (पूर्णांक) कि एक पाठ से संबंधित होगा

कुछ इस (टूटी हुई नीचे कोड) की तरह स्ट्रिंग, उदाहरण के लिए:

next(1) == 'a' 
next(2) == 'b' 
next(3) == 'c' 

next(4) == 'aa' 
next(5) == 'ab' 
next(6) == 'ac' 

next(7) == 'ba' 
next(8) == 'bb' 
next(9) == 'bc' 

next(10) == 'ca' 
next(11) == 'cb' 
next(12) == 'cc' 

और आगे। स्ट्रिंग:

  1. अद्वितीय होना चाहिए, मैं एक पहचानकर्ता के रूप में उपयोग किया जाएगा, और यह केवल a-zA-जेड वर्ण
  2. के रूप में संभव के रूप में छोटा है, कम सूचकांक जा रहा है कम से कम के साथ किया जा सकता है (देखें उपरोक्त उदाहरण)
  3. केवल वर्ण दिए गए तर्क स्ट्रिंग validCharacters

अंत में में निर्दिष्ट होते हैं, कैसे मैं अगले() फ़ंक्शन लिख सकता है निर्दिष्ट पात्रों के साथ एक अद्वितीय कम स्ट्रिंग के लिए एक पूर्णांक सूचकांक मूल्य से संबंधित ?

पीएस मैं एसओ के लिए नया हूं, इस साइट ने मुझे पूरे वर्षों में मदद की है, और जब मैंने कभी खाता नहीं बनाया है या एक सवाल पूछा है (अब तक), मुझे उम्मीद है कि मैंने ठीक काम किया है कि मैं क्या कर रहा हूं इस के साथ पूरा करने की कोशिश कर रहा है।

from itertools import combinations_with_replacement, chain 

chars = 'abc' 
a = chain(*(combinations_with_replacement(chars, i) for i in range(1, len(chars) + 1))) 

मूल रूप से, इस कोड को पुनरावर्तक कि लंबाई 1, 2, ..., len(chars) की chars के सभी संयोजनों को जोड़ती है बनाता है:

+0

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

उत्तर

1

आप किसी अन्य आधार में एक नंबर के लिए एक नंबर परिवर्तित करने के लिए कोशिश कर रहे हैं, लेकिन उस आधार के अंक के लिए स्वैच्छिक वर्णों का उपयोग कर।

import string 
chars = string.lowercase + string.uppercase 

def identifier(x, chars): 
    output = [] 
    base = len(chars) 
    while x: 
     output.append(chars[x % base]) 
     x /= base 
    return ''.join(reversed(output)) 

print identifier(1, chars) 

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

+0

'उलट' यहां भी आवश्यक नहीं है क्योंकि आप केवल लंबाई के बारे में चिंतित हैं, आदेश नहीं। – agf

+0

हालांकि सावधान रहें: 'पहचानकर्ता (123456789, वर्ण) 'रिटर्न' þƒžå' –

+0

स्वीकृत (और +1 किया गया) यह वही है जो मुझे चाहिए, और मैं कार्यान्वयन की सराहना करता हूं। मुझे पता था कि यह ऐसा कुछ था, बस उस पर उंगली लगाने में असमर्थ था! – powerpup118

1

itertools हमेशा दे सकते हैं आप एक लाइनर iterators समझ से परे।

for x in a: print x के उत्पादन में है:

('a',) 
('b',) 
('c',) 
('a', 'b') 
('a', 'c') 
('b', 'a') 
('b', 'c') 
('c', 'a') 
('c', 'b') 
('a', 'b', 'c') 
('a', 'c', 'b') 
('b', 'a', 'c') 
('b', 'c', 'a') 
('c', 'a', 'b') 
('c', 'b', 'a') 
+0

+1। मैंने कुछ महीनों पहले इस समस्या को लंबे समय तक हल किया था, यह एक फ्रिगिन मिशन था :) – Sheena

1

आप कर सकते हैं वास्तव में नहीं "सहयोगी" कष्टप्रद साथ सूचकांक, लेकिन अगले एक जनरेटर है कि उपज और उत्पादन आप के लिए पूछ रहे हैं प्रदान करती है:

from itertools import combinations_with_replacement 

def uniquenames(chars): 
    for i in range(1, len(chars)): 
     for j in combinations_with_replacement(chars, i): 
      yield ''.join(j) 

print list(uniquenames('abc')) 
# ['a', 'b', 'c', 'aa', 'ab', 'ac', 'bb', 'bc', 'cc'] 
+0

पठनीय कोड – Blender

+0

@ ब्लेंडर धन्यवाद के लिए +1, बस एहसास हुआ कि यह कुछ याद आ रहा है ... –

3

आप जो करने का प्रयास कर रहे हैं वह next फ़ंक्शन के दूसरे आधार पर पैरामीटर लिखें। तो next समारोह का काम validCharacters में पात्रों का उपयोग करके आधार k में पैरामीटर p को बदलने के लिए होगा:

मान लें validCharactersk वर्ण हैं करते हैं।

अपने उदाहरण में, आप आधार 3 में संख्या लिखना और फिर एक पत्र के साथ प्रत्येक अंक संबद्ध कर सकते हैं:

next(1) -> 1 -> 'a' 
next(2) -> 2 -> 'b' 

next(4) -> 11 -> 'aa' 
next(7) -> 21 -> 'ba' 

और इसके आगे।

इस पद्धति से

, आप जानते हुए भी या किसी next(x-i), जो आप पुनरावृत्ति के तरीकों के साथ ऐसा नहीं कर सकते कंप्यूटिंग के बिना next(x) कॉल कर सकते हैं।

+0

मेरे उत्तर में कार्यान्वयन को ठीक करने की आवश्यकता है। विचार के लिए – agf

+0

+1, मुझे इसे समझने के लिए कुछ प्रकार के मूल कार्यान्वयन या psuedo कोड को देखने की आवश्यकता है। – powerpup118

0

तो ऐसा लगता है कि आप भाषा '' ए ',' बी ',' सी '} द्वारा उत्पन्न सभी तारों के माध्यम से गणना करने की कोशिश कर रहे हैं। यह finite state automata का उपयोग करके किया जा सकता है (हालांकि आप ऐसा नहीं करना चाहते हैं)। भाषा के माध्यम से गणना करने का एक आसान तरीका एक सूची से शुरू करना है और क्रमशः लंबाई 1 के सभी तारों को जोड़ना है (तो फिर बी तो सी)। फिर लंबाई प्रत्येक एन स्ट्रिंग के प्रत्येक स्ट्रिंग में वर्णमाला में प्रत्येक अक्षर संलग्न करें। जब तक आप लेक्सिकोग्राफिक रूप से अगली स्ट्रिंग पर जाने से पहले किसी दिए गए स्ट्रिंग में वर्णमाला में सभी अक्षरों को जोड़ते हैं, तब तक यह इसे बनाए रखेगा।

+1

यह समस्या उससे कहीं अधिक सरल है। 'Count' के लिए – agf

1

जहां तक ​​मुझे समझ में आया कि हमें आउटपुट स्ट्रिंग की अधिकतम लंबाई निर्दिष्ट नहीं करनी चाहिए। तो range पर्याप्त नहीं है:

>>> from itertools import combinations_with_replacement, count 
>>> def u(chars): 
...  for i in count(1): 
...   for k in combinations_with_replacement(chars, i): 
...    yield "".join(k) 
... 
>>> g = u("abc") 
>>> next(g) 
'a' 
>>> next(g) 
'b' 
>>> next(g) 
'c' 
>>> next(g) 
'aa' 
>>> next(g) 
'ab' 
>>> next(g) 
'ac' 
>>> next(g) 
'bb' 
>>> next(g) 
'bc' 
+0

+1। यह सही जवाब है। – Blender

+0

@ ब्लेंडर मुझे इस मामले में नहीं लगता कि पुनरावृत्त उत्तर सही समस्या को हल कर रहे हैं। – agf

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