0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104

Строка: По букве получить численное представление и по числу получить соответствующую букву.

20.08.2018, 09:54. Показов 3337. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет. Задача такая: необходимо реализовать два метода, один из которых по введенной букве возвращал ее численное представление, а другой метод наоборот, по введенному числу возвращал соответствующую букву. Например:
- ввожу "A" - получаю 1; ввожу "AA" - получаю 27; ввожу "AAA" - получаю 703. Для чисел тоже самое, ввел 703 - получил "AAA". Сначала я реализовал через LinkedHashMap следующим образом:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public static int str2int(String number) {
        int p = 0, k = 0, g = 0, l = 0;
 
        String[] letters = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
                "S", "T", "U", "V", "W", "X", "Y", "Z" };
 
        Map<Integer, String> intString = new LinkedHashMap<>();
        for (int i = 0; i < letters.length; i++) {
            intString.put(i, letters[i]);
            p++;
        }
        k = p; // k = 26
        g = 2 * k; // 52
 
        for (int i = 0; i < letters.length; i++) {
            for (int j = k; j < g; j++, l++) {
                intString.put(j, letters[i].concat(letters[l]));
            }
            k = g;
            g = k + 26;
            l = 0;
        } // AA-ZZ
 
        for (int i = 0; i < letters.length; i++) {
            for (int j = k; j < g; j++, l++) {
                intString.put(j, letters[i].concat(letters[i]).concat(letters[l]));
            }
            k = g;
            g = k + 26;
            l = 0;
        }//AAA-ZZZ
    
        int num = 0;
        for (Map.Entry<Integer, String> entry: intString.entrySet()) {
            if (number.equals(entry.getValue())) {
                num = entry.getKey() + 1;
                break;
            }
        }
 
        return num;
    }
Это пример метода, возвращающего по букве ее число.
Проблема в том, что я выяснил, нет предела в последовательности букв. То есть я считал, что максимальный порядок - это три: "ZZZ". Но Оказалось, что можно ввести, например, "AAZX" и надо получить тоже его число.
Подскажите, как лучше все это дело оформить? Продолжать с коллекцией работать, а именно: создать еще один цикл, в котором я буду просто четвертую букву присоединять, как и в двух других циклах, или как-то по-другому шаманить? Спасибо.


P.S. Если нужен пример кода для метода, возвращающего букву по числу, я конечно скину, но там тот же самый код, что и в скинутом примере.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.08.2018, 09:54
Ответы с готовыми решениями:

Строка: Получить и вывести на экран слова начинающиеся и заканчивающиеся на одну и ту же букву.
Пользователь вводит строку символов. Получить и вывести на экран слова начинающиеся и заканчивающиеся на одну и ту же букву.

Как получить доступ к каждой букве строки?
Вот проблема такая, работаю с документами, данные храню в Excel, а готовые документы получаю в Word. Вот например у меня в ячейке данные...

Получить заданное слово, изменяя в исходном слове по одной букве
Ребят, прошу помощи! Есть задача: Дано исходное и конечное слово равной длины. Длина исходных слов не ограничена. Необходимо составить...

11
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
20.08.2018, 11:25
Лучший ответ Сообщение было отмечено Kirillgo как решение

Решение

Цитата Сообщение от Kirillgo Посмотреть сообщение
Подскажите, как лучше все это дело оформить?
сделать метод который просто вычисляет нужное, а не перебирает все возможности, ниже привожу тебе метод для получения букв по числу

сразу скажу писал на скорую руку и на коленке, мог что-то упустить
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import org.junit.Assert;
import org.junit.Test;
//это для тестов, для метода не нужно
 
public class Convert {
    private static final int LETTERS_COUNT = 26;
    private final static String[] letters = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
            "S", "T", "U", "V", "W", "X", "Y", "Z"};
 
    public static String intToChars(int value) {
        if (value <= LETTERS_COUNT) {
            return letters[value - 1]; //если меньше 27, то простая буква, сразу возвращаем
        }
        int val = value / LETTERS_COUNT; //получаем частное
        String result = ""; //готовим результат для возврата
        if (value - val * LETTERS_COUNT > 0) {  // вычисляем последнюю букву последовательности
            result += letters[value - val * LETTERS_COUNT - 1];
        } else {
            return intToChars(val - 1) + "Z"; // для исключительного случая, когда речь идет о последней букве и value делится на 26 без остатка
        }
        if (val > LETTERS_COUNT) { // если частное все еще больше 26 то отправляем на повторную обработку
            result = intToChars(val) + result;
        } else {
            result = letters[val - 1] + result;
        }
        return result;
    }
 
    @Test
    public void checkIntToChars(){
        Assert.assertEquals(intToChars(27),"AA");
        Assert.assertEquals(intToChars(1),"A");
        Assert.assertEquals(intToChars(26),"Z");
        Assert.assertEquals(intToChars(703),"AAA");
        Assert.assertEquals(intToChars(747),"ABS");
        Assert.assertEquals(intToChars(52),"AZ");
        Assert.assertEquals(intToChars(639),"XO");
        Assert.assertEquals(intToChars(162),"FF");
        Assert.assertEquals(intToChars(247),"IM");
        Assert.assertEquals(intToChars(389),"NY");
    }
}
-1 везде потому что массив считается с 0, а буквы с 1. Да, не обрабатываю случай, если пришлют 0 или менее 0, надо исключение кидать

Добавлено через 29 минут
Kirillgo, кстати метод возврата числа по буквам еще короче и проще получается, чем intToChars, но оставляю тебе возможность реализовать самому
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104
20.08.2018, 12:03  [ТС]
Welemir1, спасибо, но вот этот прикол с вычислениями пока в ступор привел
Лан, буду пробовать разбирать. Мой вариант действительно не подходит, но другое просто в голову не лезет.

Добавлено через 5 минут
Welemir1, работает....а как Вы это сделали? Жесть, я в шоке прост. Я долбился пару дней над этой задачей и лучшее, что пришло мне в голову - использовать LinkedHashMap...и хотя я интуитивно понимаю, что это не вариант, потому что решение мое не подходит для любого случая, но вот как стена в голове...

Добавлено через 8 минут
Welemir1, так, а я бы хотел задать пару вопросов по коду, если можно:
1.
Цитата Сообщение от Welemir1 Посмотреть сообщение
int val = value / LETTERS_COUNT; //получаем частное
Какая логика должна быть? Как я должен мыслить на этом шаге? Ну то есть я не понял, зачем мне получать частное, да еще и таким способом.


2.
Цитата Сообщение от Welemir1 Посмотреть сообщение
if (value - val * LETTERS_COUNT > 0) { // вычисляем последнюю букву последовательности result += letters[value - val * LETTERS_COUNT - 1]; } else { return intToChars(val - 1) + "Z"; // для исключительного случая, когда речь идет о последней букве и value делится на 26 без остатка } if (val > LETTERS_COUNT) { // если частное все еще больше 26 то отправляем на повторную обработку result = intToChars(val) + result; } else { result = letters[val - 1] + result; }
Для чего мы вычисляем последнюю букву последовательности? Я задаю, например, код 18954, на выходе должен получить "AAZX". По этому алгоритму я нахожу только букву X, верно?
Про исключительный случай я не совсем понял, это когда получаем букву "Z"?
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
20.08.2018, 12:12
Kirillgo, когда долго над одной задачей бьешься - это бывает, надо иногда отвлекаться, я вот когда зависаю -иду сюда на форум решать ваши задачки)))

Ты просто пойми для себя, что есть некий алгоритм получения как букв по числу, так и наоборот, надо просто его найти. Так как результаты работы тебе известны (1="А", 27="АА"), то начинаешь по-маленьку писать код и искать закономерности. Как вариант сразу написать тест вот как у меня (он естественно будет падать) и по мере написания кода метода, все большее количество строчек будет выполняться, пока не выполнятся все.

Добавлено через 6 минут
Цитата Сообщение от Kirillgo Посмотреть сообщение
Какая логика должна быть? Как я должен мыслить на этом шаге?
ну логика тут моя, мои рассуждения, твоя реализация может быть другой. Я делю число на 26 чтобы проверить сколько раз туда укладывается весь алфавит. Скажем, берем 27, алфавит туда укладывается 1 раз, далее...

Цитата Сообщение от Kirillgo Посмотреть сообщение
Для чего мы вычисляем последнюю букву последовательности?
чтобы была) мы уже выше выяснили, что в числе 27 1 раз уложен весь алфавит и еще есть 1 (26+1=27), 1 это у нас буква А, запоминаем ее

потом нам нужно знать сколько раз этот алфавит укладывается в нашем числе, для 27 это 1, то есть первая буква, тоже А
получаем А+А=АА

Цитата Сообщение от Kirillgo Посмотреть сообщение
Про исключительный случай я не совсем понял, это когда получаем букву "Z"?
да, когда будет Z на конце, то число будет делиться на 26 без всяких остатков, то есть все наши действия с остатком к нему не применятся, поэтому приходится руками прописывать этот конкретный случай

Добавлено через 2 минуты
Цитата Сообщение от Kirillgo Посмотреть сообщение
Я задаю, например, код 18954, на выходе должен получить "AAZX"
нет 18952
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104
20.08.2018, 12:37  [ТС]
Welemir1, так, я понял. А вот вопрос по поводу получения числа по букве. Я начал вот так:
Java
1
2
3
for (int i = 0; i < letters.length; i++) {
            if (value.equals(letters[i])) return i+1;
        }
То есть тут возвращаю номер единичной буквы.
А дальше как рассуждать? Как мне по числу 27 обратиться к "AA"?

Добавлено через 2 минуты
Может так: взять длину входной строки, если она больше 1 и меньше 3, то это двухзначная строка...но я так не смогу подбирать, наверное, у меня может быть строка длинной 5 или 6. На все числа не переберу варианты...
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
20.08.2018, 13:26
Kirillgo, нужно найти закономерность, а не просто наугад пытаться.
Разбиваем слово по букве и начиная с последней начинаем считать. Последняя нам просто даст индекс числа, скажем для А -1. Далее с каждой новой буквой (все ближе к началу) прибавляем к общему результату умножение индекса буквы в массиве на 26^номер буквы с конца (скажем для предпоследней 26^1=26, для предпредпоследней 26^2 и так далее)
ТО есть для АА берем последнюю А, она первая в алфавите, значит к результату прибавляем 1. 0+1=1
Берем вторую А, ее номер опять же 1, но умножаем на 26. Прибавляем к результату 26. Получаем 26+1=27

вот такой цикл тебе надо написать, можно в 8 строк уложиться и не надо перебирать варианты
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104
20.08.2018, 15:14  [ТС]
Welemir1, т.е. ввожу я "AAZX", это 18952 должно получится. Я делаю так: X - 24, Z - 26, A -1. Тогда с конца иду: 24 + 26*26*2 + 3 + 4, так я понимаю? Походу нет, потому что такое число не выходит(
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
20.08.2018, 16:16
Kirillgo, я же выше писал про 26 в степени индекса буквы с конца)
AAZX=24 (номер Х в алфавите) + 26(индекс Z)*26 (26 в степени 1) + 1 (индекс А)*26*26 (26 в степени 2)+1(индекс А)*26*26*26 (26 в степени 3)=
= 24+676+676+17576=18952

если будет больше букв то там дальше будет 26 в четвертой степени, пятой и так далее. Вот тебе и алгоритм, осталось написать.
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104
21.08.2018, 11:36  [ТС]
Welemir1, спасибо Вам, все сработало. У меня было в задании сказано про еще один метод, возвращающий соседнюю букву по отношению к той, которую передаем в аргументе. Я в принципе через вызовы первых двух методов его оформил да и все. А по букве найти его номер вот так сделал:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static int strToint(String number) {
        int k = 0, result = 0;
        String[] str = number.split("");
        for (int s = str.length - 1; s >= 0; s--) {
            for (int j = 0; j < letters.length; j++) {
                if (str[s].equals(letters[j])) {
                    result += (j + 1) * Math.pow(26, k);
                    k++;
                    break;
                }
            }
        }
        return result;
    }
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
21.08.2018, 12:12
Kirillgo, вот и молодец, а то я думал и этот метод для тебя писать придется
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104
21.08.2018, 13:04  [ТС]
Welemir1, можно еще вопрос не по этой теме? Я реализую свою коллекцию (другое задание), в ней надо реализовать свой итератор. Проблема возникает, когда я пытаюсь переопределить метод remove(). В нем я хочу удалить элемент по индексу, который возвращает метод next(). Вопрос в следующем, как мне узнать, был ли вызван метод next() уже, чтобы выбросить исключение, и как мне узнать, что я вызвал remove() дважды подряд? Я пока что итератор сделал вот так:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    class IteratorImpl implements Iterator<Object> {
        int index = 0;
        
 
        @Override
        public boolean hasNext() {
            if (index != size) {
                return true;
            }
 
            return false;
        }
 
        @Override
        public Object next() {
            
            return data[index++];
        }
 
        @Override
        public void remove() {
 
            
            Object obj = data[--index];
            if (obj == null) {
                throw new IllegalStateException();
            }
            
            
            int numMoved = size - index - 1; // количество сдвигаемых элементов
            System.arraycopy(data, index + 1, data, index, numMoved);
            data[size--] = null;
        }
    }
Но я понимаю, что

Java
1
2
3
4
Object obj = data[--index];
            if (obj == null) {
                throw new IllegalStateException();
            }
стопудово ошибка, потому что таким образом я никак не проверяю, вызвал ли я метод next() или нет. А написал такое извращение с индексом, потому что тут тоже возникает такая фигня, что при каждом вызове метода next() увеличивается индекс, соответственно, в метод remove приходит не индекс элемента, на который "наступил" итератор, а индекс элемента, который его сосед справа. Поэтому и уменьшал его. Как по-другому реализовать - не знаю, через мою реализацию next() hasNext() наверное никак. Но мне это особо и не важно. Важно понять, как убедиться, что был вызван метод next()

P.S. Коллекция типа ArrayList. Но без наследования от данной реализации.
0
Автоматизируй это!
Эксперт Python
 Аватар для Welemir1
7390 / 4817 / 1246
Регистрация: 30.03.2015
Сообщений: 13,667
Записей в блоге: 29
21.08.2018, 13:21
Цитата Сообщение от Kirillgo Посмотреть сообщение
можно еще вопрос не по этой теме?
неа) 1 тема -1 вопрос, чтобы в свалку не превращать. Совет -посмотри как реализован итератор в других коллекциях!
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.08.2018, 13:21
Помогаю со студенческими работами здесь

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

Получить для каждого элемента максимальную дату и цену, соответствующую этой дате
Нужен такой хитрейший запрос: Вот есть скажем таблица: Element DDoc Price 1 01.01.01 200 1 02.01.01 150 2 ...

По введенному баллу получить соответствующую характеристику ученика: отличник, хорошист, троечник, двоечник
По введенному баллу получить соответствующую характеристику ученика: отличник, хорошист, троечник, двоечник.

Как из диапазона цифр и букв вытянуть цифру соответствующую букве?
Имеется диапазон букв, 9 столбцов, каждому столбцу присвоена цифра. Необходимо, чтобы в ячейке при наборе последовательности букв, в другой...

Получить численное решение дифф. уравнения: проверьте программу
С новый годом всех вас! Программа работает, но хотелось бы спросить то, что правильно ли она написана у опытных программистов. Вот задание:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru