Предопределенные замены текста в C ++ и Python - PullRequest
3 голосов
/ 15 сентября 2010

В качестве хобби-проекта мне хотелось реализовать кодировщик и декодер азбуки Морзе на C ++ и Python (оба).Мне было интересно, какую структуру данных мне следует использовать для этого.Этот вопрос связан не только с этим конкретным проектом, но в целом, когда нужно сделать предопределенные замены текста, каков наилучший и самый быстрый способ сделать это?

Я бы не стал заново изобретать любые данныеструктура, если это возможно (и я думаю, что это так).Обратите внимание, что это чисто учебное упражнение, и я всегда задавался вопросом, как лучше всего это сделать.Я могу сохранить код и соответствующий символ в словаре, возможно, затем перебирать текст и делать замены.Это лучший способ сделать это или я могу сделать лучше?

Ответы [ 7 ]

3 голосов
/ 15 сентября 2010
from collections import defaultdict

morsecode = [('a','._'), ('b','_...'), ('c','_._.')]
codedict = defaultdict(lambda:' ')
for k,v in morsecode:
    codedict[k] = v

tomorse = lambda x: ' '.join([codedict[chr] for chr in x])

print tomorse('bab cab')

Дает:

_... ._ _...   _._. ._ _...
2 голосов
/ 15 сентября 2010

Со стороны Python наилучшим способом является функция перевода класса string.На стороне C ++ я бы использовал std :: map для хранения сопоставления символов.Тогда я бы, вероятно, использовал std :: for_each для поиска и замены.

2 голосов
/ 15 сентября 2010

Вы можете использовать str.translate:

m = {ord('S'): '---', ord('O'): '...'}
print('S O S'.translate(m))

напечатает:

--- ... ---
2 голосов
/ 15 сентября 2010

В Python строки являются неизменяемыми, поэтому, вероятно (в зависимости от того, что вы делаете с выводом), вы хотите создать список всех простых результатов подстановки. Что-то вроде:

MORSE = {'A': '.-', ...}

def morsify(data):
    return [MORSE[c] for c in data if c in MORSE]

Вам нужно было бы стать более любопытным, если вы хотите поддерживать разные национальные версии азбуки Морзе и т. Д.

(отредактировано для учета того факта, что азбука Морзе, по-видимому, не является префиксным кодом).

1 голос
/ 15 сентября 2010

Первое попадание на Google .

В зависимости от количества текста будет работать 'foo'.replace (' f ',' ..-. '). Replace (' o ',' --- ').

Если вы не переводите тысячи строк текста, вы, вероятно, не заметите большой разницы в любом используемом вами методе, хотя вы можете легко использовать модуль timeit для тестирования каждого отдельного метода.

1 голос
/ 15 сентября 2010

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

Мой официальный совет - придерживаться этого. Производительность поиска вряд ли будет проблемой для такого кода, поскольку, скорее всего, вы можете легко кодировать / декодировать быстрее, чем вы можете вводить / выводить.

Поскольку это учебное упражнение, и вы хотите опробовать различные возможности: для текста -> Морзе вы можете использовать массив, а не карту / словарь. Возможно удивительно, это трудно сделать в C ++ и быть полностью переносимым. Далее предполагается, что все заглавные буквы имеют значения char, превышающие A, что не гарантируется стандартом:

std::string encode['Z'-'A'];
encode['A' - 'A'] = ".-";
encode['B' - 'A'] = "-...";
// etc.
encode['Z' - 'A'] = "--..";

Если вы хотите предположить, что ваш код будет работать только на машинах, базовый набор символов которых содержит буквы в непрерывном режиме (верно для ASCII, но не для EBCDIC), вы можете немного привести его в порядок:

std::string encode[26] = {".-", "-...", /* etc */ "--.."};

Для поиска символа, хранящегося в переменной c:

morse = encode[c - 'A'];

Версия Python может предполагать ASCII (я думаю), и вам придется добавить некоторое использование ord.

Чтобы справиться с чем-либо, кроме букв верхнего регистра, вам нужен либо больший массив (содержащий запись для каждого возможного значения символа), либо несколько массивов с проверками границ, специальным кодом для пунктуации и т. Д.

0 голосов
/ 20 декабря 2010

Python (ожидает строку):

def m(t):
 m=0xBFAFA7AEA1A0B0B8BCBE121A021D11120C41888A642082668040876584434267868D626021618163898B8C
 r=[]
 for c in t.upper():
  val=int((m/(256**(90-ord(c))))%256)
  r.append("".join([str((val>>y)&1) for y in range(val/32-1,-1,-1)]))
 return " ".join(r)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...