Как можно найти все перестановки вращающегося текста в C # - PullRequest
1 голос
/ 30 ноября 2011

У меня есть вращающийся текст: {T1 {M1 | {A1 | B1} | M2} F1 | {X1 | X2}}

Мой вопрос: как мне найти все перестановки в C #? T1M1F1 T1M2F1 T1A1F1 T1B1F1 X1 X2

Есть предложения?

Редактировать: Спасибо за вашу помощь, но M1, A1, .. являются примерами

Со словами, которые могли бы дать: {меня зовут Джеймс Вик, и я {член | пользователь | посетитель} на этом {форуме | веб-сайте | сайте}, и мне это нравится | я являюсь администратором и являюсь {руководителем | администратором | модератором} на этом {форуме | веб-сайте | сайте}, и мне это нравится}.

меня зовут Джеймс Вик, и я {член | пользователь | посетитель} на этом {форуме | веб-сайте | сайте}, и мне это нравится => 3 * 3 => 9 перестановок

Я - администратор, и я {supervisor | admin | модератор} на этом {форуме | веб-сайте | сайте}, и мне это нравится => 3 * 3 => 9 перестановок

Результат: 18 перестановок

Ответы [ 2 ]

1 голос
/ 07 октября 2012

Метод создания всех перестановок прядомых струн

Я реализовал простой метод для решения этой проблемы. Он принимает аргумент ArrayList, содержащий вращающиеся текстовые строки. Я использую его для генерации всех перестановок нескольких прядомых строк.

Он поставляется с дополнительной функциональностью поддержки дополнительных блоков, заключенных в скобки "[]".

Eq .: Если у вас есть один строковый объект в ArrayList с содержимым: {A | {B1 | B2} [B необязательно]}

Заполняет список массивов всеми перестановками, «извлеченными». Содержание после вызова метода: B1 B1 B опционально Би 2 B2 B опционально

Вы также можете передать несколько строк в качестве аргумента для генерации перестановок для всех из них: Например.: Входные данные: ArraList с двумя строками {A1 | A2} {B1 | БИ 2} Содержание после вызова: 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]);
        }
    }

Надеюсь, я помог. Возможно, это не самая простая и лучшая реализация, но она хорошо работает для меня. Пожалуйста, оставьте отзыв и проголосуйте!

0 голосов
/ 30 ноября 2011

На мой взгляд, вы должны поступить так:

  1. Все вложенные списки выбора, то есть между {}, должны быть "сведены" к одному списку выбора. Как в вашем примере:

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

  2. Используйте рекурсию для генерации всех возможных комбинаций. Например, начиная с пустого массива, сначала ставьте T1, поскольку это единственный вариант. Затем из вложенного списка {M1 | A1 | B1 | M2} выберите каждый элемент по очереди, поместите его на следующую позицию и затем, наконец, F1. Повторяйте, пока все возможности не будут исчерпаны.

Это всего лишь грубый намек, вам нужно заполнить остальные детали.

...