如何将整数序列拆分为范围(java \ kotlin)

时间:2023-01-29 09:10:33

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