Q re: limpiar una matriz sin mover índices

Estoy intentando completar el desafío Abreviatura de HackerRank en Swift.

La física para los poetas de lo que estoy tratando de determinar si una abreviatura dada se puede formar con una cadena dada. Se le da una cadena y una abreviatura que les gustaría formar con ella. La bola curva es que solo puedes eliminar caracteres o cambiar su mayúscula … no puedes intercambiar índices sobre ellos.

Soy capaz de completar la mayor parte de la validation y limpieza de la cadena que me dan, pero estoy atrapado en una parte donde solo puedo eliminar caracteres, pero no intercambiar índices.

let abbrArray = abbreviation.characters.map({String($0)}) var matchingCharArray = capitalizedInputArray.filter({abbrArray.contains($0)}) 

Estoy tratando de ejecutar cada elemento de la matriz de abreviaturas para eliminar los caracteres en la parte delantera de matchingCharArray que no coinciden con el carácter en el índice de abbrArray .

Aquí está mi código para esa porción:

 for index in 0..<abbrArray.count { let charToEvaluate = abbrArray[index] while matchingCharArray.first != charToEvaluate { matchingCharArray.removeFirst() } } if matchingCharArray.joined().range(of: abbreviation) == nil { return "NO" } 

Aquí hay un enlace al código en Swift Sandbox .

Cualquier sugerencia sobre cómo puedo limpiar mi matriz matchingCharArray sin mover índices es muy apreciada.

El truco con este desafío es que no es necesario que produzca la matriz de salida , simplemente tiene que responder "sí" o "no" para determinar si puede producir la matriz de salida. Y esta respuesta puede determinarse respondiendo a la pregunta "¿La secuencia de letras en la 'abreviatura' existe en la cadena de input en order, dado que puede haber otros caracteres entre las letras de destino?" Por supuesto, también debe considerar que algunas de las letras de destino pueden estar en minúsculas.

Dado que el order de las cadenas es importante, esto prácticamente descarta usar sets. Mi enfoque sería:

  1. Convierta toda la cadena de input en mayúscula
  2. Iterar a través de la cadena de input buscando el primer carácter en la abreviatura
  3. Si lo encuentras, vuelve al paso 2, busca el siguiente carácter en la abreviatura
  4. Si llega al final de la cadena de abreviaturas, regrese "SÍ"
  5. Si llega al final de la cadena de input antes de encontrar el carácter final en la abreviatura, regrese "NO".

Mi respuesta en Swift es:

 func canBeAbbreviated(input: String, abbreviation: String) -> String { var retValue = "NO" let inputCharacters = input.uppercased().characters let abbreviationCharacters = abbreviation.characters var inputIndex = inputCharacters.startIndex var abbreviationIndex = abbreviationCharacters.startIndex while abbreviationIndex < abbreviationCharacters.endIndex { while inputIndex < inputCharacters.endIndex { let iChar = inputCharacters[inputIndex] let aChar = abbreviationCharacters[abbreviationIndex] inputIndex = inputCharacters.index(after: inputIndex) if iChar == aChar { abbreviationIndex = abbreviationCharacters.index(after: abbreviationIndex) break } } if inputIndex == inputCharacters.endIndex { break; } } if abbreviationIndex == abbreviationCharacters.endIndex { retValue = "YES" } return retValue } 

La respuesta de Paulw11 es correcta, eso es lo que hice, pero luego, si sigue la explicación en la página, conseguí que esto reemplace la parte atascada por ti, debería eliminar todo el carácter innecesario de matchingCharArray , también puedes usar abbrArray.filter({capitalizedInputArray.contains($0)}) y compare la count con el abbrArray sí mismo, suficiente para replace toda la parte media ya:

 var i = 0 var indexToRemove = [Int]() for char in abbrArray { while i < matchingCharArray.count { if matchingCharArray[i] != char { indexToRemove.append(i) i+=1 } else { i+=1 break } } } if i < matchingCharArray.count - 1 { matchingCharArray.removeSubrange(i...matchingCharArray.count-1) } for j in indexToRemove.reversed() { matchingCharArray.remove(at: j) }