2016-05-11 2 views
1

私は(サンプルデータは、このように、それは意味がありません)このような辞書を持っている:反復処理非正方形(一種の)行列

Dictionary<char, string[]> codes = new Dictionary<char, string[]>(); 

string[]辞書のキーのための可能な代替の配列です。いくつかのサンプルデータと辞書を埋める

...

codes.Add("A", new string[] {"噅噅", "裧", "頖", "11"}); 
codes.Add("B", new string[] {"垥", "2", "鉠"}); 
codes.Add("C", new string[] {"33", "韎"}); 
codes.Add("D", new string[] {"櫋", "緟", "嘕", "鈖", "灡", "犅"}); 
... 
codes.Add("T", new string[] {"濇", "汫", "岕", "5"}); 
... 

は今、「エンコード」次の単語ができます:

char[] charArray = "act".ToCharArray(); 
    foreach (char c in charArray) { 
     string[] replacements = codes[c].Where(x => !String.IsNullOrEmpty(x)).ToArray();//removing empty elements 

     ... 
    } 

を私は、次の何をすべきかについて、今、私の頭をラップすることはできません私はすべての可能な組み合わせのリストを持つようにしたい、それが(ワード「行為」のために)このようなリストを返す必要があります。

噅噅韎5

裧33濇

裧33汫

裧33岕

裧335

裧韎濇

裧韎汫

裧韎岕

...

は、記事のタイトルは誤解を招くおそれがあり...

+0

これは、再帰によってかなり簡単に解決されます。 – dharms

+0

@興味があります。どこで再帰的メソッドを呼び出すべきですか?各 "キー"について? – Cornwell

+0

2つの文字列を渡します。エンコードしたいものと現在のブランチのエンコードされた文字列を渡します。最初の呼び出しは 'Encode(" act "、" ");' – dharms

答えて

1

を理由にStackOverflowのスパムフィルタのすべての組み合わせを表示することはできません。正しく理解すれば、codesを入力文字の置き換えとして使用して、すべての組み合わせを生成する必要があります。

私は私が直接Looking at each combination in jagged arrayから便利なコードを再利用することはできませんが原因string[]部分に、同様の質問(String combinations with multi-character replacement)を回答しているので、代わりに私はちょうどあなたのケースのために同じアルゴリズムを利用します:

public static class Algorithms 
{ 
    public static IEnumerable<string> GetCombinations(this string input, Dictionary<char, string[]> replacements) 
    { 
     var map = new string[input.Length][]; 
     for (int i = 0; i < map.Length; i++) 
     { 
      var c = input[i]; 
      string[] r; 
      map[i] = replacements.TryGetValue(c, out r) 
       && (r = r.Where(s => !string.IsNullOrEmpty(s)).ToArray()).Length > 0 ? 
       r : new string[] { c.ToString() }; 
     } 
     int maxLength = map.Sum(output => output.Max(s => s.Length)); 
     var buffer = new char[maxLength]; 
     int length = 0; 
     var indices = new int[input.Length]; 
     for (int pos = 0, index = 0; ;) 
     { 
      for (; pos < input.Length; pos++, index = 0) 
      { 
       indices[pos] = index; 
       foreach (var c in map[pos][index]) 
        buffer[length++] = c; 
      } 
      yield return new string(buffer, 0, length); 
      do 
      { 
       if (pos == 0) yield break; 
       index = indices[--pos]; 
       length -= map[pos][index].Length; 
      } 
      while (++index >= map[pos].Length); 
     } 
    } 
} 

をテスト:

var codes = new Dictionary<char, string[]>(); 
codes.Add('A', new string[] { "噅噅", "裧", "頖", "11" }); 
codes.Add('B', new string[] { "垥", "2", "鉠" }); 
codes.Add('C', new string[] { "33", "韎" }); 
codes.Add('D', new string[] { "櫋", "緟", "嘕", "鈖", "灡", "犅" }); 
//... 
codes.Add('T', new string[] { "濇", "汫", "岕", "5" }); 
//... 

var test = "ACT".GetCombinations(codes).ToList(); 
1

次のコードは、フォーム上のボタンのクリックイベントにimplemened直感的な再帰的なアプローチ(で簡単に刺しを示して - 私はあなたがそれイラストではなく、soluti検討すべき提案します)...

private void button3_Click(object sender, EventArgs e) 
    { 
     test.Text = "act"; 
     Encoding encoder = new Encoding(); 
     foreach (string encoding in encoder.EncodedStrings(test.Text)) 
     { 
      output.AppendText(encoding + "\n"); 
     } 
    } 

    public class Encoding 
    { 
     public readonly Dictionary<char, string[]> codes = new Dictionary<char, string[]>(); 

     public Encoding() 
     { 
      codes.Add('A', new string[] {"a ", "A ", "a1 ", "A1 "}); 
      codes.Add('B', new string[] {"b ", "B ", "b1 ", "B1 "}); 
      codes.Add('C', new string[] {"c ", "C ", "c1 ", "C1 "}); 
      codes.Add('D', new string[] {"d ", "D ", "d1 ", "D1 "}); 
      codes.Add('T', new string[] {"t ", "T ", "t1 ", "T1 "}); 
     } 

     public List<string> EncodedStrings(string input) 
     { 
      var results = new List<string>(); 

      if (string.IsNullOrWhiteSpace(input)) 
      { 
       results.Add(string.Empty); 
       return results; 
      } 

      // Find the set of replacements for the first character: 
      char  firstChar = input[0]; 
      string[] replacements = this.codes[firstChar.ToString().ToUpperInvariant()[0]]; 

      foreach (string replacement in replacements) 
      { 
       string thisVersion  = replacement; 
       string remainder   = input.Length > 1 ? input.Substring(1) : string.Empty; 
       var remainderVersions = new List<string>(); 

       // Get the various versions of the remainder of the string: 
       remainderVersions.AddRange(EncodedStrings(remainder)); 

       foreach (string remainderVersion in remainderVersions) 
       { 
        results.Add(string.Format("{0}{1}", thisVersion, remainderVersion)); 
       } 
      } 

      return results; 
     } 
    } 

私は簡単なエンコーディングを含んでいますので、結果を読みやすくなりました。これにより、次のリストが生成されます。

a c t 
a c T 
a c t1 
a c T1 
a C t 
a C T 
a C t1 
a C T1 
a c1 t 
a c1 T 
a c1 t1 
a c1 T1 
a C1 t 
a C1 T 
a C1 t1 
a C1 T1 
A c t 
A c T 
A c t1 
A c T1 
A C t 
A C T 
A C t1 
A C T1 
A c1 t 
A c1 T 
A c1 t1 
A c1 T1 
A C1 t 
A C1 T 
A C1 t1 
A C1 T1 
a1 c t 
a1 c T 
a1 c t1 
a1 c T1 
a1 C t 
a1 C T 
a1 C t1 
a1 C T1 
a1 c1 t 
a1 c1 T 
a1 c1 t1 
a1 c1 T1 
a1 C1 t 
a1 C1 T 
a1 C1 t1 
a1 C1 T1 
A1 c t 
A1 c T 
A1 c t1 
A1 c T1 
A1 C t 
A1 C T 
A1 C t1 
A1 C T1 
A1 c1 t 
A1 c1 T 
A1 c1 t1 
A1 c1 T1 
A1 C1 t 
A1 C1 T 
A1 C1 t1 
A1 C1 T1