Задний план
Инцидент - довольно необычный язык программирования, в котором его список токенов не предопределен, а скорее выведен из входных данных. Таким образом, токенизация программы «Инцидент» может быть довольно сложной, особенно если вы хотите сделать это эффективно. Эта задача о том, чтобы сделать это самостоятельно.
Задание
Ваша программа получит строку в качестве ввода. Вот алгоритм, который использует Incident для токенизации:
- Идентифицируйте все строки, которые встречаются как подстрока ввода, точно тремя способами (то есть есть ровно три вхождения этой строки во входных данных).
- Откажитесь от любой из этих строк, которые являются подстрокой другой такой строки (например, для ввода
ababab
единственной оставшейся строкой будетab
, а неa
илиb
, потому чтоa
иb
обе являются подстрокамиab
). - Откажитесь от любых строк, которые перекрываются внутри ввода. (Например,
aaaa
содержит ровно три копииaa
, но эти копии пересекаются со вторым и третьим символами, поэтому будут отброшены. Аналогичноabababa
, существует три копииab
и три копииba
, но каждый со второго по шестой символы находятся на перекрытия aab
и aba
, поэтому обаab
иba
будут отброшены). - Любые строки, которые остаются в этой точке, являются токенами, используемыми программой. Токенизируйте исходный вход в последовательность этих токенов (из-за сброса на предыдущем шаге будет только один способ сделать это). Любые символы на входе, которые не являются частью какого-либо токена, рассматриваются как комментарии и отбрасываются.
Ваша программа должна принять строку в качестве входных данных и вернуть соответствующий токенизацию строки (список токенов, каждый из которых выражен в виде строк) в качестве выходных данных. Кроме того, это должно быть сделано по крайней мере умеренно эффективно; в частности, программа должна запускаться за квадратичное время («O (n²)») или лучше. (Между прочим, почти наверняка возможно пойти быстрее, чем квадратичный, но это не самый быстрый алгоритм , поэтому не стесняйтесь использовать самый краткий алгоритм, который вы можете найти, который вписывается в пределы сложности.)
Разъяснения
- Хотя программы Incident теоретически могут содержать любой из 256 октетов, для этой задачи для вашей программы приемлемо обрабатывать только входные данные, сформированные из печатного ASCII (включая пробел), плюс перевод строки и табуляцию. (Все известные программы Incident ограничиваются этим подмножеством). Обратите внимание, что пробел / новая строка / табуляция не являются особыми и могут появляться в середине токенов; Инцидент рассматривает все 256 октетов как непрозрачные.
- Определение «квадратичного времени»: «если размер входных данных удвоится, программа будет работать медленнее не более чем на константу плюс коэффициент 4», т. Е. Если t ( x ) - максимальное время, необходимое вашей программе для обработать ввод размера x , тогда должна быть некоторая константа k такая, что t (2 x ) <4 t ( x ) + k для всех x . Имейте в виду, что сравнение строк занимает время, пропорциональное длине строк.
- Ваша программа теоретически должна иметь возможность обрабатывать входные программы любой длины, если они запускаются в (возможно, гипотетическом) варианте вашего языка, который имеет неограниченную память и использует неограниченные целые числа (это нормально, если программа не может достичь этой цели при запуске на практике из-за целые числа или память языка на самом деле очень большие). Вы можете предположить (для целей расчета сложности), что целые числа, которые не превышают длину ввода, можно сравнивать в постоянное время (хотя имейте в виду, что если вы используете большие значения, например, из-за преобразования входных данных в одно целое число, они будут сравниваться пропорционально количеству цифр, которые у них есть).
- Вы можете использовать любой алгоритм, который укладывается в пределы сложности, даже если он не выполняет те же шаги, что и алгоритм, описанный выше, при условии, что он дает те же результаты.
- Эта головоломка о токенизации ввода, а не о форматировании вывода. Если наиболее естественный способ вывода списка на вашем языке связан с неоднозначным форматом (например, с разделением новой строки, когда строки содержат буквальные переводы строки, или без разделителей между строками), не беспокойтесь о том, что вывод заканчивается неоднозначно ( до тех пор, пока список фактически построен). Возможно, вы захотите сделать вторую версию вашего представления, которая дает однозначный вывод, чтобы помочь в тестировании, но исходная версия - это версия, которая имеет значение для оценки.
Прецедент
Для следующей входной строки:
aaabcbcbcdefdfefedghijghighjkllkklmmmmonono-nonppqpq-pqprsrsrstststuvuvu
Ваша программа должна создать следующий список вывода:
a a a bc bc bc d e f d f e f e d gh gh gh k l l k k l pq pq pq u u u
Состояние победы
Это код-гольф , поэтому выигрывает самая короткая действующая (то есть правильная программа ввода-вывода и достаточно быстрая для выполнения) программа, измеренная в байтах.