You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala中向多个方法传递同一数组数据的问题求解

问题原因与解决方案

你遇到的问题核心是Scala中数组是可变的引用类型——当你把array传递给One和Two方法时,传递的不是数组的副本,而是指向原始数组内存地址的引用。第一个方法One里直接修改了数组元素(比如arr(i)(1) -= q、arr(i)(1) = 0这些操作),这些修改会直接作用在原始数组上,等调用Two方法时,自然拿到的是已经被改得面目全非的数组了。

要让两个方法都拿到原始的同一组数据,你需要给每个方法传递原始数组的深拷贝,确保它们操作的是独立的副本,互不干扰。

具体实现步骤

因为你用的是二维数组,普通的clone()只能做浅拷贝(外层数组是新的,但内层的每个小数组还是引用原始数据),所以需要做深拷贝:

方案1:在调用方法时传递拷贝后的数组

修改main方法里的调用逻辑,给每个方法传递独立的深拷贝:

object Demo {
  def main(args: Array[String]): Unit = {
    println("Enter number of process:");
    val n = scala.io.StdIn.readInt();
    var array: Array[Array[Double]] = Array.ofDim(n, 2)
    var bt: Double = 0
    var at: Double = 0
    for (i <- 0 to n - 1) {
      println("Enter BT for process: " + i);
      bt = scala.io.StdIn.readDouble();
      println("Enter AT for process: " + i);
      at = scala.io.StdIn.readDouble();
      array(i)(0) = at
      array(i)(1) = bt
    }
    // 给One方法传递深拷贝
    One(n, array.map(_.clone()))
    // 给Two方法传递深拷贝(基于原始array)
    Two(n, array.map(_.clone()))
  }

  // 下面的One和Two方法保持原样即可
  def One(n: Int, data: Array[Array[Double]]): Unit = {
    var q = 0.0
    var arr = data
    arr = arr.sortBy(x => x(1))
    var arr_copy = arr
    var wt = new Array[Double](n)
    var a = new Array[Double](n)
    var tat = new Array[Double](n)
    var new_tat = new Array[Double](n)
    var new_wt = new Array[Double](n)
    var D_Sum = 0.0
    var sum = 0.0
    for (i <- 0 to n - 1) {
      a(i) = arr(i)(1)
    }
    for (i <- 0 to n - 1) {
      wt(i) = 0
    }
    var tracker = 0.0
    var li = 0
    var updated_TAT = 0.0
    do {
      D_Sum = 0.0
      arr = arr.filterNot(x => x(1) <= 0)
      for (i <- 0 to arr.size - 1) {
        D_Sum = D_Sum + arr(i)(1)
      }
      q = math.round(math.sqrt(arr.length * D_Sum * 1.49))
      for (i <- 0 to arr.size - 1) {
        if (tracker >= arr(i)(0)) {
          if (arr(i)(1) > q) {
            arr(i)(1) -= q
            tracker = tracker + q
            for (j <- 0 to arr.size - 1) {
              if ((j != i) && (arr(j)(1) != 0)) wt(j) += q
            }
          } else {
            for (j <- 0 to arr.size - 1) {
              if ((j != i) && (arr(j)(1) != 0)) {
                wt(j) += arr(i)(1)
              }
            }
            tracker = tracker + arr(i)(1)
            updated_TAT = tracker
            new_tat(li) = updated_TAT - arr_copy(i)(0)
            new_wt(li) = tracker - arr_copy(i)(1) - arr_copy(i)(0)
            li = li + 1
            arr(i)(1) = 0
          }
        }
      }
      sum = 0.0
      for (i <- 0 to arr.length - 1) sum = sum + arr(i)(1)
    } while (sum != 0)
    var avg_wt = 0.0
    var avg_tat = 0.0
    for (j <- 0 to n - 1) avg_wt += wt(j)
    for (j <- 0 to n - 1) avg_tat += new_tat(j)
    println("average waiting time= " + (avg_wt / n) + " Average turn around time= " + (avg_tat / n))
  }

  def Two(n: Int, data: Array[Array[Double]]): Unit = {
    var arr = data
    arr = arr.sortBy(x => x(1))
    var arr_copy = arr
    var q = 0.0
    var wt = new Array[Double](n)
    var a = new Array[Double](n)
    var tat = new Array[Double](n)
    var new_tat = new Array[Double](n)
    var new_wt = new Array[Double](n)
    var sum = 0.0
    for (i <- 0 to n - 1) {
      a(i) = arr(i)(1)
    }
    for (i <- 0 to n - 1) {
      wt(i) = 0
    }
    var tracker = 0.0
    var li = 0
    var updated_TAT = 0.0
    do {
      arr = arr.filterNot(x => x(1) <= 0)
      q = arr(0)(1)
      for (i <- 0 to arr.size - 1) {
        if (tracker >= arr(i)(0)) {
          if (arr(i)(1) > q) {
            arr(i)(1) -= q
            tracker = tracker + q
            for (j <- 0 to arr.size - 1) {
              if ((j != i) && (arr(j)(1) != 0)) wt(j) += q
            }
          } else {
            for (j <- 0 to arr.size - 1) {
              if ((j != i) && (arr(j)(1) != 0)) {
                wt(j) += arr(i)(1)
              }
            }
            tracker = tracker + arr(i)(1)
            updated_TAT = tracker
            new_tat(li) = updated_TAT - arr_copy(i)(0)
            new_wt(li) = tracker - arr_copy(i)(1) - arr_copy(i)(0)
            li = li + 1
            arr(i)(1) = 0
          }
        }
      }
      sum = 0.0
      for (i <- 0 to arr.length - 1) sum = sum + arr(i)(1)
    } while (sum != 0)
    var avg_wt = 0.0
    var avg_tat = 0.0
    for (j <- 0 to n - 1) avg_wt += wt(j)
    for (j <- 0 to n - 1) avg_tat += new_tat(j)
    println("average waiting time= " + (avg_wt / n) + " Average turn around time= " + (avg_tat / n))
  }
}

方案2:在方法内部先拷贝数据

如果你不想修改调用逻辑,也可以在One和Two方法的开头,先对传入的data做深拷贝,确保方法内部操作的是副本:

def One(n: Int, data: Array[Array[Double]]): Unit = {
  // 先做深拷贝,后续操作这个副本
  val arr = data.map(_.clone())
  // 下面的代码用arr代替原来的data,其他逻辑不变
  // ... 原方法剩余代码 ...
}

def Two(n: Int, data: Array[Array[Double]]): Unit = {
  val arr = data.map(_.clone())
  // ... 原方法剩余代码 ...
}

关键说明

  • array.map(_.clone())是二维数组的深拷贝方式:外层数组用map生成新数组,每个内层小数组用clone()生成独立副本,这样整个二维数组的元素都是独立的,修改副本不会影响原始数组。
  • 这样修改后,One和Two方法都会拿到和原始输入完全一致的初始数据,各自的修改只会作用在自己的副本上,不会互相干扰。

内容的提问来源于stack exchange,提问作者asif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:39:45