如何将整数序列分割成范围(java \ kotlin)

现在我有一个这样的序列

("1,3,5,7,11,13,15,17,21,23,25,27,29,33,35") 

我怎样才能分成不分段的范围。 例如,我需要得到像这样的奇数范围的列表:

 ([1,3,5,7] [11,13,15,17] [21,23,25,27,29] [33,35]) 

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。 我对代码感到抱歉。 我添加了我的解决方案版本。 我正在寻找一个更漂亮的版本。

这里有一个使用maplet

 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() } 

您可以使用google / guava的RangeSet :Google Core Libraries for Java 6+ :

 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 } } 

你可以使用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 } 

你可以使用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