迭代非正方形(种类)矩阵

时间:2016-05-11 18:31:15

标签: c# algorithm

我有一个这样的字典(样本数据,因此它没有意义):

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"});
...

现在让&#34;编码&#34;以下字样:

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

       ...
    }

我现在无法理解下一步该做什么,我想要列出所有可能的组合,它应该返回一个这样的列表(对于单词&#34; act&#34;):

  

噅噅韎5

     

裧33濇

     

裧33汫

     

裧33岕

     

裧335

     

裧韎濇

     

裧韎汫

     

裧韎岕

     

...

由于stackoverflow的垃圾邮件过滤器无法显示所有组合...

2 个答案:

答案 0 :(得分:1)

帖子标题具有误导性。如果我理解正确,您希望使用codes作为输入字符替换生成所有组合。

我已经回答了类似的问题(String combinations with multi-character replacement),但是由于string[]部分我不能直接重用Looking at each combination in jagged array中的方便代码,所以我只会使用相同的算法对于你的情况:

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 :(得分:1)

下面的代码显示了对直观递归方法的快速刺激(在表单上的按钮点击事件中实现 - 我建议您应该将其视为插图而不是直接适用于复制的解决方案!)...

    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