Reputation: 33
For example i have:
List(1,3,2,5)
How i get all these:
List(1), List(3), List(2), List(5), List(1,3), List(1,2), List(1,5), List(3,2), List(3,5), List(2,5), List(1,3,2), List(1,3,5), List(1,2,5), List(3,2,5), List(1,3,2,5))
I need this for Longest Increasing Subsequence -problem and this answer for example would be: (1,3,5)
And I want use it for bigger Lists.
Upvotes: 2
Views: 1887
Reputation: 27366
[ Update in response to updated question ]
[ Thanks to @jwvh for spotting error in original version ]
This method will generate all possible sub-sequences of a List
:
def subsequences[T](list: List[T]): List[List[T]] =
list match {
case Nil =>
List(List())
case hd :: tl =>
val subs = subsequences(tl)
subs.map(hd +: _) ++ subs
}
Note that this is not efficient for a number of reasons, so it is not a good way to solve the "longest increasing subsequence problem".
[ Original answer ]
This function will generate all the non-empty contiguous sub-sequences of any sequence:
def subsequences[T](seq: Seq[T]) =
seq.tails.flatMap(_.inits).filter(_.nonEmpty)
This returns an Iterator
so it creates each sub-sequence in turn which reduces memory usage.
Note that this will generate all the sub-sequences and will preserve the order of the values, unlike solutions using combinations
or Set
.
You can use this in your "longest increasing subsequence problem" like this:
def isAscending(seq: Seq[Int]): Boolean =
seq.length <= 1 || seq.sliding(2).forall(x => x(0) < x(1))
subsequences(a).filter(isAscending).maxBy(_.length)
The result will be the longest sequence of ascending values in the input a
.
Upvotes: 0
Reputation: 51271
You want all the combinations()
from 1 to array length.
val arr = Array(4, 3, 1)
arr.indices.flatMap(x => arr.combinations(x + 1))
//res0: Seq[Array[Int]] = Vector(Array(4), Array(3), Array(1), Array(4, 3), Array(4, 1), Array(3, 1), Array(4, 3, 1))
update
This will give you all possible combinations, retaining original order and duplicate elements.
def subseqs[A](seq :Seq[A]) :List[Seq[A]] = seq match {
case hd +: tl =>
val res = subseqs(tl)
Seq(hd) :: res ++ res.map(hd +: _)
case Seq() => Nil
}
The result is a List
of n^2 - 1 possible sub-sequences. So for a collection of 8 elements you'll get 255 sub-sequences.
This, of course, is going to be way too tedious and inefficient for your purposes. Generating all possible sub-sequences in order to find the Longest Increasing is a little like washing all the clothes in your neighborhood so you'll have clean socks in the morning.
Much better to generate only the increasing sub-sequences and find the longest from that set (9 lines of code).
Upvotes: 6