Ниже представлена реализация функции, которая возвращает лексографически следующую перестановку. Это полезно в одной из проблем Эйлера.
Он написан для работы со строками (которые мне для этого понадобились). Однако он должен работать с любой проиндексированной последовательностью сопоставимых значений. Я попытался обобщить это, изменив два вхождения String на IndexedSeq [Char], но получаю сообщение об ошибке:
euler-lib.scala:26: error: type mismatch;
found : IndexedSeq[Char]
required: String
((n.slice(pivot+1, successor):+ n(pivot)) + n.drop(successor+1)).reverse
^
Почему модуль вывода типа вывел там String? Кажется, я не выполнял никаких операций, требующих String?
И могу ли я сделать это еще более общим, используя IndexedSeq ["что-то-сопоставимое"]? Мне не удалось выполнить эту работу.
// return the lexographically next permutation to the one passed as a parameter
// pseudo-code from an article on StackOverflow
def nextPermutation(n:String):String = {
// 1. scan the array from right-to-left
//1.1. if the current element is less than its right-hand neighbor,
// call the current element the pivot,
// and stop scanning
// (We scan left-to-right and return the last such).
val pivot = n.zip(n.tail).lastIndexWhere{ case (first, second) => first < second }
//1.2. if the left end is reached without finding a pivot,
// reverse the array and return
// (the permutation was the lexicographically last, so its time to start over)
if (pivot < 0) return n.reverse
//2. scan the array from right-to-left again,
// to find the rightmost element larger than the pivot
// (call that one the successor)
val successor = n.lastIndexWhere{_ > n(pivot)}
//3. swap the pivot and the successor, and
//4. reverse the portion of the array to the right of where the pivot was found
return (n.take(pivot) :+ n(successor)) +
((n.slice(pivot+1, successor):+ n(pivot)) + n.drop(successor+1)).reverse
}