Создание пары для векторов и хэш-сигналов [дубликат]

Существует множество решений, таких как font-size:0, word-spacing, margin-left, letter-spacing и т. д.

Обычно я предпочитаю использовать letter-spacing, потому что

  1. кажется, что если мы присваиваем значение, большее ширины дополнительного пространства (например, -1em).
  2. Однако с word-spacing и margin-left это будет нехорошо, когда мы устанавливаем большее значение, например -1em.
  3. Использование font-size неудобно, когда мы пытаемся использовать em как font-size.

So , letter-spacing кажется лучшим выбором.

Однако, я должен предупредить вас

, когда вы используете letter-spacing, вам лучше использовать -0.3em или -0.31em not другие.

* {
  margin: 0;
  padding: 0;
}
a {
  text-decoration: none;
  color: inherit;
  cursor: auto;
}
.nav {
  width: 260px;
  height: 100px;
  background-color: pink;
  color: white;
  font-size: 20px;
  letter-spacing: -1em;
}
.nav__text {
  width: 90px;
  height: 40px;
  box-sizing: border-box;
  border: 1px solid black;
  line-height: 40px;
  background-color: yellowgreen;
  text-align: center;
  display: inline-block;
  letter-spacing: normal;
}

Если вы используете Chrome (тестовая версия 66.0.3359.139) или Opera (тестовая версия 53.0.2907.99) , вы можете увидеть:

Если вы используете Firefox (60.0.2), IE10 или Edge, то, что вы видите, может быть:

Это интересно. Итак, я проверил mdn-letter-spacing и нашел это:

length

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

Похоже, что это и есть причина.

33
задан Daniel Fischer 19 June 2013 в 14:45
поделиться

10 ответов

Вам нужна рекурсия:

Предположим, что все ваши списки находятся в Lists, который является списком списков. Пусть Result будет списком ваших необходимых перестановок: сделайте это так

void GeneratePermutations(List<List<Character>> Lists, List<String> result, int depth, String current)
{
    if(depth == Lists.size())
    {
       result.add(current);
       return;
     }

    for(int i = 0; i < Lists.get(depth).size(); ++i)
    {
        GeneratePermutations(Lists, result, depth + 1, current + Lists.get(depth).get(i));
    }
}

Конечный вызов будет таким, как это

GeneratePermutations(Lists, Result, 0, EmptyString);
44
ответ дан user54595 25 August 2018 в 23:47
поделиться

Добавление ответа, основанного на итераторе, для работы с общим списком списков List<List<T>>, расширяющим идею от ответа Руслана Остафичука. Идея, которой я следовала, была:

     * List 1: [1 2]
     * List 2: [4 5]
     * List 3: [6 7]
     * 
     * Take each element from list 1 and put each element 
     * in a separate list.
     * combinations -> [ [1] [2] ]
     * 
     * Set up something called newCombinations that will contains a list
     * of list of integers
     * Consider [1], then [2]
     * 
     * Now, take the next list [4 5] and iterate over integers
     * [1]
     *  add 4   -> [1 4]
     *      add to newCombinations -> [ [1 4] ]
     *  add 5   -> [1 5]
     *      add to newCombinations -> [ [1 4] [1 5] ]
     * 
     * [2]
     *  add 4   -> [2 4]
     *      add to newCombinations -> [ [1 4] [1 5] [2 4] ]
     *  add 5   -> [2 5]
     *      add to newCombinations -> [ [1 4] [1 5] [2 4] [2 5] ]
     * 
     * point combinations to newCombinations
     * combinations now looks like -> [ [1 4] [1 5] [2 4] [2 5] ]
     * Now, take the next list [6 7] and iterate over integers
     *  ....
     *  6 will go into each of the lists
     *      [ [1 4 6] [1 5 6] [2 4 6] [2 5 6] ]
     *  7 will go into each of the lists
     *      [ [1 4 6] [1 5 6] [2 4 6] [2 5 6] [1 4 7] [1 5 7] [2 4 7] [2 5 7]]

Теперь код. Я использовал Set, чтобы избавиться от любых дубликатов. Может быть заменен на List. Все должно работать без проблем. :)

public static <T> Set<List<T>> getCombinations(List<List<T>> lists) {
    Set<List<T>> combinations = new HashSet<List<T>>();
    Set<List<T>> newCombinations;

    int index = 0;

    // extract each of the integers in the first list
    // and add each to ints as a new list
    for(T i: lists.get(0)) {
        List<T> newList = new ArrayList<T>();
        newList.add(i);
        combinations.add(newList);
    }
    index++;
    while(index < lists.size()) {
        List<T> nextList = lists.get(index);
        newCombinations = new HashSet<List<T>>();
        for(List<T> first: combinations) {
            for(T second: nextList) {
                List<T> newList = new ArrayList<T>();
                newList.addAll(first);
                newList.add(second);
                newCombinations.add(newList);
            }
        }
        combinations = newCombinations;

        index++;
    }

    return combinations;
}

Небольшой тестовый блок.

public static void main(String[] args) {
    List<Integer> l1 = Arrays.asList(1,2,3);
    List<Integer> l2 = Arrays.asList(4,5);
    List<Integer> l3 = Arrays.asList(6,7);

    List<List<Integer>> lists = new ArrayList<List<Integer>>();
    lists.add(l1);
    lists.add(l2);
    lists.add(l3);

    Set<List<Integer>> combs = getCombinations(lists);
    for(List<Integer> list : combs) {
        System.out.println(list.toString());
    }

}
5
ответ дан Debosmit Ray 25 August 2018 в 23:47
поделиться

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

Если у вас более двух списков,

  1. Объедините первые два в один новый список.
  2. Объедините полученный список со следующим списком.
  3. Повторите.
3
ответ дан mbeckish 25 August 2018 в 23:47
поделиться

Вот пример с использованием битовой маски. Нет рекурсии и нескольких списков

static List<Integer> allComboMatch(List<Integer> numbers, int target) {
    int sz = (int)Math.pow(2, numbers.size());
    for (int i = 1; i < sz; i++) {
        int sum = 0;
        ArrayList<Integer> result = new ArrayList<Integer>();
        for (int j = 0; j < numbers.size(); j++) {
            int x = (i >> j) & 1;
            if (x == 1) {
                sum += numbers.get(j);
                result.add(j);
            }
        }
        if (sum == target) {
            return result;
        }
    }
    return null;
}
-4
ответ дан Michail Medvinsky 25 August 2018 в 23:47
поделиться

Эта операция называется декартовым произведением . Guava предоставляет для этого функцию полезности: Lists.cartesianProduct

3
ответ дан Pedro Oliveira 25 August 2018 в 23:47
поделиться

поздно для вечеринки, как обычно, но вот пример с объяснением, используя массивы, его легко изменить для списков. Мне нужны все уникальные комбинации нескольких массивов для моего использования в лексикографическом порядке.

Я разместил его, так как ни один из ответов здесь не дает ясного алгоритма, и я не могу выдержать рекурсию. Разве мы не находимся на stackoverflow ?

String[][] combinations = new String[][] {
                 new String[] { "0", "1" },
                 new String[] { "0", "1" },
                 new String[] { "0", "1" },
                 new String[] { "0", "1" } };

    int[] indices = new int[combinations.length];

    int currentIndex = indices.length - 1;
    outerProcess: while (true) {

        for (int i = 0; i < combinations.length; i++) {
            System.out.print(combinations[i][indices[i]] + ", ");
        }
        System.out.println();

        while (true) {
            // Increase current index
            indices[currentIndex]++;
            // If index too big, set itself and everything right of it to 0 and move left
            if (indices[currentIndex] >= combinations[currentIndex].length) {
                for (int j = currentIndex; j < indices.length; j++) {
                    indices[j] = 0;
                }
                currentIndex--;
            } else {
                // If index is allowed, move as far right as possible and process next
                // combination
                while (currentIndex < indices.length - 1) {
                    currentIndex++;
                }
                break;
            }
            // If we cannot move left anymore, we're finished
            if (currentIndex == -1) {
                break outerProcess;
            }
        }
    }

Выход;

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

1010

1011

1100

1101

1110

1111

0
ответ дан professorcolm 25 August 2018 в 23:47
поделиться

Без рекурсии уникальные комбинации:

    String sArray[] = new String []{"A", "A", "B", "C"};
    //convert array to list
    List<String> list1 = Arrays.asList(sArray);
    List<String> list2 = Arrays.asList(sArray);
    List<String> list3 = Arrays.asList(sArray);

    LinkedList<List <String>> lists = new LinkedList<List <String>>();

    lists.add(list1);
    lists.add(list2);
    lists.add(list3);

    Set<String> combinations = new TreeSet<String>();
    Set<String> newCombinations;

    for (String s: lists.removeFirst())
        combinations.add(s);

    while (!lists.isEmpty()) {
        List<String> next = lists.removeFirst();
        newCombinations =  new TreeSet<String>();
        for (String s1: combinations) 
            for (String s2 : next) 
              newCombinations.add(s1 + s2);               

        combinations = newCombinations;
    }
    for (String s: combinations)
        System.out.print(s+" ");    
5
ответ дан Ruslan Ostafiichuk 25 August 2018 в 23:47
поделиться

Операция, которую вам нужно реализовать, называется декартовым продуктом. Для получения дополнительной информации см. https://en.wikipedia.org/wiki/Cartesian_product

Я рекомендую использовать мою библиотеку с открытым исходным кодом, которая может делать именно то, что вам нужно: https://github.com/SurpSG/Kombi

Есть пример того, как его использовать: https://github.com/SurpSG/Kombi#usage-for-lists -1

Примечание. Библиотека была разработана для высокопроизводительных целей. Вы можете наблюдать результаты banchmarks здесь

Библиотека дает вам довольно хорошую пропускную способность и постоянное использование памяти

0
ответ дан SergiiGnatiuk 25 August 2018 в 23:47
поделиться
  • Нет рекурсии
  • упорядочено
  • Возможно получить конкретную комбинацию по ее индексу (без построения всех других перестановок):

Метод класса и main() в конце:

public class TwoDimensionalCounter<T> {
    private final List<List<T>> elements;

    public TwoDimensionalCounter(List<List<T>> elements) {
        this.elements = Collections.unmodifiableList(elements);
    }

    public List<T> get(int index) {
        List<T> result = new ArrayList<>();
        for(int i = elements.size() - 1; i >= 0; i--) {
            List<T> counter = elements.get(i);
            int counterSize = counter.size();
            result.add(counter.get(index % counterSize));
            index /= counterSize;
        }
        return result;//Collections.reverse() if you need the original order
    }

    public int size() {
        int result = 1;
        for(List<T> next: elements) result *= next.size();
        return result;
    }

    public static void main(String[] args) {
        TwoDimensionalCounter<Integer> counter = new TwoDimensionalCounter<>(
                Arrays.asList(
                        Arrays.asList(1, 2, 3),
                        Arrays.asList(1, 2, 3),
                        Arrays.asList(1, 2, 3)
                ));
        for(int i = 0; i < counter.size(); i++)
            System.out.println(counter.get(i));
    }
}
1
ответ дан Stanislav Bashkyrtsev 25 August 2018 в 23:47
поделиться

Эта тема пригодилась. Я полностью переписал предыдущее решение на Java и стал более удобным для пользователя. Кроме того, для большей гибкости я использую коллекции и дженерики:

/**
 * Combines several collections of elements and create permutations of all of them, taking one element from each
 * collection, and keeping the same order in resultant lists as the one in original list of collections.
 * 
 * <ul>Example
 * <li>Input  = { {a,b,c} , {1,2,3,4} }</li>
 * <li>Output = { {a,1} , {a,2} , {a,3} , {a,4} , {b,1} , {b,2} , {b,3} , {b,4} , {c,1} , {c,2} , {c,3} , {c,4} }</li>
 * </ul>
 * 
 * @param collections Original list of collections which elements have to be combined.
 * @return Resultant collection of lists with all permutations of original list.
 */
public static <T> Collection<List<T>> permutations(List<Collection<T>> collections) {
  if (collections == null || collections.isEmpty()) {
    return Collections.emptyList();
  } else {
    Collection<List<T>> res = Lists.newLinkedList();
    permutationsImpl(collections, res, 0, new LinkedList<T>());
    return res;
  }
}

/** Recursive implementation for {@link #permutations(List, Collection)} */
private static <T> void permutationsImpl(List<Collection<T>> ori, Collection<List<T>> res, int d, List<T> current) {
  // if depth equals number of original collections, final reached, add and return
  if (d == ori.size()) {
    res.add(current);
    return;
  }

  // iterate from current collection and copy 'current' element N times, one for each element
  Collection<T> currentCollection = ori.get(d);
  for (T element : currentCollection) {
    List<T> copy = Lists.newLinkedList(current);
    copy.add(element);
    permutationsImpl(ori, res, d + 1, copy);
  }
}

Я использую библиотеку guava для создания коллекций.

15
ответ дан Víctor 25 August 2018 в 23:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: