Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 104

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

20.08.2018, 09:54. Показов 3356. Ответов 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
7392 / 4819 / 1246
Регистрация: 30.03.2015
Сообщений: 13,694
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Автозаполнение реквизита при выборе элемента справочника
Maks 27.03.2026
Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. При выборе "Спецтехники" (Тип Справочник. Спецтехника), заполняется. . .
Сумматор с применением элементов трёх состояний.
Hrethgir 26.03.2026
Тут. https:/ / fips. ru/ EGD/ ab3c85c8-836d-4866-871b-c2f0c5d77fbc Первый документ красиво выглядит, но без схемы. Это конечно не даёт никаких плюсов автору, но тем не менее. . . всё может быть. . .
Автозаполнение реквизитов при создании документа
Maks 26.03.2026
Программный код из решения ниже размещается в модуле объекта документа, в процедуре "ПриСозданииНаСервере". Алгоритм проверки заполнения реализован для исключения перезаписи значения реквизита,. . .
Команды формы и диалоговое окно
Maks 26.03.2026
1. Команда формы "ЗаполнитьЗапчасти". Программный код из решения ниже на примере нетипового документа "ЗаявкаНаРемонтСпецтехники" разработанного в конфигурации КА2. В качестве источника данных. . .
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при создании или изменении элементов справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной записи электронной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru