5

これに「似ている」他のいくつかのSOの質問(およびグーグルで検索したトン)を見てきましたが、どれも私の質問に正しく適合していないようです。

指定した文字列内の文字のみを含む、固定長ではない一意のテキスト文字列を作成しようとしています。たとえば、大文字と小文字の a-zA-Z 文字で構成されます。(この例では、a、b、および c の小文字のみを使用します)

このようなもの(以下の壊れたコード)

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

index 引数は、テキスト文字列に関連するインデックス (整数) です。たとえば、次のようになります。

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-Z 文字のみを使用できます
  2. できるだけ短く、インデックス番号が小さいほど短くなります (上記の例を参照)。
  3. 指定された引数文字列で指定された文字のみを含む

結論として、整数のインデックス値を、指定された文字を含む一意の短い文字列に関連付ける next() 関数をどのように記述すればよいでしょうか?

PS 私は SO の初心者です。このサイトは何年にもわたって私を大いに助けてくれました。アカ​​ウントを作成したり、質問したりしたことはありませんが (今まで)、自分のことをうまく説明できていることを本当に願っています。これで達成しようとしています。

4

6 に答える 6

3

あなたがしようとしているのは、next関数のパラメーターを別のベースに書き込むことです。

validCharactersに文字が含まれているとします。関数kの仕事は、の文字を使用してパラメータをベースnextに変換することです。pkvalidCharacters

あなたの例では、基数 3 で数字を書き、各数字を 1 つの文字に関連付けることができます。

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

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

などなど。

このメソッドを使用すると、反復メソッドでは実行できない を知らずに、next(x)または計算せずに呼び出すことができます。next(x-i)

于 2012-10-25T06:36:50.680 に答える
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'
于 2012-10-25T06:44:27.633 に答える
1

itertools難読化されたワンライナーイテレータを常に提供できます。

from itertools import combinations_with_replacement, chain

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

chars基本的に、このコードは長さ1, 2, ...,のすべての組み合わせを結合する反復子を作成しますlen(chars)

の出力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')
于 2012-10-25T06:35:27.923 に答える
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']
于 2012-10-25T06:35:37.330 に答える
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)

これにより、任意の位置にジャンプできます。カウントしているため、識別子は完全に一意であり、任意の長さ (2 つ以上) の任意の文字セットを簡単に使用でき、数字が小さいほど識別子が短くなります。

于 2012-10-25T06:45:43.850 に答える
0

したがって、言語 {'a','b','c'} によって生成されたすべての文字列を列挙しようとしているようです。これは、有限状態オートマトンを使用して行うことができます (ただし、そうしたくありません)。言語を列挙する簡単な方法の 1 つは、リストから始めて、長さ 1 のすべての文字列を順番に追加することです (つまり、a の次に b の次に c)。次に、アルファベットの各文字を長さ n-1 の各文字列に追加します。これにより、辞書順で次の文字列に移動する前に、アルファベットのすべての文字を特定の文字列に追加する限り、順序が維持されます。

于 2012-10-25T06:37:17.530 に答える