Как я могу создать конкатенацию между двумя символами на основе предыдущего объединения с использованием Java 8? - PullRequest
0 голосов
/ 31 января 2019

Я работаю над проблемой, пытаясь сгенерировать все возможные комбинации между двумя символами на основе ранее сгенерированного комбината, используя java 8

, например:

private static final String LETTER_RANGE = "abcdefghijklmnopqrstuvwxz";

from this letter rang I want to extract all differents combine between two chars XX

for example : 

zz,zx,zw....za 
xz,xx,xw....xa
..,..,..,..,..
az,ax,aw... aa

My problem is I need to generate those combination at runtime based on previous combine : 

String value = generate("zx") // this should return 'zw'

Может любойпомогите мне с любой идеей, как можно использовать java 8 loop, Stream, String для этого заранее спасибо

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Шаблон в вашем примере напоминает мне столбцы Excel.Excel именует свои столбцы буквами от A до Z, а затем последовательность становится AA, AB, AC ... AZ, BA, BB и т. Д. Поэтому, если мы интерпретируем ваши комбинации как заголовки столбцов Excel, задача может быть перефразирована следующим образом:

Учитывая заголовок столбца, как показано на листе Excel, найдите заголовок следующего столбца (или предыдущий, как показано в ожидаемом результате).

Для этого вы можете написатьметод, который принимает строку в качестве параметра (например, «zf») и возвращает фактический номер столбца.Затем добавьте или вычтите 1, чтобы получить номер следующего или предыдущего столбца, и преобразуйте число обратно в строку.Пример:

public final class ExcelColumn {
    public static void main(String[] args) {
        String str = "zx";
        System.out.println(getPreviousColumn(str));
    }

    public static int toColumnNumber(String column) {
        int result = 0;
        for (int i = 0; i < column.length(); i++) {
            result *= 26;
            result += column.charAt(i) - 'a' + 1;
        }
        return result;
    }

    public static String toColumnName(int number) {
        final StringBuilder sb = new StringBuilder();
        int num = number - 1;
        while (num >=  0) {
            int numChar = (num % 26)  + 97;
            sb.append((char)numChar);
            num = (num  / 26) - 1;
        }
        return sb.reverse().toString();
    }
    public static String getNextColumn(String s) {
        return toColumnName( toColumnNumber(s)+1);
    }
    public static String getPreviousColumn(String s) {
        return toColumnName( toColumnNumber(s)-1);
    }
}

ToDo:

  • Проверка ввода и
  • обработка исключений

Плюсы:

  • Вы можете использовать это, даже если ваша общая длина строки> 2
  • может быть легко изменена для использования с заглавными буквами
  • Вы можете сделать что-то вроде от 'be' до 'cf'для генерации всех комбинаций, попадающих в этот диапазон при необходимости

Минусы:

  • Может быть много кода для простой задачи.Посмотрите на комментарий Андрея Вдовиченко, который решает проблему в несколько строк
0 голосов
/ 31 января 2019

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

char ch = LETTER_RANGE.charAt(2); // 'c'
int ix = LETTER_RANGE.indexOf(ch); // 2

Использование одного массива char[], вероятно, намного проще, поэтому метод может выглядеть следующим образом:

String next(String combination) {
    char[] chars = combination.toCharArray();
    char ch = chars[1];
    if (...) {
    }
    return new String(chars);
}
0 голосов
/ 31 января 2019

Звучит как очень плохое решение задачи для меня.Но если вам это действительно нужно, это можно сделать так.

    private static final String LETTER_RANGE = "abcdefghijklmnopqrstuvwxz";

public String findNext(String prev) {
    if(prev==null || prev.length()<2)
        throw new RuntimeException("Invalid argument");

    int char1Index = LETTER_RANGE.indexOf(prev.charAt(0));
    int char2Index = LETTER_RANGE.indexOf(prev.charAt(1));
    char2Index--;
    if (char2Index < 0) {
        char1Index--;
        char2Index = LETTER_RANGE.length() - 1;
    }
    if (char1Index < 0) {
        return null;// or what you need here.
    }
    return new String(new char[]{LETTER_RANGE.charAt(char1Index), LETTER_RANGE.charAt(char2Index)});
}

И задача найти все конкатенации между двумя символами из предопределенного списка. Я бы сделал так:

public List findAll() {
    List<String> result=new ArrayList<>();
    char[] chars=LETTER_RANGE.toCharArray();
    for(int i=0;i<chars.length;i++)
    for(int j=0;j<chars.length;j++)
        result.add(new String(new char[]{chars[i],chars[j]}));
    return result;
}
0 голосов
/ 31 января 2019

Вы можете использовать простую арифметику символов.Поскольку char s можно увеличивать и сравнивать:

final List<String> permutations = new ArrayList<>(26 * 26);
for (char[] array = {'a', 'a'}; array[0] <= 'z'; array[0]++) {
    for (array[1] = 'a'; array[1] <= 'z'; array[1]++) {
        permutations.add(new String(array));
    }
}

Этот фрагмент кода создает каждую комбинацию всех символов от a до z включительно и добавляет их к List.

Это возможно, потому что в ASCII значение символа a (97) меньше значения из z (122).

Я также использовал некоторые оптимизации, например, использование array внутри for-loop для хранения текущей комбинации из 2 символов.Этот массив затем также может быть непосредственно использован для создания новой строки с помощью строкового конструктора: String(char[]).

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