Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将迭代二和k转换为泛函_Scala_Functional Programming - Fatal编程技术网

Scala 将迭代二和k转换为泛函

Scala 将迭代二和k转换为泛函,scala,functional-programming,Scala,Functional Programming,我在Python中有这样一段代码,它在一个数组中查找所有求和为k的数字对: def two_sum_k(array, k): seen = set() out = set() for v in array: if k - v in seen: out.add((min(v, k-v), max(v, k-v))) seen.add(v) return out 有人能帮我把它转换成Scala(函数式)吗?还

我在Python中有这样一段代码,它在一个数组中查找所有求和为k的数字对:

def two_sum_k(array, k):
    seen = set()
    out = set()

    for v in array:
        if k - v in seen:
            out.add((min(v, k-v), max(v, k-v)))
        seen.add(v)
    return out

有人能帮我把它转换成Scala(函数式)吗?还有线性复杂度。

你可以只过滤(k-x我不确定这是最清晰的,但褶皱通常起作用:

def two_sum_k(xs: Seq[Int], k: Int) = {
  xs.foldLeft((Set[Int](),Set[(Int,Int)]())){ case ((seen,out),v) =>
    (seen+v, if (seen contains k-v) out+((v min k-v, v max k-v)) else out)
  }._2
}
def two_sum_k(xs: List[Int], k: Int): List[(Int, Int)] ={
      xs.map(a=>xs.map(b=>(b,a+b)).filter(_._2 == k).map(b=>(b._1,a))).flatten.collect{case (a,b)=>if(a>b){(b,a)}else{(a,b)}}.distinct
}
这就是诀窍:

def two_sum_k(xs: Seq[Int], k: Int) = {
  xs.foldLeft((Set[Int](),Set[(Int,Int)]())){ case ((seen,out),v) =>
    (seen+v, if (seen contains k-v) out+((v min k-v, v max k-v)) else out)
  }._2
}
def two_sum_k(xs: List[Int], k: Int): List[(Int, Int)] ={
      xs.map(a=>xs.map(b=>(b,a+b)).filter(_._2 == k).map(b=>(b._1,a))).flatten.collect{case (a,b)=>if(a>b){(b,a)}else{(a,b)}}.distinct
}

我认为这是一个典型的例子,当一个理解的例子可以提供额外的清晰度

scala> def algo(xs: IndexedSeq[Int], target: Int) =
   | for {
   |   i <- 0 until xs.length
   |   j <- (i + 1) until xs.length if xs(i) + xs(j) == target
   | }
   | yield xs(i) -> xs(j)
algo: (xs: IndexedSeq[Int], target: Int)scala.collection.immutable.IndexedSeq[(Int, Int)]

我认为它也不会遇到您的算法存在的问题。好吧,直接翻译如下:

import scala.collection.mutable

def twoSumK[T : Numeric](array: Array[T], k: T) = {
  val num = implicitly[Numeric[T]]
  import num._

  val seen = mutable.HashSet[T]()
  val out: mutable.Set[(T, T)]  = mutable.HashSet[(T, T)]()

  for (v <- array) {
    if (seen contains k - v) out += min(v, k - v) -> max(v, k - v)
    seen += v
  }

  out
}
def twoSumK[T : Numeric](array: Array[T], k: T) = {
  val num = implicitly[Numeric[T]]
  import num._

  // One can write all the rest as a one-liner
  val s1 = array.toSet
  val s2 = s1 map (k -)
  val s3 = s1 intersect s2

  s3 map (v => min(v, k - v) -> max(v, k - v))
}

假设是哈希集,这比python解决方案更糟糕。是的-我肯定有更有效的解决方案。你认为我的解决方案如何?这不符合基本要求:答案中的所有数字都必须包含在
xs
中。看起来有点复杂,但在包含10000个元素的短测试中速度最快,大约10%不是suitable用于构建一个和。比我的快。这是不完整的。给定xs=(2,3,5,6)和k=4,它返回(2,2),它不应该返回(2,2)。你是对的。我做了一个改进,测试了它,测试了其他人的代码。你希望
f((2,3,3,4,5,5),8)
返回什么?4次(3,5)?我想你没有。python代码做什么?因为有集合,我想每个组合只有一次。Mh。最后一个
distinct
解决了这个问题。
import scala.collection.mutable

def twoSumK[T : Numeric](array: Array[T], k: T) = {
  val num = implicitly[Numeric[T]]
  import num._

  val seen = mutable.HashSet[T]()
  val out: mutable.Set[(T, T)]  = mutable.HashSet[(T, T)]()

  for (v <- array) {
    if (seen contains k - v) out += min(v, k - v) -> max(v, k - v)
    seen += v
  }

  out
}
def twoSumK[T : Numeric](array: Array[T], k: T) = {
  val num = implicitly[Numeric[T]]
  import num._

  // One can write all the rest as a one-liner
  val s1 = array.toSet
  val s2 = s1 map (k -)
  val s3 = s1 intersect s2

  s3 map (v => min(v, k - v) -> max(v, k - v))
}