I'm attempting to complete HackerRank's Abbreviation challenge in Swift.
The physics for poets of what I'm trying to determine if a given abbreviation can be formed with a given string. You're given a string and an abbreviation they'd like formed with it. The curve ball is you can only delete characters or change their case...you can't swap indexes on them.
I'm able to complete most of the validating and cleanup of the string they give me, but I'm stuck on a part where I can only delete characters, but not swap indexes.
let abbrArray = abbreviation.characters.map({String($0)})
var matchingCharArray = capitalizedInputArray.filter({abbrArray.contains($0)})
I'm trying to run through each element of the abbreviation array remove characters at the front of the matchingCharArray
that don't match the character in the abbrArray
's index.
Here's my code for that portion:
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"
}
Here's a link to the code on Swift Sandbox .
Any suggestions re: how I can clean up my matchingCharArray
array without moving indexes is greately appreciated.
The trick with this challenge, is that you don't need to produce the output array , you simply need to answer "yes" or "no" as to whether you could produce the output array. And this answer can be determined by answering the question "Does the sequence of letters in the 'abbreviation' exist in the input string in order, given that there may be other characters between the target letters?" Of course, you also need to consider that some of the target letters may be in lower case.
Since the order of the strings is important, this pretty much rules out using sets. My approach would be:
My answer in Swift is:
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
}
Paulw11 answer is correct, thats what I did, but then if follow the explanation in the page, I got this to replace the stuck part for you, it should remove all unnecessary character from the matchingCharArray
, also you can use abbrArray.filter({capitalizedInputArray.contains($0)})
and compare the count
it with the abbrArray
itself then enough to replace the whole middle part already:
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)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.