@Nikita1244
Anonymous

Как можно перебирать слова в C++?

Есть задача.
Пользователь введет несколько слов в wcin. Запишем. Затем есть функция decrypt(), которая должна преобразовать слова в нужные символы. Для этого нужен не перебор символов, как было в моем случае раньше, а перебор слов. Гуглил, гуглил, но не нашел подходящего решения.
Отмечу, что пользователь не должен вводить количество слов. Это должна считать сама программа. Внутри конструкции для перебора слов должен быть switch/case, которые будут сравнивать слово и заменять нужными символами.

Пример строки:
•− −−•• −••• ••− −•− •− −− −−− •−• −−•• •

Программа должна понять, что тут 11 слов. Затем перебирать их. Затем создавать переменную, в которую будет записываться преобразованный текст. И так до конца(до 11 слова).
И программа должна преобразовать в это:
АЗБУКА МОРЗЕ
Слова разделяются пробелами.
  • Вопрос задан
  • 332 просмотра
Решения вопроса 3
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Раз у вас во вводе коды каждого символа разделены пробелами, то все просто. Заведите в программе map<wstring, wchar> и где-то в начале напишите 33 строчки вида:
dict[L"•−"] = L'А';

Потом входную строку разбейте на части по проблелам. Руками, циклом. Указатель-индекс будет указывать на первый необработанный символ. Найдите первый пробел или конец строки начиная с этой позиции. Кусок между двумя позициями - это текущий код. Его с помощью map'а выше переводите в символ. Сдвигайте индекс первого необработанного символа на позицию после пробела. Ну и аккуратно смотрите, если первый необработанный - пробел, то это пробел между словами - его как есть и выводите, сдвигая индекс необработанного символа на 1.
Ответ написан
HemulGM
@HemulGM
Delphi Developer, сис. админ
Вот как делается на Делфи. Вдруг будет полезно
uses
  System.SysUtils, System.Generics.Collections, Winapi.Windows;

begin
  SetConsoleCP(CP_UTF8);
  SetConsoleOutputCP(CP_UTF8);

  var Map := TDictionary<string, Char>.Create;
  Map.Add('',     ' ');
  Map.Add('•−',   'А');
  Map.Add('−•••', 'Б');
  Map.Add('•',    'Е');
  Map.Add('−−••', 'З');
  Map.Add('−•−',  'К');
  Map.Add('−−',   'М');
  Map.Add('−−−',  'О');
  Map.Add('•−•',  'Р');
  Map.Add('••−',  'У');

  var a := '•− −−•• −••• ••− −•− •−   −− −−− •−• −−•• •'.Replace('   ', '  ').Split([' ']);
  var c: Char;
  for var s in a do
    if Map.TryGetValue(s, c) then Write(c) else Write('?');

  Map.Free;
  readln;
end.
Ответ написан
TrueBers
@TrueBers
Гуглю за еду
Обычно, слова в коде Морзе в рукописном варианте делят не пробелами, а прямым слешем: "/". А если в кодировке, то 7-ю длительностями низкого уровня.

Словарь на такое мизерное количество ключей будет иметь на порядок больше оверхеда, чем простой линейный поиск в массиве:

C++23
#include <string>
#include <string_view>
#include <ranges>
#include <array>
#include <utility>
#include <algorithm>
#include <cassert>
#include <stdexcept>

template <typename Key, typename Value, std::size_t Size>
struct Map {
	std::array<std::pair<Key, Value>, Size> data;

	constexpr Value at(const Key key) const {
		const auto iter = std::find_if(std::begin(data), std::end(data),
			[&key](const auto& v) { return v.first == key; });

		if (iter == std::end(data)) {
			throw std::range_error("unknown character");
		}
		return iter->second;
	}
};

static constexpr std::array<std::pair<std::string_view, char>, 51> MORSE_MAP = { {
	{"•-", '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'},    {"-----", '0'},  {"•----", '1'},
	{"••---", '2'},   {"•••--", '3'},   {"••••-", '4'},  {"•••••", '5'},
	{"-••••", '6'},   {"--•••", '7'},   {"---••", '8'},  {"----•", '9'},
	{"•-•-•-", '.'},  {"--••---", ','}, {"---•••", ':'}, {"••--••", '?'},
	{"•----•", '\''}, {"-••••-", '-'},  {"-••-•", '/'},  {"-•--•", '('},
	{"-•--•-", ')'},  {"•-••-•", '"'},  {"-•••-", '='},  {"•-•-•", '+'},
	{"-••-", 'x'},    {"•--•-•", '@'},  {"/", ' '} } };

constexpr auto decode(std::string_view morse) {
	constexpr auto map = Map<std::string_view, char, MORSE_MAP.size()>{ MORSE_MAP };
	return morse
		| std::ranges::views::split(' ')
		| std::ranges::views::transform([](auto&& range) {
			return map.at(std::string_view{ range });
		})
		| std::ranges::to<std::string>();
}

int main() {
	const auto CODE = "•••• • •-•• •-•• --- --••--- / •-- --- •-• •-•• -••";
	const auto TEXT = "HELLO, WORLD";

	assert(decode(CODE) == TEXT);

	return 0;
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы