19


7

たとえば、 "12345"という文字列があるとしましょう。この文字列のすべての部分列の組み合わせを取得する必要があります。

  1. - > 1 2 3 4 5

  2. - > 12 13 14 15 23 24 25 34 35 45

  3. - > 123 124 125 234 235 345

  4. - > 1234 1235 1245 1345 2345

  5. - > 12345

私はそれらを異なる数の文字にグループ化したが、それらの順序を変えなかったことに注意しなさい。 私はそれを行う方法/機能が必要です。

12 Answer


31


あなたはパワーセットが欲しいです。 powersetsまたはhttps://stackoverflow.com/search?q=%22power set%22 [power sets]に言及しているStackOverflowに関するすべての質問はここにあります。

これがpythonの基本的な実装です。

def powerset(s):
    n = len(s)
    masks = [1<

そして、これがその出力です。

[]
[1]
[2]
[1, 2]
[3]
[1, 3]
[2, 3]
[1, 2, 3]
[4]
[1, 4]
[2, 4]
[1, 2, 4]
[3, 4]
[1, 3, 4]
[2, 3, 4]
[1, 2, 3, 4]
[5]
[1, 5]
[2, 5]
[1, 2, 5]
[3, 5]
[1, 3, 5]
[2, 3, 5]
[1, 2, 3, 5]
[4, 5]
[1, 4, 5]
[2, 4, 5]
[1, 2, 4, 5]
[3, 4, 5]
[1, 3, 4, 5]
[2, 3, 4, 5]
[1, 2, 3, 4, 5]

最初の結果は空の集合です。 空のセットをスキップする場合は、反復をこの `+ for i in xrange(2 n):`からこの ` for i in xrange(1、2 n):+`に変更します。

これが文字列出力を生成するのに適したコードです:

def powerset(s):
    n = len(s)
    masks = [1<

'' '' '

編集2009-10-24

さて、私はあなたがJavaでの実装に偏っているのを見ます。 私はJavaがわからないので、途中でお会いし、C#でコードを提供します。

    static public IEnumerable> powerset(IList s)
    {
        int n = s.Count;
        int[] masks = new int[n];
        for (int i = 0; i < n; i++)
            masks[i] = (1 << i);
        for (int i = 0; i < (1 << n); i++)
        {
            List newList = new List(n);
            for (int j = 0; j < n; j++)
                if ((masks[j] & i) != 0)
                    newList.Add(s[j]);
            yield return newList;
        }
    }


11


サイズNのセットのサブセットを生成するための最も簡単なアルゴリズムは、Nビットを使用してすべての2進数を考慮することです。 番号内の各位置は、セットの要素を表します。 数値のビットが1の場合、対応する集合要素はサブセット内にあり、それ以外の場合、要素はサブセット内にありません。 数の中のビットは順序付けられているので、これは元の集合の順序付けを保存します。

参考文献:

  1. ";" 集合のサブセットを効率的に列挙する] ";ラフリー、ヘマート、スクーフ

  2. " Generating Subsets";ストーニーブルックアルゴリズムリポジトリ


11


以下のように再帰によってよりきれいなアプローチを達成することができます。

パブリッククラスStrManipulation {

public static voidの組み合わせ(文字列接尾辞、文字列接頭辞){if(prefix.length()<0)を返す。 System.out.println(サフィックス)。 (int i = 0; iの場合


9


Cでは、次のルーチンを与えます:

template bool next_combination(最初にconstイテレータ、最後にk、constイテレータ){/ *クレジット:Mark Nelson http://marknelson.us * / if((first == last)||(first == k)||( last == k))falseを返す。イテレータi1 =最初。イテレータi2 =最後。
   ++i1;
if(last == i1)がfalseを返す場合i1 =最後。 --i1; i1 = k。 --i2; while(first!= i1){if(*  -  i1 <* i2){イテレータj = k; while(!(* i1 <* j))j; std :: iter_swap(i1、j);
         ++i1;
         ++j;
i2 = k。 std :: rotate(i1、j、last); while(last!= j){
            ++j;
            ++i2;
} std :: rotate(k、i2、last); trueを返します。 std :: rotate(最初、k、最後); falseを返します。 }

その後、次のことを実行できます。

std :: string s = "12345"; for(std :: size_t i = 1; i <= s.size(); i){do {std :: cout << std :: string(s.begin()、s.begin()i)<< std :: endl; while(next_combination(s.begin()、s.begin()i、s.end())); }


8


pythonを使用して、itertoolsモジュールはあなたが必要とするだけのことをする組み合わせ()メソッドを定義します。

itertoolsインポート*リストから(組み合わせ( '12345'、2))

あなたを与えるでしょう:

[('1', '2'), ('1', '3'), ('1', '4'), ('1', '5'), ('2', '3'), ('2', '4'), ('2', '5'), ('3', '4'), ('3', '5'), ('4', '5')]


3


これには次のクラスを使用できます(Javaの場合)。

クラスの組み合わせ{

文字列入力StringBuilder cur;

プライベートvoid next(int pos、intリマインダー){cur.append(input.charAt(pos));

if(リマインダー== 1){System.out.println(cur); } else(for(int i = pos 1; iリマインダー-1 <= input.length(); i)next(i、リマインダー-1); cur.deleteCharAt(cur.length() -  1); }

public void generate(String input){cur = new StringBuilder(); this.input = input; for(int length = 1; length <= input.length(); length)for(int pos = 0; pos length <= input.length(); pos)next(pos、length); }}

例を実行するには、次のコードを使用してください。

新しい組み合わせ()を生成します( "12345")。

出力の順序は例と同じです。 すべてのサブセットを保存してから、並べ替えて説明した順序にする必要はありません。


2


入力文字列を引数として取り、outisの答えをJavaで実装。

import java.util.ArrayList; import java.util.List;

パブリッククラスCombo {

public static void main(String [] args){リストの結果= new ArrayList(); (int i = 1; i <=(1 <<(args.length)) -  1; i){StringBuilderビルダー= new StringBuilder(); for(int j = 0; j <args.length; j){if((i

これが実行です。

> javac Combo.java> javaコンボA B C
[A, B, AB, C, AC, BC, ABC]


1


文字列のすべての可能な組み合わせを生成するためのコードはjavaで与えられています。 長さ4の文字列のすべての可能な組み合わせは2 ^ 4(2の4乗)です。 一般に、長さnの文字列に対して可能な組み合わせは2 ^ n(2のn乗)です。 それ故にコード:

class Perms {public void permsOfString(String a){int x = 1;}

/ * 2 ^文字列長を計算する

* /

(int i = 0; iの場合


0


https://stackoverflow.com/questions/1617699/how-to-obtain-all-subsequence-combinations-of-a-string-in-java-or-c-etc/1617818#1617818 [Adrien Plissonの回答] Pythonで指定された長さのすべての部分列を取得します(任意の配列データ型の場合)。 OPは、彼が文字列を操作し、_all_サブシーケンスを望んでいることを指定します。 したがって、http://docs.python.org/3.1/library/itertools.html#itertools.combinations [+ itertools.combinations +]を使用して以下を定義します。

>>> from itertools import combinations
>>> def subseq_combos(inp):
...     return (''.join(s) for r in range(len(inp) + 1) for s in combinations(inp, r))
...
>>> list(subseq_combos('12345'))
['', '1', '2', '3', '4', '5', '12', '13', '14', '15', '23', '24', '25', '34', '35', '45', '123', '124', '125', '134', '135', '145', '234', '235', '245', '345', '1234', '1235', '1245', '1345', '2345', '12345']

(空のサブシーケンスを省略する必要がある場合は、 `+ range(1、len(inp)+ 1))+`を使用します。)


0


  • Cの実装*

//Usage
組み合わせ((char *) ""、(char *) "12346897909787");

voidの組み合わせ(char *サフィックス、char *プレフィックス){if(NULL ==プレフィックス|| NULL ==サフィックス){return;} int prefixLen = strlen(prefix); printf( "\ n [%s]"、サフィックス); int slen = strlen(サフィックス); char * s =(char *)malloc(slen 2); s [slen 1] = '\ 0'; (int i = 0; iの場合