Я готовлюсь к собеседованию, которое у меня есть в понедельник, и я нашел эту проблему для разрешения «String Reduction». Задача формулируются следующим образом:Решение алгоритма сокращения строк
Учитывая строку, состоящую из а, Ь и с, мы можем выполнить следующую операцию : Возьмите любые два смежных различные символы и заменить его с третьим символом. Например, если «a» и «c» смежны, они могут быть заменены на «b». Что представляет собой наименьшая строка, которая может получить результат , применяя эту операцию повторно?
Например, кабины -> cc или кабины -> bb, что приводит к веревке длины 2. Для этого одним из оптимальных решений является: bcab -> aab -> ac -> b. Больше никаких действий не могут быть применены и результирующая строка имеет длину 1. Если строка = CCCCC, никакие операции не могут быть выполнены и поэтому ответ 5.
Я видел много questions and answers на StackOverflow, но Я хотел бы проверить свой собственный алгоритм. Вот мой алгоритм в псевдокоде. В моем коде
- S моя строка уменьшить
- S [I] является символ с индексом я
- P является стек:
перевождь это функция, которая уменьшает символы.
function reduction(S[1..n]){ P = create_empty_stack(); for i = 1 to n do car = S[i]; while (notEmpty(P)) do head = peek(p); if(head == car) break; else { popped = pop(P); car = redux (car, popped); } done push(car) done return size(P)}
Наихудший моих алгоритмов представляет собой О (п), так как все операции на стеке P на O (1). Я пробовал этот алгоритм в приведенных выше примерах, я получаю ожидаемые ответы. Позвольте мне выполнить мой Algo с этим примером «abacbcaa»:
i = 1 :
car = S[i] = a, P = {∅}
P is empty, P = P U {car} -> P = {a}
i = 2 :
car = S[i] = b, P = {a}
P is not empty :
head = a
head != car ->
popped = Pop(P) = a
car = reduction (car, popped) = reduction (a,b) = c
P = {∅}
push(car, P) -> P = {c}
i = 3 :
car = S[i] = a, P = {c}
P is not empty :
head = c
head != car ->
popped = Pop(P) = c
car = reduction (car, popped) = reduction (a,c) = b
P = {∅}
push(car, P) -> P = {b}
...
i = 5 : (interesting case)
car = S[i] = c, P = {c}
P is not empty :
head = c
head == car -> break
push(car, P) -> P = {c, c}
i = 6 :
car = S[i] = b, P = {c, c}
P is not empty :
head = c
head != car ->
popped = Pop(P) = c
car = reduction (car, popped) = reduction (b,c) = a
P = {c}
P is not empty : // (note in this case car = a)
head = c
head != car ->
popped = Pop(P) = c
car = reduction (car, popped) = reduction (a,c) = b
P = {∅}
push(car, P) -> P = {b}
... and it continues until n
Я запустить этот алгоритм на различных примерах, как это, кажется, работает. Я написал код на Java, который проверяет этот алгоритм, когда я отправляю свой код в систему, я получаю неправильные ответы. Я разместил код java на gisthub, чтобы вы могли его увидеть.
Может кто-нибудь сказать мне, что не так с моим алгоритмом.
Он просит наименьшему строки, то это означает, что если есть более чем один способ уменьшить цепочку, должны найти его. Кажется, вы только ищите первый способ сокращения, конечно, это провалится. Иногда, не используя правило и ждать появления большего количества символов, может привести к лучшему результату. – nhahtdh
@acattle yeap, но только в первом случае, первый символ. В каждом for-loop стек будет иметь хотя бы один символ. – Dimitri
@nhahtdh вы можете быть более конкретным? – Dimitri