Сравнение string и массива string

Как можно первый символ текста сдвинуть "назад по алфавиту" (например б=а, к=й, а=я), а второй символ текста сдвинуть "вперёд по алфавиту" (а=б, й=к, я=а)? Пример текста : Доброго времени суток. = Гпасндн бсдндоз рфспл.

Пытался использовать массив string, в котором хранил весь алфавит, а после циклом for прогонял все символы и сравнивал их с символами в тексте, но ничего не получилось. Выводит что попало...

public class Main {

    public static void main(String[] args) {
        StringBuilder result = new StringBuilder();
        String text = "Доброго времени суток.";
        int text_length = text.length();

        String [][] alphabet = {{"а","б","в","г","д","е","ё"},
                                {"ж","з","и","й","к","л","м"},
                                {"н","о","п","р","с","т","у"},
                                {"ф","х","ц","ч","ш","щ","ъ"},
                                {"ы","ь","э","ю","я", null, null},
        };

        int column = 0;
        int row = 0;
        int counter = 0;

        int x = 0;
        int y = 1;

        char char_x;
        char char_y;

        String string_x =0;

        int move = 1;

        while (counter < text_length) {

            char_x = text.charAt(x);
            string_x =String.valueOf(char_x);

            for (int i =1;i<=33;i++ ) {
                if (string_x.equals(alphabet[row][column])) {

                    if (move % 2 != 0) {
                        if (!string_x.equals(alphabet[0][0])) {

                            result.append(alphabet[row][column-1]);

                        } else {
                            result.append(alphabet[4][4]);
                        }

                    } else {

                        if (move % 2 == 0) {
                            if (!string_x.equals(alphabet[4][4])) {

                                result.append(alphabet[row][column+1]);

                            } else {
                                result.append(alphabet[0][0]);

                            }
                        }

                    }
                }

                if (column !=6) {
                    column ++;
                } else {
                    if (row !=4) {
                        row ++;
                        column = 0;
                    }
                }

                move++;
                counter++;
            }
        }
    }
}

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

Автор решения: HMRDevil

К сожалению, не знаю Java, напишу решение на php с комментариями, думаю, сможете адаптировать. Соглашусь с S.H. , вы сильно усложняете двумерным массивом. Попробуйте так:

$string = "Доброго времени суток.";
// разбиваем строку на массив символов
$strArr = mb_str_split($string);
$letterString = "абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
//массив букв
$array = mb_str_split($letterString);

//boolean для смены значения
$change = true;
//измененная строка
$string2 = '';

foreach ($strArr as $i => $value)
{
    //символ есть в массиве символов, продолжаем
    if(in_array($value, $array))
    {
        //проверяем не "а" ли, если да
        if($strArr[$i] == "а")
        {
            //Заменяем на -1, т.е. "я"
            if($change)
            {
                $strArr[$i] = $array[32];
                $change = false;
                $string2 = $string2 . $strArr[$i];
                continue;
            //Заменяем на +1, "б"
            } else {
                $strArr[$i] = $array[1];
                $change = true;
                $string2 = $string2 . $strArr[$i];
                continue;
            }
        //проверяем на "А"
        } elseif($strArr[$i] == "А") {
            //Заменяем на "Я"
            if($change)
            {
                $strArr[$i] = $array[65];
                $change = false;
                $string2 = $string2 . $strArr[$i];
                continue;
            //Заменяем на +1, "Б"
            } else {
                $strArr[$i] = $array[34];
                $change = true;
                $string2 = $string2 . $strArr[$i];
                continue;
            }
        //проверяем на "я"
        } elseif($strArr[$i] == "я") {
            //Заменяем на "ю"
            if($change)
            {
                $strArr[$i] = $array[31];
                $change = false;
                $string2 = $string2 . $strArr[$i];
                continue;
            //Заменяем на +1, "а"
            } else {
                $strArr[$i] = $array[0];
                $change = true;
                $string2 = $string2 . $strArr[$i];
                continue;
            }
        //проверяем на "Я"
        } elseif($strArr[$i] == "Я") {
            //Заменяем на "Ю"
            if($change)
            {
                $strArr[$i] = $array[64];
                $change = false;
                $string2 = $string2 . $strArr[$i];
                continue;
            //Заменяем на +1, "А"
            } else {
                $strArr[$i] = $array[33];
                $change = true;
                $string2 = $string2 . $strArr[$i];
                continue;
            }
        // если не "аАяЯ", то
        } else {
            if($change)
            {
                $strArr[$i] = $array[array_search($strArr[$i], $array) -1];
                $change = false;
                $string2 = $string2 . $strArr[$i];
                continue;
            } elseif (!$change) {
                $strArr[$i] = $array[array_search($strArr[$i], $array) +1];
                $change = true;
                $string2 = $string2 . $strArr[$i];
                continue;
            }
        }
    // Не находим, значит добавляем так (это запятые, точки, и т.д.)
    } else {
        $string2 = $string2 . $strArr[$i];
        continue;
    }
}

Вывод построчный (Буква слова, буква замены, позиция замены):

Д => Г = -1
о => п = +1
б => а = -1
р => с = +1
о => н = -1
г => д = +1
о => н = -1
в => б = +1
р => п = -1
е => ё = +1
м => л = -1
е => ё = +1
н => м = -1
и => й = +1
с => р = -1
у => ф = +1
т => с = -1
о => п = +1
к => й = -1

Полная строка:

Гпасндн бпёлёмй рфспй.

Используемые функции php:

mb_str_split - Если задана многобайтовая строка возвращает массив символов

in_array — Проверяет, присутствует ли в массиве значение

array_search — Осуществляет поиск данного значения в массиве и возвращает ключ первого найденного элемента в случае успешного выполнения

P.S. Если необходимо всегда сменять +/- $change, при любых символах, можно ввести доп. проверку. Дополним:

} else {
    $string2 = $string2 . $strArr[$i];
    continue;
}

вот так:

} else {
    $string2 = $string2 . $strArr[$i];
    if($change)
    {
        $change = false;
    }
    else
    {
        $change = true;
    }
    continue;
}

И получится вывод строки:

Гпасндн бсдндоз рфспй.
→ Ссылка
Автор решения: Alex Rudenko

Для решения такой задачи нужно прежде всего определить функции для возврата следующего/предыдущего символа для данной буквы, и по очереди вызывать один из данных методов. Также, понадобится счётчик букв в слове, который будет сбрасываться при появлении небуквенного символа.

public static String encrypt(String s) {
    StringBuilder sb = new StringBuilder();
    int cnt = 0;
    for (char c : s.toCharArray()) {
        if (Character.isLetter(c)) {
            sb.append(cnt++ % 2 == 1 ? next(c) : prev(c));
        } else {
            cnt = 0;
            sb.append(c);
        }
    }
    return sb.toString();
}

Для дешифровки соответственно достаточно будет изменить порядок вызова next/prev:

public static String decrypt(String s) {
    StringBuilder sb = new StringBuilder();
    int cnt = 0;
    for (char c : s.toCharArray()) {
        if (Character.isLetter(c)) {
            sb.append(cnt++ % 2 == 0 ? next(c) : prev(c));
        } else {
            cnt = 0;
            sb.append(c);
        }
    }
    return sb.toString();
}

Методы next(char c), prev(char c) можно определить и без массива, при помощи switch (на Java 12+ будет выглядеть ещё лаконичнее):

private static char next(char c) {
    switch(c) {
       case 'z' : return 'a';
       case 'Z' : return 'A';
       case 'я' : return 'а';
       case 'е' : return 'ё';
       case 'ё' : return 'ж';
       case 'Я' : return 'А';
       case 'Е' : return 'Ё';
       case 'Ё' : return 'Ж';
       default  : return (char) (c + 1);       
    }
/** // Java 12
    return switch(c) {
       case 'z' -> 'a';
       case 'Z' -> 'A';
       case 'я' -> 'а';
       case 'Я' -> 'А';
       default  -> (char) (c + 1);       
    };
*/
}

private static char prev(char c) {
    switch(c) {
       case 'a' : return 'z';
       case 'A' : return 'Z';
       case 'а' : return 'я';
       case 'А' : return 'Я';
       case 'ё' : return 'е';
       case 'ж' : return 'ё';
       case 'Ё' : return 'Е';
       case 'Ж' : return 'Ё';
       default  : return (char) (c - 1);
    }
}

Тест:

String s = encrypt("Доброго времени суток! АБВГДейка! Где ёж? Вышел весь!");
System.out.println(s);
System.out.println(decrypt(s));

Вывод:

Гпасндн бсдндоз рфспй! ЯВБДГёиля! Вед ез? Бьчёк бёрэ!
Доброго времени суток! АБВГДейка! Где ёж? Вышел весь!

В слове "суток" к должно перейти в предыдущую букву.

→ Ссылка