1

我有一个旋转文本:{T1{M1|{A1|B1}|M2}F1|{X1|X2}}

我的问题是:如何在 C# 中找到所有排列?T1M1F1 T1M2F1 T1A1F1 T1B1F1 X1 X2

有什么建议么 ?

编辑:感谢您的帮助,但 M1、A1、.. 是示例

用可以给出的话: {我的名字是詹姆斯维克,我是这个{论坛|网站|网站}的{会员|用户|访问者},我很喜欢它| 我是管理员,我是这个{论坛|网站|网站}的{主管|管理员|版主},我很喜欢它}。

我的名字是詹姆斯维克,我是这个{论坛|网站|网站}的{会员|用户|访问者},我很喜欢它=> 3 * 3 => 9 个排列

我是管理员,我是这个{论坛|网站|网站}的{主管|管理员|版主},我很喜欢它=> 3 * 3 => 9 个排列

结果:18 个排列

4

2 回答 2

1

生成可旋转字符串的所有排列的方法

我已经实现了一个简单的方法来解决这个问题。它接受一个包含可旋转文本字符串的 ArrayList 参数。我用它来生成多个可旋转字符串的所有排列。

它带有支持可选块的额外功能,由“[]”括号括起来。

等式:如果 ArrayList 中有一个字符串对象,其内容为:{A | {B1 | B2 } [B 可选] }

它使用所有排列填充数组列表,在调用方法后“提取”内容:A B1 B1 B 可选 B2 B2 B 可选

您还可以传递多个字符串作为参数来为所有这些字符串生成排列:例如:输入:带有两个字符串的 ArraList {A1 | A2} {B1 | B2} 调用后的内容:A1 A2 B1 B2

此实现的工作原理是始终在第一个可旋转部分中找到最里面的括号对,然后将其提取出来。我这样做直到所有特殊的 {}、[] 字符都被删除。

private void ExtractVersions(ArrayList list)
    {
        ArrayList IndicesToRemove = new ArrayList();

        for (int i = 0; i < list.Count; i++)
        {
            string s = list[i].ToString();
            int firstIndexOfCurlyClosing = s.IndexOf('}');
            int firstIndexOfBracketClosing = s.IndexOf(']');

            if ((firstIndexOfCurlyClosing > -1) || (firstIndexOfBracketClosing > -1))
            {

                char type = ' ';
                int endi = -1;
                int starti = -1;

                if ((firstIndexOfBracketClosing == -1) && (firstIndexOfCurlyClosing > -1))
                { // Only Curly
                    endi = firstIndexOfCurlyClosing;
                    type = '{';
                }
                else
                {
                    if ((firstIndexOfBracketClosing > -1) && (firstIndexOfCurlyClosing == -1))
                    { // Only bracket
                        endi = firstIndexOfBracketClosing;
                        type = '[';
                    }
                    else
                    {
                        // Both
                        endi = Math.Min(firstIndexOfBracketClosing, firstIndexOfCurlyClosing);
                        type = s[endi];

                        if (type == ']')
                        {
                            type = '[';
                        }
                        else
                        {
                            type = '{';
                        }
                    }
                }

                starti = s.Substring(0, endi).LastIndexOf(type);

                if (starti == -1)
                {
                    throw new Exception("Brackets are not valid.");
                }
                // start index, end index and type found. -> make changes
                if (type == '[')
                {
                    // Add two new lines, one with the optional part, one without it
                    list.Add(s.Remove(starti, endi - starti+1));
                    list.Add(s.Remove(starti, 1).Remove(endi-1, 1));
                    IndicesToRemove.Add(i);
                }
                else
                    if (type == '{')
                    {
                        // Add as many new lines as many alternatives there are. This must be an in most bracket.
                        string alternatives = s.Substring(starti + 1, endi - starti - 1);
                        foreach(string alt in alternatives.Split('|'))
                        {
                            list.Add(s.Remove(starti,endi-starti+1).Insert(starti,alt));
                        }
                        IndicesToRemove.Add(i);
                    }
            } // End of if( >-1 && >-1)
        } // End of for loop

        for (int i = IndicesToRemove.Count-1; i >= 0; i--)
        {
            list.RemoveAt((int)IndicesToRemove[i]);
        }
    }

我希望我有所帮助。也许这不是最简单和最好的实现,但对我来说效果很好。请反馈,并投票!

于 2012-10-07T17:08:12.950 回答
0

在我看来,你应该这样进行:

  1. 所有嵌套的选择列表,即 { } 之间的列表都应该“展平”为单个选择列表。就像在您的示例中一样:

    {M1|{A1|B1}|M2} -> {M1|A1|B1|M2}

  2. 使用递归生成所有可能的组合。例如,从一个空数组开始,首先放置 T1,因为它是唯一的选项。然后从嵌套列表 {M1|A1|B1|M2} 中依次选择每个元素并将其放置在下一个位置,最后是 F1。重复,直到用尽所有可能性。

这只是一个粗略的提示,您需要填写其余的详细信息。

于 2011-11-30T18:45:48.170 回答