Лексикографический порядок - два символьных массива в качестве параметров, поиск лучшего решения - PullRequest
0 голосов
/ 17 октября 2018

Мне нужно написать функцию, которая занимает 2 char[] с и возвращает:

  • -1, если первое слово стоит перед вторым в лексикографическом порядке
  • 0 если это одно и то же слово
  • 1 если оно идет после

Мне известен метод compareTo(), но это назначение, мне нужно избегатьиспользуй это.Пока мой код работает хорошо, я провел несколько тестов с разными словами.

Мне было интересно, есть ли другой способ сделать это, мой код не чувствует себя оптимизированным, он длинный и повторяющийся:

public static int lexico(char[] word1, char[] word2) {
        int length1 = word1.length;
        int length2 = word2.length;

        if (length1 == length2) {
            for (int i = 0; i < length1; i++) {
                if (word1[i] < word2[i]) {
                    return -1;
                } else if (word1[i] > word2[i]) {
                    return 1;
                } else if (i == length1 - 1) {
                    return 0;
                }
            }
        }

        if (length1 < length2) {
            for (int i = 0; i < length1; i++) {
                if (word1[i] < word2[i]) {
                    return -1;
                } else if (word1[i] > word2[i]) {
                    return 1;
                } else if (i == length1 - 1) {
                    // If I'm here then it means that all of the characters
                    // from 0 to length1-1 are equals
                    // but since length of the first string is shorter than the second,
                    // the first string will be put before the second
                    return -1;
                }

            }
        }

        if (length1 > length2) {
            for (int i = 0; i < length2; i++) {
                if (word1[i] < word2[i]) {
                    return -1;
                } else if (word1[i] > word2[i]) {
                    return 1;
                } else if (i == length1 - 1) {
                    return 1;
                }
            }
        }

        return -999;
    }

public static void main(String[] args) {
    char[] share = { 's', 'h', 'a', 'r', 'e' };
    char[] ship = { 's', 'h', 'i', 'p' };

    System.out.println(lexico(share, ship)); // -1 share is before ship
    System.out.println(lexico(ship, share)); // 1 ship is after share
    System.out.println(lexico(ship, ship)); // 0 same word

}

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

хорошо, я сдался и написал это ... нет модульного тестирования (всегда код поставки проверен модулем), но я думаю, что это должно дать вам хорошую идею для функциональной работы (есть такие крайние случаи, как разная длина и т. Д.)имел в виду, но вы понимаете, правильно?) ... ура и весело провести время: =) ... это может быть сделано более эффективно, я думаю, с потоками ...

public static void main(String[] args) {
    List<Character> firstCharArr = new ArrayList<>(Arrays.asList('a', 'c'));
    List<Character> secondCharArr = new ArrayList<>(Arrays.asList('x', 'c'));

    BiFunction<Character, Character, Integer> charCompareFunction = new BiFunction<Character, Character, Integer>() {
        @Override
        public Integer apply(Character character, Character character2) {
            if (character.charValue() < character2.charValue()) {
                return -1;
            } else if (character.charValue() == character2.charValue()) {
                return 0;
            } else {
                return 1;
            }
        }
    };

    int i = 0;
    for (Character firstLineChar : firstCharArr) {
        if (charCompareFunction.apply(firstLineChar, secondCharArr.get(i++)) == 0) {
            continue;
        } else {
            if (charCompareFunction.apply(firstLineChar, secondCharArr.get(i++)) < 0) {
                System.out.println("FirstLine is Smaller");
                break;
            } else {
                System.out.println("FirstLine is Larger");
                break;
            }
        }
    }
}

На самом деле, вы можетеиспользуя вышеизложенное, докажите символьный лексикографический порядок Java: цифры перед буквами заглавные перед строчными

0 голосов
/ 17 октября 2018

Пара замечаний для вас:

  • Вам нужен только один цикл: от начала до нижнего из двух длин.Если массивы одинаковы до тех пор, пока нижняя из двух длин и их длины не будут разными, ваше назначение должно сказать вам, что возвращать (обычно это будет -1, если левый массив будет короче правого, 1 в противном случае).

  • a < b не является действительным буквенным сравнением двух символов (что означает большинство программистов, когда они говорят «лексикографический», «лексико» означает «относящийся к словам»), это числовое сравнение.Теперь String s compareTo утверждает, что использует "лексикографическое упорядочение", но на самом деле оно просто использует числовое упорядочение, так что этого может быть достаточно для того, что вы делаете.Если вы хотите алфавитное упорядочение, я не могу вспомнить метод сравнения JDK, который принимает для сравнения два отдельных символа , а не строки.Может быть одна, о которой я не знаю, или вам может потребоваться создать односимвольные строки для сравнения (с Collator), которое (например) будет правильно определять, что à в "вуаля" должно быть перед любой другой буквы в нем.

...