Now I have a sequence like this
现在我有一个这样的序列
("1,3,5,7,11,13,15,17,21,23,25,27,29,33,35")
How can I split into non-breaking ranges. For example I need get list with odd ranges like this:
我怎样才能分成不间断的范围。例如,我需要得到奇数范围的列表,如下所示:
([1,3,5,7] [11,13,15,17] [21,23,25,27,29] [33,35])
UPD. My code:
UPD。我的代码:
fun test1 (arr : List<Int>): List<List<Int>>{
var lastElem: Int? = null
val arr = ArrayList(arr)
Collections.sort(arr)
val iter = arr.iterator()
val resultList = ArrayList<List<Int>>()
val tmlList = ArrayList<Int>()
while(iter.hasNext()){
val currElem = iter.next()
if (lastElem == null) {
lastElem = currElem
tmlList.add(currElem)
}else if(lastElem+2==currElem){
tmlList.add(currElem)
lastElem = currElem
}else if(lastElem+2 != currElem){
resultList.add(ArrayList(tmlList))
tmlList.clear()
tmlList.add(currElem)
lastElem = currElem
}
}
resultList.add(ArrayList(tmlList))
return resultList;
}
UPD. I'm sorry about code. I added my version of solution. I'm looking for a more beautiful version.
UPD。我很抱歉代码。我添加了我的解决方案版本。我正在寻找一个更漂亮的版本。
2 个解决方案
#1
1
Here's one way using map
, let
:
这是使用map的一种方式,让:
val a = ("1,3,5,7,11,13,15,17,21,23,25,27,29,33,35")
val nonBreakingRanges = a.split(',')
.map { it.toLong() }
.let { list ->
var lastRange = mutableListOf<Long>()
list.map {
val previousElement = lastRange.lastOrNull() ?: it
if (it == previousElement + 2) {
lastRange.add(it)
} else {
lastRange = mutableListOf(it)
}
lastRange
}.distinct()
}
#2
2
You can use a RangeSet from google/guava: Google Core Libraries for Java 6+:
您可以使用google / guava中的RangeSet:适用于Java 6+的Google核心库:
val rangeSet: RangeSet<Int> = ImmutableRangeSet.builder<Int>()
.apply { sequence.forEach { add(Range.closedOpen(it, it + 2)) } }
.build()
val nonBreakingRanges = rangeSet.asRanges()
.map { ContiguousSet.create(it, DiscreteDomain.integers()).filter { it % 2 != 0 } }
You can use fold
:
你可以使用折叠:
val nonBreakingRanges = sequence.fold(mutableListOf<MutableList<Int>>()) {
nonBreakingRanges, element ->
val lastRange = nonBreakingRanges.lastOrNull()
if (lastRange != null && lastRange.lastOrNull() == element - 2) {
lastRange.add(element)
} else {
nonBreakingRanges.add(mutableListOf(element))
}
nonBreakingRanges
}
You can use groupBy
:
你可以使用groupBy:
var previousElement: Int? = null
var rangeIndex = 0
fun rangeIndexSelector(currentElement: Int): Int {
if (previousElement != currentElement - 2) {
rangeIndex++
}
previousElement = currentElement
return rangeIndex
}
val nonBreakingRanges = sequence.groupBy(::rangeIndexSelector).values
#1
1
Here's one way using map
, let
:
这是使用map的一种方式,让:
val a = ("1,3,5,7,11,13,15,17,21,23,25,27,29,33,35")
val nonBreakingRanges = a.split(',')
.map { it.toLong() }
.let { list ->
var lastRange = mutableListOf<Long>()
list.map {
val previousElement = lastRange.lastOrNull() ?: it
if (it == previousElement + 2) {
lastRange.add(it)
} else {
lastRange = mutableListOf(it)
}
lastRange
}.distinct()
}
#2
2
You can use a RangeSet from google/guava: Google Core Libraries for Java 6+:
您可以使用google / guava中的RangeSet:适用于Java 6+的Google核心库:
val rangeSet: RangeSet<Int> = ImmutableRangeSet.builder<Int>()
.apply { sequence.forEach { add(Range.closedOpen(it, it + 2)) } }
.build()
val nonBreakingRanges = rangeSet.asRanges()
.map { ContiguousSet.create(it, DiscreteDomain.integers()).filter { it % 2 != 0 } }
You can use fold
:
你可以使用折叠:
val nonBreakingRanges = sequence.fold(mutableListOf<MutableList<Int>>()) {
nonBreakingRanges, element ->
val lastRange = nonBreakingRanges.lastOrNull()
if (lastRange != null && lastRange.lastOrNull() == element - 2) {
lastRange.add(element)
} else {
nonBreakingRanges.add(mutableListOf(element))
}
nonBreakingRanges
}
You can use groupBy
:
你可以使用groupBy:
var previousElement: Int? = null
var rangeIndex = 0
fun rangeIndexSelector(currentElement: Int): Int {
if (previousElement != currentElement - 2) {
rangeIndex++
}
previousElement = currentElement
return rangeIndex
}
val nonBreakingRanges = sequence.groupBy(::rangeIndexSelector).values