Home > other >  ArrayBuffer elements are not being swapped in Scala
ArrayBuffer elements are not being swapped in Scala

Time:10-19

The below is the Scala Code for finding the permutations of the given digits using the Johnson-Trotter algorithm:-

 import scala.collection.mutable.ArrayBuffer

 object Code{

    def factorial(x:Int):Int={
        if(x==0) return 1 else x*factorial(x-1)
    }

    def permutation(arr:ArrayBuffer[Int]):ArrayBuffer[ArrayBuffer[Int]]={
        val len=arr.length;
        var result=new ArrayBuffer[ArrayBuffer[Int]]

        for(i<-Range(0,factorial(len)/len,1)){
            if(i%2==0){
                for(j<-Range(len-1,0,-1)){
                    var c=arr(j)
                    arr(j)=arr(j-1)
                    arr(j-1)=c
                    result.append(arr)
                }
                var c=arr(len-1)
                arr(len-1)=arr(len-2)
                arr(len-2)=c
                result.append(arr)
            }
            else{
                for(j<-Range(0,len-1,1)){
                    var c=arr(j)
                    arr(j)=arr(j 1)
                    arr(j 1)=c
                    result.append(arr)
                }
                var c=arr(0)
                arr(0)=arr(1)
                arr(1)=c
                result.append(arr)
            }
        }
        return result
    }

    def main(args:Array[String]):Unit={
        var arr=ArrayBuffer(1,2,3)
        var perm=permutation(arr)
        for(j<-Range(0,perm.length,1)){
            for(k<-Range(0,perm(0).length,1)){
                println(" " perm(j)(k))
            }
            println()
        }      
    }
}

But, the resultant two dimensional ArrayBuffer contains (1,2,3) six times for the ArrayBuffer input of (1,2,3) instead of showing all the permutations. I believe that the elements are not being swapped. What am I doing wrong here ? Would really appreciate the help.

CodePudding user response:

Array (same as ArrayBuffer) in scala is mutable. When you do result.append(arr), you're adding the references to the same array to the result. When arr is then modified, the modification can be observed in all elements of the result.

One way to fix your code is to replace all instances of result.append(arr) with result.append(arr.clone()).

That is correct, but not very efficient. Another, slightly more efficient approach would be to use Vector[Int] instead of ArrayBuffer, which is immutable and uses structural sharing to perform more efficient updates.

See also How to update a specific element in Immutable Array using Scala

  • Related