Me estoy preparando para una entrevista que tengo el lunes y encontré este problema para resolver llamado "String Reduction". El problema se plantea así:Resolviendo Algoritmo de reducción de cadena
Dada una cadena que consta de A, B y C de, podemos realizar la siguiente operación : Tomar dos caracteres distintos adyacentes y reemplazarlo con el tercer personaje. Por ejemplo, si 'a' y 'c' son adyacentes, pueden reemplazarse por 'b'. ¿Cuál es la cadena más pequeña que puede resultar aplicando esta operación repetidamente?
Por ejemplo, cab -> cc o cab -> bb, lo que resulta en una cadena de longitud 2. Para esta, una solución óptima es: bcab -> aab -> ac -> b. No hay más operaciones pueden ser aplicadas y la cadena resultante tiene longitud 1. Si la cadena es = CCCCC, no hay operaciones se pueden realizar y por lo tanto la respuesta es 5.
he visto mucho questions and answers en StackOverflow pero Me gustaría verificar mi propio algoritmo. Aquí está mi algoritmo en pseudo código. En mi código
- S es mi cadena para reducir
- S [i] es el carácter en el índice i
- P es una pila:
Redux es la función que reduce los personajes.
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)}
El peor caso de mis algoritmos es O (n), ya que todas las operaciones en la pila P está en O (1). Probé este algoritmo en los ejemplos anteriores, obtengo las respuestas esperadas. Déjame ejecuto mi algo con este ejemplo "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
he ejecutar este algoritmo en varios ejemplos como este, parece que funciona. He escrito un código en Java que prueba este algoritmo. Cuando envío mi código al sistema, obtengo respuestas incorrectas. He publicado el código de Java en gisthub para que pueda verlo.
¿Puede alguien decirme qué está mal con mi algoritmo?
Se está pidiendo la cadena más pequeña, entonces significa que si hay más de una manera de reducir la cadena, tiene que encontrarlo Parece que solo busca la primera forma de reducción, por supuesto, fallará. A veces, no usar una regla y esperar a que aparezcan más caracteres puede dar como resultado un mejor resultado. – nhahtdh
@acattle yeap, pero solo en el primer caso, el primer personaje. En cada bucle for, la pila tendrá al menos un personaje. – Dimitri
@nhahtdh ¿puedes ser más específico? – Dimitri