Сгенерировать все возможные комбинации из строкового массива без повторения - PullRequest
0 голосов
/ 09 мая 2020

Я хочу сравнить каждый элемент массива строк с другими элементами, кроме самого себя, результатом будет символьная строка, разделенная этим -->, вторая часть результата будет элементом, а первая часть будет 1 или больше символьных строк, разделенных ,

для примера vect [a1, a2, a3] Out put:

a2-->a1
a3-->a1
a2,a3 -->a1

a1-->a2
a3-->a2
a1,a3 -->a2

a1-->a3
a2-->a3
a1,a2-->a3

Я пробую этот код

    public static void main(String[] args) {

        String vect[] = { "a1", "a2", "a3" };
        int n = 3;
        String attribut;

        int i = 0, j = 0, k = 0;
        for (i = 0; i < n; i++) {
            attribut = vect[i];
            for (j = 0; j < n; j++) {
                if (!attribut.equals(vect[j])) {
                    System.out.println(vect[j] + "-->" + attribut);

                }
            }
            for (j = 0; j < n; j++) {

                for (k = j + 1; k < n; k++) {
                    if ((!attribut.equals(vect[j])) && (!attribut.equals(vect[k]))) {
                        System.out.println(vect[j] + "," + vect[k] + "-->" + attribut);

                    }
                }

            }
        }
    }

код возвращает результат, но я не знаю, как это сделать, если у меня есть массив, например, с 5 строками символов для примера vect [a1, a2, a3, a4] out, поместите

a2-->a1
a3-->a1
a4-->a1
a2,a3 -->a1
a2,a4 -->a1
a3,a4-->a1
a2,a3,a4 -->a1
....

в этом случае количество запятых перед -> увеличивается до 4.

1 Ответ

0 голосов
/ 09 мая 2020

Используя битовые манипуляции, мы можем легко перебирать все комбинации строк из массива строк.

Например, если у нас есть 3 строки ("a1", "a2", "a3") , мы будем повторять от 1 до 7 (2³-1). В двоичном представлении этого числа каждый бит справа указывает, включена ли эта входная строка в результат. идет справа от -->. Назовем это значением результат .

Например, если мы сейчас генерируем результат для "a2" (индекс результата 1), мы «вытаскиваем» его из пула битов. , так что теперь у нас есть только 2 бита. Любой бит в индексе результата или после него представляет индекс значения, на единицу превышающий битовый индекс.

Это означает, что бит 0 является индексом значения 0, а бит 1 - индексом значения 2.

01    "a1"
10    "a3"
11    "a1", "a3"

Теперь мы можем написать код следующим образом:

static void printCombinations(String... values) {
    if (values.length < 2 || values.length > 30)
        throw new IllegalArgumentException("There must be between 2 and 30 values (got " + values.length + ")");
    if (values.length != new HashSet<>(Arrays.asList(values)).size())
        throw new IllegalArgumentException("Duplicate values not allowed");

    final int maxBit = values.length - 1;
    final int maxMask = 1 << maxBit;
    StringBuilder buf = new StringBuilder();
    for (int resIdx = 0; resIdx < values.length; resIdx++) {
        for (int bitMask = 1; bitMask < maxMask; bitMask++) {
            buf.setLength(0);
            for (int bitIdx = 0; bitIdx < maxBit; bitIdx++)
                if ((bitMask & (1 << bitIdx)) != 0)
                    buf.append(',').append(values[bitIdx >= resIdx ? bitIdx + 1 : bitIdx]);
            System.out.println(buf.append("-->").append(values[resIdx]).substring(1));
        }
    }
}

Тест

printCombinations("a1", "a2", "a3", "a4");

Вывод

a2-->a1
a3-->a1
a2,a3-->a1
a4-->a1
a2,a4-->a1
a3,a4-->a1
a2,a3,a4-->a1
a1-->a2
a3-->a2
a1,a3-->a2
a4-->a2
a1,a4-->a2
a3,a4-->a2
a1,a3,a4-->a2
a1-->a3
a2-->a3
a1,a2-->a3
a4-->a3
a1,a4-->a3
a2,a4-->a3
a1,a2,a4-->a3
a1-->a4
a2-->a4
a1,a2-->a4
a3-->a4
a1,a3-->a4
a2,a3-->a4
a1,a2,a3-->a4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...