Для личного назидания, я возился с .reduce()
Свифта и столкнулся с необычным поведением, которое я не могу понять.
Я потратил довольно много неожиданного времени (не менее 6 часов) на исследования и эксперименты, и я в замешательстве.
У меня есть два алгоритма (я написал второй.), Которые появляютсясделать то же самое, то есть посчитать количество символов (в данном случае «а»), которые появляются в бесконечной строке с повторяющимся узором.Оба алгоритма ведут себя одинаково примерно в 50% случаев.Один использует .reduce () дважды, а другой - рабочий - использует цикл for.
Алгоритм, который работает во всех случаях:
let str = readLine()!
let length = Int(readLine()!)!
let fullRepetitions = length / str.characters.count
let lengthLastRep = length % str.characters.count
var count = fullRepetitions * str.characters.reduce(0) { $1 == "a" ? $0 + 1 : $0 }
for i in 0..<lengthLastRep {
if str[str.index(str.startIndex, offsetBy: i)] == "a" {
count += 1
}
}
print(count)
Итот, который не , но должен , выглядит так:
let pattern = readLine()!
let length = Int(readLine()!)!
let fullyRepeatedPatterns = length / pattern.count
let lastPatternLength = pattern.count % length
var countOfAs = fullyRepeatedPatterns * pattern.reduce(0, { $1 == "a" ? $0 + 1 : $0 })
countOfAs += pattern
.prefix(upTo: pattern.index(pattern.startIndex, offsetBy: lastPatternLength - 1))
.reduce(0, { $1 == "a" ? $0 + 1 : $0 })
print(countOfAs)
По крайней мере, на поверхности они выглядят так, как будто они должны делать то же самое.Но они этого не делают.
Сначала я подумал, что нашел свою проблему при выполнении по модулю, чтобы получить длину последнего паттерна, , если я изменю 2-й алгоритм так, чтобы он был похож наво-первых, он не только прекращает выполнение в пограничных случаях, но и имеет серьезную ошибку во время выполнения. То есть изменение этого значения:
let lastPatternLength = pattern.count % length
На это:
let lastPatternLength = length % pattern.count
Вызывает сбой второго алгоритма с большим количеством .reduce () (ошибка времени выполнения), , поэтому я не думаю, что модуль вызывает ошибку.
Что еще интереснее, ошибки не согласованы.Вход с:
aab
882787
То есть "aab" повторяется 882787 раз, и это похоже на ошибку выключения одного ... Или то, что кажется отключением одного .Однако ...
let pattern = "aab"
let length = 882787
let fullyRepeatedPatterns = length / pattern.count
let lastPatternLength = pattern.count % length
var countOfAs = fullyRepeatedPatterns * pattern.reduce(0, { $1 == "a" ? $0 + 1 : $0 })
countOfAs += pattern
.prefix(upTo: pattern.index(pattern.startIndex, offsetBy: lastPatternLength - 1))
.reduce(0, { $1 == "a" ? $0 + 1 : $0 })
print("expected 588525 but got \(countOfAs)")
Я знаю правильный ответ заранее, поэтому могу сказать:
Я ожидал 588525, но получил 588526.
но при вводе:
babbaabbabaababaaabbbbbbbababbbabbbababaabbbbaaaaabbaababaaabaabbabababaabaabbbababaabbabbbababbaabb
860622337747
выключено на 27!
Наконец, , как будто бы очень раздражает специально , ввод:
ababa
3
отключен на -1.
Есть много случаев, когда оба алгоритма работают, например:
aba
10
Но меня это не волнует.
Может кто-нибудь объяснить, что яздесь не хватает?