// use a default value for the lastchar for the first char,
// which is impossible to meet in an regular string
def concentrate (s: String, lastchar: Char = 0) : String = {
// recursive methods always need to know when it is enough
if (s.length == 0) s else
if (s(0) == lastchar) concentrate (s.substring (1), lastchar) else
s(0) + concentrate (s.substring (1), s(0)) }
concentrate ("AAAABCCDDDDAACCCCCC")
以下は末尾再帰のバリエーションです。
@tailrec
def concentrate (s: String, carry:String = "", lastchar: Char = 0) : String = {
if (s.length == 0) carry else
if (s(0) == lastchar) concentrate (s.substring (1), carry, lastchar) else
concentrate (s.substring (1), carry + s(0), s(0)) }
結果の文字列がその場で一緒に接着され、パラメーターとして渡されるため、最後の位置に再帰呼び出しがあります。Scala では、これはコンパイラによって最適化され、変更可能な変数を使用したループとほぼ同じ速度で実行され、スタックが爆発することはありません (非常に長い文字列の場合でも)。