Редакция для Двойной шестнадцатеричный код в строку
Submitting an official solution before solving the problem yourself is a bannable offence.
1. Идея
Нужно снять два одинаковых слоя шестнадцатеричного кодирования.
Один слой работает так:
- берётся символ,
- его ASCII-код переводится в шестнадцатеричный вид,
- записывается ровно двумя символами,
- все такие пары склеиваются в одну строку.
Если такое преобразование применили два раза, то для восстановления исходного сообщения достаточно:
- один раз декодировать входную строку из шестнадцатеричного вида;
- ещё раз декодировать полученный результат.
То есть задача сводится к двойному применению одной и той же функции декодирования.
2. Наблюдения
Наблюдение 1
Если строка закодирована одним слоем, то каждые 2 символа в ней — это шестнадцатеричная запись ASCII-кода одного символа.
Например:
41→ символ'A',48→ символ'H',69→ символ'i'.
Наблюдение 2
После первого декодирования получится не исходное сообщение, а строка, которая сама является результатом одного шестнадцатеричного кодирования.
Например, для входа 3431:
- пара
34означает символ'4', - пара
31означает символ'1'.
Значит, после первого декодирования получаем строку 41.
Но 41 — это тоже шестнадцатеричное представление ASCII-кода символа 'A'.
После второго декодирования получаем A.
Наблюдение 3
По условию гарантируется, что строка корректна и действительно получена таким способом. Значит:
- длина входа чётная;
- после первого декодирования тоже получится корректная строка для второго декодирования.
3. Алгоритм
Сделаем функцию decode_hex(s), которая:
- идёт по строке
sс шагом 2; - берёт очередные два символа;
- переводит их из шестнадцатеричной системы в число;
- превращает это число в символ;
- добавляет символ в ответ.
После этого:
- читаем входную строку
s; - вычисляем
first = decode_hex(s); - вычисляем
second = decode_hex(first); - выводим
second.
4. Почему это работает
Докажем, что алгоритм восстанавливает исходную строку.
Пусть исходная строка равна T.
После одного кодирования каждый символ строки T заменяется двумя шестнадцатеричными цифрами его ASCII-кода. Получается строка E(T).
После второго кодирования аналогичная операция применяется к строке E(T). Получается итоговая строка E(E(T)). Именно она дана во входных данных.
Функция decode_hex выполняет обратное действие к одному слою кодирования:
- каждые 2 шестнадцатеричные цифры переводятся в число;
- это число интерпретируется как ASCII-код символа;
- из таких символов собирается строка.
Следовательно:
decode_hex(E(E(T))) = E(T),decode_hex(E(T)) = T.
Значит, после двух применений decode_hex мы получаем исходную строку T.
Следовательно, алгоритм работает правильно.
5. Сложность
Пусть длина входной строки равна n.
Один вызов decode_hex обрабатывает строку по парам символов, то есть работает за O(n).
Так как декодирование выполняется два раза, общая сложность остаётся линейной: O(n).
Дополнительная память:
- на результат первого декодирования,
- на результат второго декодирования.
Итого O(n) дополнительной памяти.
6. Код на C++17
#include <iostream>
#include <string>
using namespace std;
string decode_hex(const string& s) {
string result;
result.reserve(s.size() / 2);
for (size_t i = 0; i < s.size(); i += 2) {
string part = s.substr(i, 2);
int value = stoi(part, nullptr, 16);
result.push_back(static_cast<char>(value));
}
return result;
}
int main() {
string s;
cin >> s;
string first = decode_hex(s);
string second = decode_hex(first);
cout << second;
return 0;
}
7. Код на Python 3
def decode_hex(s):
result = []
for i in range(0, len(s), 2):
part = s[i:i + 2]
value = int(part, 16)
result.append(chr(value))
return ''.join(result)
s = input()
first = decode_hex(s)
second = decode_hex(first)
print(second)
Комментарии