Поскольку мне нравилось программировать на Scala, для интервью в Google я попросил их задать мне вопрос о стиле Scala/функциональном программировании. Вопрос о функциональном стиле Scala, который я получил, был следующим:
У вас есть две строки, состоящие из буквенных символов, а также специальный символ, представляющий символ возврата. Давайте назовем этот символ возврата '/'. Когда вы доберетесь до клавиатуры, вы наберете эту последовательность символов, включая символ возврата/удаления. Решение, которое вы должны реализовать, должно проверять, дают ли две последовательности символов одинаковый результат. Например, «abc», «aa/bc». «abb/c», «abcc/», «/abc» и «//abc» производят один и тот же вывод «abc». Поскольку это вопрос о Scala/функциональном программировании, вы должны реализовать свое решение в идиоматическом стиле Scala.
Я написал следующий код (может быть, это не совсем то, что я написал, я просто ухожу из памяти). В основном я просто прохожу по строке линейно, добавляя символы к списку, а затем сравниваю списки.
def processString(string: String): List[Char] = {
string.foldLeft(List[Char]()){ case(accumulator: List[Char], char: Char) =>
accumulator match {
case head :: tail => if(char != '/') { char :: head :: tail } else { tail }
case emptyList => if(char != '/') { char :: emptyList } else { emptyList }
}
}
}
def solution(string1: String, string2: String): Boolean = {
processString(string1) == processString(string2)
}
Все идет нормально? Затем он спросил временную сложность, и я ответил: линейное время (потому что вам нужно обработать каждый символ один раз) и линейное пространство (потому что вам нужно скопировать каждый элемент в список). Затем он попросил меня сделать это в линейном времени, но с постоянным пространством. Я не мог придумать способ сделать это, который был бы чисто функциональным. Он сказал попробовать использовать функцию в библиотеке коллекций Scala, такую как «zip» или «map» (я точно помню, как он произносил слово «zip»).
Вот в чем дело. Я думаю, что физически невозможно сделать это в постоянном пространстве без каких-либо изменяемых состояний или побочных эффектов. Как я думаю, что он перепутал вопрос. Что вы думаете?
Можете ли вы решить ее за линейное время, но с постоянным пространством?
immutability
является одним из краеугольных камней функционального программирования, вы обязаны создавать копии строки/списка/массива, а это означает, что делать что-либо из этого в постоянном пространстве не представляется возможным. А что касаетсяzip
, то любое его использование будет означать линейное пространство по определению. - person sarveshseri   schedule 09.09.2018String
нет необходимых частей, поэтому это кажется невозможным. Это было бы тривиально, например, если бы ввод был обратным списком символов. Другие идеи, такие как повторное использование частей входной строки, имеют ту же проблему: строки не имеют частей, поэтому вам придется вести список индексов срезов, но этот список занимает O (n) места. - person Jörg W Mittag   schedule 09.09.2018Array[Char]
, нам нужно будет изменить эти массивы, чтобы выполнять действия в постоянном пространстве. И изменчивость не распространяется на функциональные программы. - person sarveshseri   schedule 09.09.2018O(1)
дополнительном пространстве. - person Dici   schedule 09.09.2018solution
должен сравнивать два строковых описания, ему не нужно их нормализовать. Результатом являетсяBoolean
, который занимает постоянное место. - person Andrey Tyukin   schedule 09.09.2018f
! - person Jatin   schedule 09.09.2018O(1)
пространстве, но новая заархивированная коллекция займет линейное пространство. - person sarveshseri   schedule 09.09.2018