【问题标题】:Iterating through array elements when arrays are stored in a list in c#当数组存储在c#中的列表中时遍历数组元素
【发布时间】:2015-03-15 21:41:19
【问题描述】:

我有一个小难题。我正在编写一个小型应用程序,并且正处于它的最后阶段,并且无法决定解决此问题的最佳方法。

程序在文本框控件中从用户那里获取一个字符串。

它从那里迭代字符串中的每个字符:对于它拥有的每个字符,都有一个匹配的替换字符数组。这些数组被添加到list<string[]>

不过,我想从那里再次迭代以生成另一个列表,该列表将为用户输入创建替代词,收集所有可能的组合。

例如,使用任何可用字符,DAN 将变为 Dan、DaN、DAn、D@n 等。

此时程序仅支持 0-9 和 a-z(任何一种情况)。 我开始在类中声明/定义一些数组和列表:

    public List<String> passwordList = new List<String>();
    public List<string[]> arrayList = new List<string[]>();
    public int arrayListLength;


    public string[] zeroArray = {"0", "o", "O"}; //line for number 0
    public string[] oneArray = {"1", "!", "I", "i", "|"}; //line for number 1
    public string[] twoArray = {"2"}; //line for number 2
    public string[] threeArray = {"3"}; //line for number 3
    public string[] fourArray = {"4", "a", "A"}; //line for number 4
    public string[] fiveArray = {"5", "s", "S", "$"}; //line for number 5
    public string[] sixArray = {"6"}; //line for number 6
    public string[] sevenArray = {"7"}; //line for number 7
    public string[] eightArray = {"8"}; //line for number 8
    public string[] nineArray = {"9"}; //line for number 9

    public string[] aArray = {"a", "A", "4", "@"}; //line for letter a
    public string[] bArray = {"b", "B", "8"}; //line for letter b
    public string[] cArray = {"c", "C", "("};//line for letter c
    public string[] dArray = {"d", "D"}; //line for letter d
    public string[] eArray = {"e", "E"}; //line for letter e
    public string[] fArray = {"f", "F"}; //line for letter f
    public string[] gArray = {"g", "G"}; //line for letter g
    public string[] hArray = {"h", "H"}; //line for letter h
    public string[] iArray = {"i", "I", "!", "|"}; //line for letter i
    public string[] jArray = {"j", "J"}; //line for letter j
    public string[] kArray = {"k", "K"}; //line for letter k
    public string[] lArray = {"l", "L"}; //line for letter l
    public string[] mArray = {"m", "M"}; //line for letter m
    public string[] nArray ={"n", "N"}; //line for letter n
    public string[] oArray = {"o", "O", "0"}; //line for letter o
    public string[] pArray = {"p", "P"}; //line for letter p
    public string[] qArray = {"q", "Q"}; //line for letter q
    public string[] rArray = {"r", "R"}; //line for letter r
    public string[] sArray = {"s", "S", "5", "$"}; //line for letter s
    public string[] tArray = {"t", "T", "+"}; //line for letter t
    public string[] uArray = {"u", "U"}; //line for letter u
    public string[] vArray = {"v", "V"}; //line for letter v
    public string[] wArray = {"w", "W"}; //line for letter w
    public string[] xArray = {"x", "X"}; //line for letter x
    public string[] yArray = {"y", "Y"}; //line for letter y
    public string[] zArray = {"z", "Z"}; //line for letter z

稍后,当迭代时,循环看起来像这样:

 String generateFrom = txtGenerateFrom.Text;

        foreach (char c in generateFrom)
            if (c.ToString() == "0")
                arrayList.Add(zeroArray);
            else if (c.ToString() == "1")
                arrayList.Add(oneArray);
            else if (c.ToString() == "2")
                arrayList.Add(twoArray);
            else if (c.ToString() == "3")
                arrayList.Add(threeArray);
            else if (c.ToString() == "4")
                arrayList.Add(fourArray);
            else if (c.ToString() == "5")
                arrayList.Add(fiveArray);
            else if (c.ToString() == "6")
                arrayList.Add(sixArray);
            else if (c.ToString() == "7")
                arrayList.Add(sevenArray);
            else if (c.ToString() == "8")
                arrayList.Add(eightArray);
            else if (c.ToString() == "9")
                arrayList.Add(nineArray);
            else if (c.ToString() == "a" || c.ToString() == "A")
                arrayList.Add(aArray);
            else if (c.ToString() == "b" || c.ToString() == "B")
                arrayList.Add(bArray);
            else if (c.ToString() == "c" || c.ToString() == "C")
                arrayList.Add(cArray);

这为我提供了一个列表 (public List&lt;string[]&gt; arrayList = new List&lt;string[]&gt;();//declared at beginning),其中包含相关数组,并且这些数组按照与用户输入相关的位置排列。

那么循环这个列表以生成我的字符串并将它们添加到可以替换的单词列表中的最佳方法是什么?

【问题讨论】:

  • 首先,我会强烈建议您使用大括号,即使您并不严格需要。为了便于阅读,我肯定会在 foreach 循环的主体周围放置大括号。接下来,我不清楚这些数字是从哪里来的——如果你能给出一个完整的例子,那真的很有帮助,因为到目前为止你给出的部分例子并没有真正清楚地描述 IMO 的问题。
  • @JonSkeet,给我一点时间,我会做一些修改
  • 我希望这些编辑让它更有意义。如果它首先命中字符 t 或 T 字符,它会将 tArray 数组添加到 arrayList 列表中,以便稍后我知道 't' 替换字符首先属于新单词。
  • 听起来你想要一个 Dictionary&lt;char, string[]&gt;Dictionary&lt;string, string[]&gt; 然后......我不会有所有这些单独的变量。
  • 访问数组中的元素在字典中的工作方式是否相同?

标签: c# arrays loops


【解决方案1】:

试试这个课程:

public static class PasswordGenerator
{
    private static readonly IReadOnlyDictionary<char, char[]> Substitutions = new Dictionary<char, char[]> {
        {'0', new[] {'0', 'o', 'O'}},
        {'1', new[] {'1', '!', 'I', 'i', '|'}},
        {'2', new[] {'2'}},
        {'3', new[] {'3'}},
        {'4', new[] {'4', 'a', 'A'}},
        {'5', new[] {'5', 's', 'S', '$'}},
        {'6', new[] {'6'}},
        {'7', new[] {'7'}},
        {'8', new[] {'8'}},
        {'9', new[] {'9'}},
        {'a', new[] {'a', 'A', '4', '@'}},
        {'b', new[] {'b', 'B', '8'}},
        {'c', new[] {'c', 'C', '('}},
        {'d', new[] {'d', 'D'}},
        {'e', new[] {'e', 'E'}},
        {'f', new[] {'f', 'F'}},
        {'g', new[] {'g', 'G'}},
        {'h', new[] {'h', 'H'}},
        {'i', new[] {'i', 'I', '!', '|'}},
        {'j', new[] {'j', 'J'}},
        {'k', new[] {'k', 'K'}},
        {'l', new[] {'l', 'L'}},
        {'m', new[] {'m', 'M'}},
        {'n', new[] {'n', 'N'}},
        {'o', new[] {'o', 'O', '0'}},
        {'p', new[] {'p', 'P'}},
        {'q', new[] {'q', 'Q'}},
        {'r', new[] {'r', 'R'}},
        {'s', new[] {'s', 'S', '5', '$'}},
        {'t', new[] {'t', 'T', '+'}},
        {'u', new[] {'u', 'U'}},
        {'v', new[] {'v', 'V'}},
        {'w', new[] {'w', 'W'}},
        {'x', new[] {'x', 'X'}},
        {'y', new[] {'y', 'Y'}},
        {'z', new[] {'z', 'Z'}}
    };

    public static IEnumerable<string> GenerateFor(string value)
    {
        if (value == null)
            throw new ArgumentNullException("value");
        return GenerateFor(value, value.ToCharArray());
    }

    private static IEnumerable<string> GenerateFor(string src, char[] value, int index = 0)
    {
        if (index < value.Length)
        {
            char[] chars;
            while (!Substitutions.TryGetValue(char.ToLowerInvariant(src[index]), out chars))
                if (++index == src.Length)
                {
                    yield return new string(value);
                    yield break;
                }

            foreach (var c in chars)
            {
                value[index] = c;
                foreach (var nextValue in GenerateFor(src, value, index + 1))
                    yield return nextValue;
            }
        }
        else
            yield return new string(value);
    }
}
  • 该类使用查找字典生成输入字符串的所有可能变体;
  • 所有未指定的字符都作为单次替换字符处理;
  • 对于任何输入字符串,生成器返回至少一个字符串(输入字符串的副本),如果存在任何替换,则返回更多字符串;

你可以这样使用它:

foreach (var password in PasswordGenerator.GenerateFor("DAN"))
    Console.WriteLine(password);

这段代码输出:

dan
daN
dAn
dAN
d4n
d4N
d@n
d@N
Dan
DaN
DAn
DAN
D4n
D4N
D@n
D@N

【讨论】:

  • 哇。绝对是我想要的。我做了一个小改动,不是将当前版本打印到屏幕上,而是将其添加到字符串列表中,然后将其转储到文件中
  • “绝对是我想要的” - 这意味着您可以将此答案标记为最佳,好吗?
【解决方案2】:

我认为这会做你想要的。首先将数组声明替换为Dictionary

public static Dictionary<char, char[]> replacementLookup = new Dictionary<char, char[]>()
        {
                { '0', new char[] { 'o', 'O' } }, 
                { '1', new char[] { '!', 'I', 'i', '|' } }, 
                { '4', new char[] { 'a', 'A' } }
                // Rest of data...
        };

然后您可以遍历您的输入(使用Distinct 以避免重复)并使用LINQ Select 来获取每个替换字符的字符串列表:

var result = new List<string>();

foreach (var c in input.Distinct().Where(x => replacementLookup.ContainsKey(x)))
{
    result.AddRange(replacementLookup[c].Select(replacement => input.Replace(c, replacement)));
}

【讨论】:

  • 我明白你在这里得到了什么。我会玩一会儿这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
  • 2021-08-12
  • 1970-01-01
  • 2013-04-11
  • 2013-06-23
  • 2019-07-19
  • 2022-01-10
相关资源
最近更新 更多