Когда я понял в первых задачах 10-ой лекции, что они построены без учёта методов, которые давались ранее, я действовал по принципу:
1. написать план решения
2. поискать в Google методы, которые решали бы описанную в плане задачу, если такой метод я не вспомнил исходя из предыдущих лекций.
Я подумал будет полезным создать тут тему, чтобы вместо Googla обсуждать тут кто как решал и какие методы использовал.
Я сразу исключил идею решать через перебор соответствий (как оказалось в правильном решении), потому что мне это показалось примитивным. Ранее было такое, что я писал "простой" длинный код, а правильное решение оказывалось лаконичным. В этот раз вышло наоборот. Я пытался сделать код максимально "автоматическим", без перебора. Проверку пройти удалось. Но осталось ощущение, все таки, что решение какое-то корявое...
package com.javarush.task.pro.task09.task0908;
import java.util.regex.Pattern;
/*
Двоично-шестнадцатеричный конвертер
*/
public class Solution {
public static void main(String[] args) {
String binaryNumber = "100111010000";
System.out.println("Двоичное число " + binaryNumber + " равно шестнадцатеричному числу " + toHex(binaryNumber));
String hexNumber = "9d0";
System.out.println("Шестнадцатеричное число " + hexNumber + " равно двоичному числу " + toBinary(hexNumber));
}
public static String toHex(String binaryNumber) {
String HEX = "0123456789abcdef";
/*
строка содержащая символы 16-ричной системы
*/
String hn = "";
/*
строка с результатом - hexNumber
*/
if (binaryNumber == null || !(binaryNumber.matches("[01]+"))) /
/*
я так и не понял как в правильном решении происходит выполнение условий:
- Если входящий параметр метода toHex(String) содержит любой символ, кроме 0 или 1, то метод
возвращает пустую строку.
- Если входящий параметр метода toBinary(String) содержит любой символ, кроме цифр от 0 до 9
или латинскую букву от a до f (в нижнем регистре), то метод возвращает пустую строку.
там есть только проверка на null.
Буду рад, если кто-то объяснит.
*/
return hn;
else {
/*
создаем цикл по переменной "длина бинарного числа". Причем в счетчике есть встроенный костыль,
смысл которого станет яснее позже. Данный цикл for должен пройтись по всем символам в строке
"бинарное число". Каждые 4 бита, начиная справа и налево в бинарном числе соответствуют одному
символу 16-ричного числа. Поэтому внутри цикла for ставится еще один цикл for со счетчиком 4,
который и будет отделять четверку символов от следующей четверки. Переменная h будет
накапливать сумму, которую образуют согласно десятичной системе числа каждой четверки битов.
Считаться число h будет согласно предыдущим задачам в лекции через конвертер. Метод
Character.getNumericValue(binaryNumber.charAt(l)) берет числовое значение символа находящегося
в строке binaryNumber под индексом l и умножает его на 2 в степени j. Как только первая четверка
будет готова, внутренний цикл закончится и символ 16-ричного числа соответствующий этой 4-ке
битов будет добавлен к строке hn. Если же битовая строка закончится внутри внутреннего цикла,
сработает проверка и цикл прервется. Но так как внутри цикла индекс бинарного символа уже
сдвигался - нужно его вернуть на место (l++), чтобы внешний цикл закончился нормально.
*/
for (int l = binaryNumber.length() - 1; l >= 0; l--) {
int h = 0;
int j = 0;
for (int i = 4; i > 0; i--) {
h = h + Character.getNumericValue(binaryNumber.charAt(l)) * (int) (Math.pow(2, j));
j++;
l--;
if (l < 0) {
break;
}
}
hn = HEX.charAt(h) + hn;
l++;
}
}
return hn;
}
public static String toBinary(String hexNumber) {
String HEX = "0123456789abcdef";
String bn = "";
/*
Примерно так же работает обратный конвертер. Берем количество символов 16-ричного числа i.
Цикл while будет работать пока символы не закончатся. Переменная z найдет в строке HEX
16-ричную цифру и выдаст ее индекс, который соответствует десятичному числу от 0 до 15.
Нам это десятичное число нужно перевести в двоичное с условием, чтобы оно в любом случае
содержало 4 символа. Создаем внутренний цикл while со счетчиком 4. Если перевод десятичного
числа в бинарное закончится до того как будут заполнены все 4 места - цикл допишет нули.
Это в свою очередь вызовет "некрасивость" этого решения, потому что в некоторых случаях
конвертер будет выводить строки с нулями впереди - это не нарушение, но все же не идеальное
решение.
*/
if (hexNumber == null || !(hexNumber.matches("[0123456789abcdef]+")))
return bn;
else {
int i = hexNumber.length();
while (i > 0) {
int z = HEX.indexOf(hexNumber.charAt(i - 1));
String xn = "";
int j = 4;
while (j > 0) {
if (z != 0) {
while (z != 0) {
int b = z % 2;
z = z / 2;
xn = b + xn;
j--;
}
} else {
xn = 0 + xn;
j--;
}
}
bn = xn + bn;
i--;
}
}
return bn;
}
}