Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/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函数,该函数生成长度为N的整数的有序列表_Scala - Fatal编程技术网

创建一个scala函数,该函数生成长度为N的整数的有序列表

创建一个scala函数,该函数生成长度为N的整数的有序列表,scala,Scala,假设我有一个简单的函数,它构建了两个正整数(x,y)的所有列表的迭代器,这两个正整数很好: def intsIterator(n: Int, limit: Int) = (1 to n).map(List.fill(limit)(_)).flatten.combinations(limit).filter(l => (l, l.tail).zipped.forall(_ <= _)) scala> intsIterator(5,3) mkString "\n" res16:

假设我有一个简单的函数,它构建了两个正整数(x,y)的所有列表的迭代器,这两个正整数很好:

def intsIterator(n: Int, limit: Int) = (1 to n).map(List.fill(limit)(_)).flatten.combinations(limit).filter(l => (l, l.tail).zipped.forall(_ <= _))

scala> intsIterator(5,3) mkString "\n"
res16: String =
Vector(1, 2, 3)
Vector(1, 2, 4)
Vector(1, 2, 5)
Vector(1, 3, 4)
Vector(1, 3, 5)
Vector(1, 4, 5)
Vector(2, 3, 4)
Vector(2, 3, 5)
Vector(2, 4, 5)
Vector(3, 4, 5)
只需使用递归:

def produce(n: Int, limit: Int, k: Int = 1): Iterator[List[Int]] = {
  Iterator.range(k, limit) flatMap {
    case x if n > 1 => produce(n - 1, limit, x).map(x :: _)
    case x => Iterator(List(x))
  }
}
或与理解:

def produce(n: Int, limit: Int, k: Int = 1): Iterator[List[Int]] = for {
   x <- k to limit - 1 iterator;
   y <- if (n > 1) produce(n - 1, limit, x) else Iterator(Nil)
} yield x :: y
def product(n:Int,limit:Int,k:Int=1):迭代器[List[Int]]=for{
这是我的解决方案:

scala> def gen(n: Int, limit: Int): Iterator[List[Int]] = n match {
     |   case 0 => Iterator(Nil)
     |   case _ => for(t <- 1 to limit iterator;s <- gen(n-1, t)) yield s:+t
     | }

如果效率或可伸缩性很重要,我将对
向量
s采取行动,我不会使用递归并创建
迭代器
,而不是
列表

new Iterator() {
  val max = limit - 1 // makes logic simpler
  var cur = Vector.fill(n - 1)(1) :+ 0
  var (i, v) = (n - 1, 1)

  def hasNext(): Boolean = cur.head != max

  def next(): List[Int] = {
    if (v <= max) 
      cur = cur.updated(i, v)
    else {
      i -= 1
      if (cur(i) == max - 1) 
        cur = cur.update(i, max)
      else {
        v = cur(i) + 1
        cur = cur.take(i) ++ Vector.fill(n - i)(v)
        i = n - 1
      }
    }
    v += 1
    cur.toList // you could leave as a Vector
  }
}
新迭代器(){
val max=limit-1//使逻辑更简单
var cur=向量填充(n-1)(1):+0
var(i,v)=(n-1,1)
def hasNext():Boolean=cur.head!=max
def next():列表[Int]={

如果(v)这不起作用。试试这个:intsIterator(101000)。取(100)foreach printlnI喜欢这样,因为它不会堆栈溢出,但效率有点低,因为它必须以非常详尽的方式进行过滤way@TrustNoOne现在有了。我错误地认为不可能有重复。现在它按照您的预期工作。很好,+1。只有一个小的风格备注:
1限制迭代器
很难阅读,它提出了一个后缀运算符警告。我认为
(1到限制)。迭代器
更清晰。顺序不同于我的示例中使用的理解顺序。例如,对于3,4,它应该是:1 1 1-1 2-1 1 3-1 2-1 2 3,等等。有些东西错了,IntsLiterator(5,5)生成4个元素的列表我也将其翻译为以便于理解,但您的看起来更紧凑。添加以便于理解。顺序重要吗?例如,123可以在122之前出现吗?是的,但您在下面(eastsun)有一个很好的答案,该答案适用于不同的顺序
def produce(n: Int, limit: Int, k: Int = 1): Iterator[List[Int]] = for {
   x <- k to limit - 1 iterator;
   y <- if (n > 1) produce(n - 1, limit, x) else Iterator(Nil)
} yield x :: y
scala> def gen(n: Int, limit: Int): Iterator[List[Int]] = n match {
     |   case 0 => Iterator(Nil)
     |   case _ => for(t <- 1 to limit iterator;s <- gen(n-1, t)) yield s:+t
     | }
def intsListIterator(n: Int, limit: Int) = gen(n, 1, limit)

scala> def gen(n: Int, start: Int, end: Int): Iterator[List[Int]] = n match {
     |   case 0 => Iterator(Nil)
     |   case _ => for(i <- Iterator.range(start, end);s <- gen(n-1,i,end)) yield i::s
     | }
gen: (n: Int, start: Int, end: Int)Iterator[List[Int]]

scala> gen(3, 1, 4) foreach println
List(1, 1, 1)
List(1, 1, 2)
List(1, 1, 3)
List(1, 2, 2)
List(1, 2, 3)
List(1, 3, 3)
List(2, 2, 2)
List(2, 2, 3)
List(2, 3, 3)
List(3, 3, 3)

scala> gen(7, -3, 4) take 10 foreach println
List(-3, -3, -3, -3, -3, -3, -3)
List(-3, -3, -3, -3, -3, -3, -2)
List(-3, -3, -3, -3, -3, -3, -1)
List(-3, -3, -3, -3, -3, -3, 0)
List(-3, -3, -3, -3, -3, -3, 1)
List(-3, -3, -3, -3, -3, -3, 2)
List(-3, -3, -3, -3, -3, -3, 3)
List(-3, -3, -3, -3, -3, -2, -2)
List(-3, -3, -3, -3, -3, -2, -1)
List(-3, -3, -3, -3, -3, -2, 0)
new Iterator() {
  val max = limit - 1 // makes logic simpler
  var cur = Vector.fill(n - 1)(1) :+ 0
  var (i, v) = (n - 1, 1)

  def hasNext(): Boolean = cur.head != max

  def next(): List[Int] = {
    if (v <= max) 
      cur = cur.updated(i, v)
    else {
      i -= 1
      if (cur(i) == max - 1) 
        cur = cur.update(i, max)
      else {
        v = cur(i) + 1
        cur = cur.take(i) ++ Vector.fill(n - i)(v)
        i = n - 1
      }
    }
    v += 1
    cur.toList // you could leave as a Vector
  }
}