Функция посимвольного сравнения строк без учета регистра

Напишите функцию, которая принимает две строки a и b и сравнивает строки без учета регистра. Возвращает -1, если a < b. 0, если a == b. 1, если a > b.

Строка может содержать символы с кодами с 32 по 126. Максимальная длина строки 10^6 символов.

Решаю эту задачу, но вывод получаю неверный.

Пожалуйста подскажите что именно не верно в моем коде

Вот код:

public static int compareIgnoreCase(String a, String b){
        char [] arrayA = a.toCharArray();     // создание массива сивмолов первой строки и передача в него символов строки
        char [] arrayB = b.toCharArray();     // создание массива для передачи символов  второй строки
        int n = Math.min(arrayA.length, arrayB.length);    // создание переменной для определения длинны массива

        for (int i = 0; i < n; i++){                // запуск цикла
            int numberAMin = arrayA[i] + 32;        // создание переменной для символа первого слова с противоположным регистром
            int numberBMin = arrayB[i] + 32;        // создание переменной для символа второго слова с противоположным регистром
            int numberAMax = arrayA[i] - 32;         //- //
            int numberBMax = arrayB[i] - 32;         // - //

            if (arrayA[i] < arrayB[i]               // создание условия, если символ первого слова меньше символа второго и не равен противоположному ргистру
                    && arrayA[i] != numberBMax
                    && arrayA[i] != numberBMin
                    && arrayB[i] != numberAMax
                    && arrayB[i] != numberAMin){
                return -1;
            }
            if (arrayA[i] > arrayB[i]
                    && arrayA[i] != numberBMax
                    && arrayA[i] != numberBMin
                    && arrayB[i] != numberAMax
                    && arrayB[i] != numberAMin){
                return 1;
            }
            else{
                return 0;
            }
        }
        if (arrayA.length < arrayB.length){
            return -1;
        }
        if (arrayA.length> arrayB.length){
            return 1;
        }
        else{
            return 0;
        }
    }

ВОТ РАБОЧИЙ ВАРИАНТ:

public static int compareIgnoreCase(String a, String b){
        char [] arrayA = a.toCharArray();
        char [] arrayB = b.toCharArray();
        int n = Math.min(arrayA.length, arrayB.length);

        for (int i = 0; i < n; i++){
            // Берем очередные символы из массивов
            char chA = arrayA[i];
            char chB = arrayB[i];
            // Если очередной символ находится в диапазоне верхнего регистра
            // И НЕ цифра, то смещаем его в диапазон нижнего регистра
            if (chA >= 'A' && chA <= 'Z' && !(chA >= '0' && chA <= '9')){
                chA += 32;
            }
            // Аналогично
            if (chB >= 'A' && chB <= 'Z' && !(chB >= '0' && chB <= '9')){
                chB += 32;
            }
            int sumA = 0;  sumA = sumA + chA;
            int sumB = 0;  sumB = sumB + chB;

            if (sumA < sumB){
                return -1;
            }
            if (sumA > sumB){
                return 1;
            }      
        }
        if (arrayA.length > arrayB.length)
            return 1;
        else if (arrayA.length < arrayB.length)
            return -1;
        return 0;
    }

Если что ))) всем спасибо!!


Ответы (2 шт):

Автор решения: Alexander Chernin

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

public static int compareIgnoreCase(String a, String b){
        char [] arrayA = a.toCharArray();
        char [] arrayB = b.toCharArray();
        
        int n = Math.min(arrayA.length, arrayB.length);

        for (int i = 0; i < n; i++) {
            // Берем очередные символы из массивов
            char chA = arrayA[i];
            char chB = arrayB[i];
            
            // Если очередной символ находится в диапазоне верхнего регистра 
            // И НЕ цифра, то смещаем его в диапазон нижнего регистра
            if (chA >= 'A' && chA <= 'Z')
                chA += 32;
            // Аналогично
            if (chB >= 'A' && chB <= 'Z')
                chB += 32;              
  
            // Если символы не равны, то
            if (chA != chB) {
                // Какая строка длиннее  
                if (arrayA.length > arrayB.length) 
                    return 1;
                else if (arrayA.length < arrayB.length) 
                    return -1;
                // Строки оказались одинаковой длины, тогда
                // сравним какой символ "меньше"
                return chA < chB ? -1: 1;
            }
        }
        
        // Ну, тут все понятно
        if (arrayA.length > arrayB.length) 
            return 1;
        else if (arrayA.length < arrayB.length) 
            return -1;
        
        return 0;
    }

    public static void main(String args[]) {
      System.out.println(compareIgnoreCase("Str1", "str1")); // 0
    }

Вариант сравнения сумм кодов символов строк:

char [] arrayA = a.toCharArray();
char [] arrayB = b.toCharArray();
    

int sumA = 0;
for(int i = 0; i < arrayA.length; i++) {
    char chA = arrayA[i];
    if (chA >= 'A' && chA <= 'Z')
        chA += 32;    
    sumA += (int)chA;
}
       
int sumB = 0;
for(int i = 0; i < arrayB.length; i++) {
    char chB = arrayB[i];
    if (chB >= 'A' && chB <= 'Z')
        chB += 32;    
    sumB += (int)chB;
}
return sumA == sumB ? 0 : (sumA < sumB? -1: 1);
→ Ссылка
Автор решения: benderje

Ваша задача сводится к тому, чтобы привести строки к одному регистру (если это цифра, то её не надо приводить, разумеется - добавьте такое условие), а вот потом уже сравнивать. И тогда это и будет "сравнение без учета регистра". У вас есть два варианта, как это сделать. Например, как посоветовал Alexander Chernin: получать массив char[] преобразованием из String, и перебирать каждый символ. Т.е. при переборе элементов массива Вы проверяете: если это буква, то какая? Например (можно и наоборот, "безучетностьрегистра" останется та же (: ), видите заглавную - приводите к строчной, видите строчную - оставляете, как есть. И потом уже сравниваете значения a[i] и b[i].

Или же можно сделать лаконичнее: поищите методы класса String toLowerCase() и toUpperCase(). На выходе имеете String, у которого все символы - одного регистра. А дальше просто сравниваете, одним циклом.)

И еще, попробуйте суммировать символы своих строк. Т.е. привели к одному регистру буквы, а дальше суммируете все элементы через цикл. Почему так? Потому что по таблице ASCII слово HELLO будет "меньше" слова RIVER, например. Хотя количество букв одно. Или, например, слова RIVER и STILL: видимо, мы должны вернуть -1, т.к. R "меньше" S. Но на деле суммы их кодов равны..

P.S. IDEA не под рукой, поэтому без кода, лень.)

→ Ссылка