How can find all permutations of spinning text in c#

佐手、 提交于 2019-12-11 14:00:05

问题


I have a spinning text : {T1{M1|{A1|B1}|M2}F1|{X1|X2}}

My question is : How can i find all permutations in C# ? T1M1F1 T1M2F1 T1A1F1 T1B1F1 X1 X2

Any suggestions ?

Edit : Thank you for your help but M1,A1, .. are examples

With words that could give : {my name is james vick and i am a {member|user|visitor} on this {forum|website|site} and i am loving it | i am admin and i am a {supervisor|admin|moderator} on this {forum|website|site} and i am loving it}.

my name is james vick and i am a {member|user|visitor} on this {forum|website|site} and i am loving it => 3 * 3 => 9 permutations

i am admin and i am a {supervisor|admin|moderator} on this {forum|website|site} and i am loving it => 3 * 3 => 9 permutations

Result : 18 permutations


回答1:


Method to generate all permuatuons of spinnable strings

I've implemented a simple method to solve this problem. It takes an ArrayList argument containing spinnable text string(s). I use it to generate all the permutations of multiple spinnable strings.

It comes with extra functionality of support of optional blocks, surronded by "[ ]" brackets.

Eq.: If you have a single string object in the ArrayList with content of: {A | {B1 | B2 } [B optional] }

It populates the array list with all the permutations, "extracted" Contents after invocation of method: A B1 B1 B optional B2 B2 B optional

You can also pass multiple strings as argument to generate permutations for all of them: Eg.: Input: ArraList with two string {A1 | A2} {B1 | B2} Contents after invocation: A1 A2 B1 B2

This implementation works by always finding the inner most bracket pair in the first spinnable section, then extract it. I do this until all the special {}, [] characters are removed.

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]);
        }
    }

I hope I've helped. Maybe it is not the simplest and best implementation, but it works well for me. Please feedback, and vote!




回答2:


In my opinion, you should proceed like this:

  1. All nested choice lists i.e. between { } should be "flattened" to a single choice list. Like in your example:

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

  2. Use recursion to generate all possible combinations. For example, starting from an empty array, first place T1 since it is the only option. Then from the nested list {M1|A1|B1|M2} choose each element in turn an place it on the next position and then finally F1. Repeat until all possibilities are exhausted.

This is just a rough hint, you need to fill in the rest of the details.



来源:https://stackoverflow.com/questions/8331020/how-can-find-all-permutations-of-spinning-text-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!