回答
如果你只是想表示一個範圍內的字符串,那麼你會發現你的序列的中點,並(在你的例子10)成爲你的中間值。然後,您會抓取序列中的第一個項目以及緊接在中點之前的項目,並構建您的第一個序列表示。你可以按照相同的步驟獲得最後一個項目,以及緊接在中間點之後的項目,並建立最後一個序列的表示。
// Provide initial sequence
var sequence = [1,2,3,4,5,6,7,8,9,10];
// Find midpoint
var midpoint = Math.ceil(sequence.length/2);
// Build first sequence from midpoint
var firstSequence = sequence[0] + "-" + sequence[midpoint-2];
// Build second sequence from midpoint
var lastSequence = sequence[midpoint] + "-" + sequence[sequence.length-1];
// Place all new in array
var newArray = [firstSequence,midpoint,lastSequence];
alert(newArray.join(",")); // 1-4,5,6-10
輸出不是1-10,因爲數字1-10依次出現而沒有丟失? – 2010-02-16 07:53:56
你可以遍歷號碼,看看接下來的數大於1,則當前數目。所以有一個:
struct range {
int start;
int end;
} range;
其中如果array[i+1] == array[i]+1;
(其中,i是當前觀察到的數目) 然後range.end = array[i+1];
。然後你進入下一個i
;如果array[i+1] != array[i]+1;
然後range.end = array[i];
你可以存儲範圍在vector<range> ranges;
印刷很容易:
for(int i = 0; i < ranges.size(); i++) {
range rng = (range)ranges.at(i);
printf("[%i-%i]", rng.start, rng.end);
}
; For all cells of the array
;if current cell = prev cell + 1 -> range continues
;if current cell != prev cell + 1 -> range ended
int[] x = [2,3,4,5,10,18,19,20]
string output = '['+x[0]
bool range = false; --current range
for (int i = 1; i > x[].length; i++) {
if (x[i+1] = [x]+1) {
range = true;
} else { //not sequential
if range = true
output = output || '-'
else
output = output || ','
output.append(x[i]','||x[i+1])
range = false;
}
}
類似的東西。
這是一種算法,我做了some time ago,最初是爲C#寫的,現在我把它移植到JavaScript的:
function getRanges(array) {
var ranges = [], rstart, rend;
for (var i = 0; i < array.length; i++) {
rstart = array[i];
rend = rstart;
while (array[i + 1] - array[i] == 1) {
rend = array[i + 1]; // increment the index if the numbers sequential
i++;
}
ranges.push(rstart == rend ? rstart+'' : rstart + '-' + rend);
}
return ranges;
}
getRanges([2,3,4,5,10,18,19,20]);
// returns ["2-5", "10", "18-20"]
getRanges([1,2,3,5,7,9,10,11,12,14 ]);
// returns ["1-3", "5", "7", "9-12", "14"]
getRanges([1,2,3,4,5,6,7,8,9,10])
// returns ["1-10"]
會建議先排序值,所以你可以處理混合值,如:[1,3,2,6,5,7] – Tracker1 2010-02-16 07:57:39
我把它放在npm https://www.npmjs.com/package/get-範圍 – 2016-09-17 08:40:32
這裏是一個Perl的一個版本:
use strict;
use warnings;
my @numbers = (0,1,3,3,3,4,4,7,8,9,12, 14, 15, 19, 35, 35, 37, 38, 38, 39);
@numbers = sort {$a <=> $b} @numbers ; # Make sure array is sorted.
# Add "infinity" to the end of the array.
$numbers[1+$#numbers] = undef ;
my @ranges =() ; # An array where the range strings are stored.
my $start_number = undef ;
my $last_number = undef ;
foreach my $current_number (@numbers)
{
if (!defined($start_number))
{
$start_number = $current_number ;
$last_number = $current_number ;
}
else
{
if (defined($current_number) && (($last_number + 1) >= $current_number))
{
$last_number = $current_number ;
next ;
}
else
{
if ($start_number == $last_number)
{
push(@ranges, $start_number) ;
}
else
{
push(@ranges, "$start_number-$last_number") ;
}
$start_number = $current_number ;
$last_number = $current_number ;
}
}
}
# Print the results
print join(", ", @ranges) . "\n" ;
# Returns "0-1, 3-4, 7-9, 12, 14-15, 19, 35, 37-39"
來自PerlMonks的較短答案:[http://www.perlmonks.org/?node_id=87538](http://www.perlmonks.org/?node_id=87538) – 2011-09-09 20:27:17
只要有樂趣來自CMS的解決方案:
function getRanges (array) {
for (var ranges = [], rend, i = 0; i < array.length;) {
ranges.push ((rend = array[i]) + ((function (rstart) {
while (++rend === array[++i]);
return --rend === rstart;
})(rend) ? '' : '-' + rend));
}
return ranges;
}
++ for trick while循環。順便說一句,這是相等的。函數getRanges(c){for(var b = [],a,d = 0; d
下面是我對此的看法...
function getRanges(input) {
//setup the return value
var ret = [], ary, first, last;
//copy and sort
var ary = input.concat([]);
ary.sort(function(a,b){
return Number(a) - Number(b);
});
//iterate through the array
for (var i=0; i<ary.length; i++) {
//set the first and last value, to the current iteration
first = last = ary[i];
//while within the range, increment
while (ary[i+1] == last+1) {
last++;
i++;
}
//push the current set into the return value
ret.push(first == last ? first : first + "-" + last);
}
//return the response array.
return ret;
}
我只是在尋找這個確切的東西。我需要一個PHP版本,以便移植CMS的解決方案。這是任何人誰被這個問題尋找同樣的事情停止:
function getRanges($nums)
{
$ranges = array();
for ($i = 0, $len = count($nums); $i < $len; $i++)
{
$rStart = $nums[$i];
$rEnd = $rStart;
while (isset($nums[$i+1]) && $nums[$i+1]-$nums[$i] == 1)
$rEnd = $nums[++$i];
$ranges[] = $rStart == $rEnd ? $rStart : $rStart.'-'.$rEnd;
}
return $ranges;
}
我發現這個答案是有用的,但需要一個Python版本:
def GroupRanges(items):
"""Yields 2-tuples of (start, end) ranges from a sequence of numbers.
Args:
items: an iterable of numbers, sorted ascendingly and without duplicates.
Yields:
2-tuples of (start, end) ranges. start and end will be the same
for ranges of 1 number
"""
myiter = iter(items)
start = myiter.next()
end = start
for num in myiter:
if num == end + 1:
end = num
else:
yield (start, end)
start = num
end = num
yield (start, end)
numbers = [1, 2, 3, 5, 6, 7, 8, 9, 10, 20]
assert [(1, 3), (5, 10), (20, 20)] == list(GroupRanges(numbers))
assert [(1, 1)] == list(GroupRanges([1]))
assert [(1, 10)] == list(GroupRanges([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
PHP
function getRanges($nums) {
sort($nums);
$ranges = array();
for ($i = 0, $len = count($nums); $i < $len; $i++)
{
$rStart = $nums[$i];
$rEnd = $rStart;
while (isset($nums[$i+1]) && $nums[$i+1]-$nums[$i] == 1)
$rEnd = $nums[++$i];
$ranges[] = $rStart == $rEnd ? $rStart : $rStart.'-'.$rEnd;
}
return $ranges;
}
echo print_r(getRanges(array(2,21,3,4,5,10,18,19,20)));
echo print_r(getRanges(array(1,2,3,4,5,6,7,8,9,10)));
除非將可選的第二個參數設置爲true,否則print_r已經打印到stdout:echo print_r(array(),true);或者只是print_r(array()); – 2012-07-18 22:00:19
import java.util.ArrayList;
import java.util.Arrays;
public class SequencetoRange {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int num[] = {1,2,3,63,65,66,67,68,69,70,80,90,91,94,95,4,101,102,75,76,71};
int l = num.length;
int i;
System.out.print("Given number : ");
for (i = 0;i < l;i++){
System.out.print(" " + num[i]);
}
System.out.println("\n");
Arrays.sort(num);
ArrayList newArray = new ArrayList();
newArray = getRanges(num);
System.out.print("Range : ");
for(int y=0;y<newArray.size();y++)
{
System.out.print(" " +newArray.get(y));
}
}
public static ArrayList getRanges(int num[])
{
ArrayList ranges = new ArrayList();
int rstart, rend;
int lastnum = num[num.length-1];
for (int i = 0; i < num.length-1; i++)
{
rstart = num[i];
rend = rstart;
while (num[i + 1] - num[i] == 1)
{
rend = num[i + 1];
// increment the index if the numbers sequential
if(rend>=lastnum)
{
break;
}
else
{
i++;
}
}
if(rstart==rend)
{
ranges.add(rend);
}
else
{
ranges.add(+rstart+"..."+rend);
}
}
return ranges;
}
}
在C#中
public string compressNumberRange(string inputSeq)
{
//Convert String array to long List and removing the duplicates
List<long> longList = inputSeq.Split(',').ToList().ConvertAll<long>(s => Convert.ToInt64(s)).Distinct().ToList();
//Sort the array
longList.Sort();
StringBuilder builder = new StringBuilder();
for (int itr = 0; itr < longList.Count(); itr++)
{
long first = longList[itr];
long end = first;
while (longList[itr + 1] - longList[itr] == 1) //Seq check
{
end = longList[itr + 1];
itr++;
if (itr == longList.Count() - 1)
break;
}
if (first == end) //not seq
builder.Append(first.ToString() + ",");
else //seq
builder.Append(first.ToString() + "-" + end.ToString() + ",");
}
return builder.ToString();
}
我寫我自己的方法,這是依賴於羅短跑,但不只是給你回的範圍數組,相反,它只是返回範圍組的陣列。
[1,2,3,4,6,8,10]變爲:
[[1,2,3,4],[6,8,10]]
下面是CMS的代碼BASH端口:
#!/usr/bin/env bash
# vim: set ts=3 sts=48 sw=3 cc=76 et fdm=marker: # **** IGNORE ******
get_range() { RANGE= # <-- OUTPUT **** THIS ******
local rstart rend i arr=("[email protected]") # ported from **** JUNK ******
for ((i=0 ; i < $# ; i++)); do # http://stackoverflow.com
((rstart = arr[i])) # /a/2270987/912236
rend=$rstart; while ((arr[i+1] - arr[i] == 1)); do
((rend = arr[++i])); done; ((rstart == rend)) &&
RANGE+=" $rstart" || RANGE+=" $rstart-$rend"; done; } # }}}
冷聚變
的CMS's javascript solution適應它首先做排序的列表,以便1,3,2,4,5,8,9,10
(或類似)正確轉換爲1-5,8-10
。
<cfscript>
function getRanges(nArr) {
arguments.nArr = listToArray(listSort(arguments.nArr,"numeric"));
var ranges = [];
var rstart = "";
var rend = "";
for (local.i = 1; i <= ArrayLen(arguments.nArr); i++) {
rstart = arguments.nArr[i];
rend = rstart;
while (i < ArrayLen(arguments.nArr) and (val(arguments.nArr[i + 1]) - val(arguments.nArr[i])) == 1) {
rend = val(arguments.nArr[i + 1]); // increment the index if the numbers sequential
i++;
}
ArrayAppend(ranges,rstart == rend ? rstart : rstart & '-' & rend);
}
return arraytolist(ranges);
}
</cfscript>
謝謝...我寫了一個類似的UDF,但它遭受了一個錯誤。我更新了這個,所以它會接受一個列表或數組,並在嘗試數字排序之前添加一個子例程來修剪和刪除非數字項目。 (如果沒有爲用戶提供的值執行此操作,則可能會引發錯誤。) – 2016-08-25 15:16:01
非常好的問題:這是我的嘗試:
function ranges(numbers){
var sorted = numbers.sort(function(a,b){return a-b;});
var first = sorted.shift();
return sorted.reduce(function(ranges, num){
if(num - ranges[0][1] <= 1){
ranges[0][1] = num;
} else {
ranges.unshift([num,num]);
}
return ranges;
},[[first,first]]).map(function(ranges){
return ranges[0] === ranges[1] ?
ranges[0].toString() : ranges.join('-');
}).reverse();
}
這是我放在一起的斯威夫特。它首先消除重複並對數組進行排序,並不介意它是否給出了一個空數組或一個數組。
func intArrayToString(array: [Int]) -> String {
var intArray = Array(Set(array))
intArray.sortInPlace()
if intArray.count == 0 {
return ""
}
var intString = "\(intArray[0])"
if intArray.count > 1 {
for j in 1..<intArray.count-1 {
if intArray[j] == intArray[j-1]+1 {
if intArray[j] != intArray[j+1]-1 {
intString += "-\(intArray[j])"
}
} else {
intString += ",\(intArray[j])"
}
}
if intArray.last! == intArray[intArray.count-2]+1 {
intString += "-\(intArray.last!)"
} else {
intString += ",\(intArray.last!)"
}
}
return intString
}
微小的ES6模塊爲你們。它接受一個函數來確定我們什麼時候必須破壞序列(breakDetectorFunc param - 默認是整數序列輸入的簡單事情)。 注意:由於輸入是抽象的 - 有沒有自動分揀處理之前,因此,如果您的序列是沒有排序 - 在調用該模塊
function defaultIntDetector(a, b){
return Math.abs(b - a) > 1;
}
/**
* @param {Array} valuesArray
* @param {Boolean} [allArraysResult=false] if true - [1,2,3,7] will return [[1,3], [7,7]]. Otherwise [[1.3], 7]
* @param {SequenceToIntervalsBreakDetector} [breakDetectorFunc] must return true if value1 and value2 can't be in one sequence (if we need a gap here)
* @return {Array}
*/
const sequenceToIntervals = function (valuesArray, allArraysResult, breakDetectorFunc) {
if (!breakDetectorFunc){
breakDetectorFunc = defaultIntDetector;
}
if (typeof(allArraysResult) === 'undefined'){
allArraysResult = false;
}
const intervals = [];
let from = 0, to;
if (valuesArray instanceof Array) {
const cnt = valuesArray.length;
for (let i = 0; i < cnt; i++) {
to = i;
if (i < cnt - 1) { // i is not last (to compare to next)
if (breakDetectorFunc(valuesArray[i], valuesArray[i + 1])) {
// break
appendLastResult();
}
}
}
appendLastResult();
} else {
throw new Error("input is not an Array");
}
function appendLastResult(){
if (isFinite(from) && isFinite(to)) {
const vFrom = valuesArray[from];
const vTo = valuesArray[to];
if (from === to) {
intervals.push(
allArraysResult
? [vFrom, vTo] // same values array item
: vFrom // just a value, no array
);
} else if (Math.abs(from - to) === 1) { // sibling items
if (allArraysResult) {
intervals.push([vFrom, vFrom]);
intervals.push([vTo, vTo]);
} else {
intervals.push(vFrom, vTo);
}
} else {
intervals.push([vFrom, vTo]); // true interval
}
from = to + 1;
}
}
return intervals;
};
module.exports = sequenceToIntervals;
/** @callback SequenceToIntervalsBreakDetector
@param value1
@param value2
@return bool
*/
第一個參數做到這一點是輸入序列排序後的數組,第二個是一布爾標誌控制輸出模式:如果爲真 - 單個項目(間隔外)將被反正返回數組:[1,7],[9,9],[10,10],[12,20],否則單品返回它們出現的輸入數組
在爲您的樣品輸入
[2,3,4,5,10,18,19,20]
則回覆:
sequenceToIntervals([2,3,4,5,10,18,19,20], true) // [[2,5], [10,10], [18,20]]
sequenceToIntervals([2,3,4,5,10,18,19,20], false) // [[2,5], 10, [18,20]]
sequenceToIntervals([2,3,4,5,10,18,19,20]) // [[2,5], 10, [18,20]]
- 1. 將數字轉換爲數字範圍?
- 2. 在Bash中,如何將數字列表轉換爲數字範圍?
- 3. C#如何將IP範圍轉換爲字符串數組?
- 4. 將特定的字符數組範圍轉換爲字符串
- 5. SQL將一列數字轉換爲一列中的範圍
- 6. 如何將字節數組的子範圍轉換爲C中的字符串#
- 7. 如何將數字範圍的字符串轉換爲Python中的列表
- 8. 如何將數字字符串範圍轉換爲Python中的列表
- 9. 如何使用Arduino將數字從一個數字範圍轉換爲另一個數字範圍
- 10. 如何將字符串列表轉換爲數字numpy數組?
- 11. 如何將字符串轉換爲字典數組的數組?
- 12. 將字符串中的數字列表轉換爲數組
- 13. 如何將字數轉換爲數字
- 14. 如何將數字轉換爲Python中的數字列表?
- 15. 將數字列表轉換爲數字
- 16. 如何將數字範圍從0-200轉換爲1-5範圍
- 17. BigInteger如何在Java中將字節數組轉換爲數字?
- 18. 如何將字符串數組轉換爲字節數組? (java)
- 19. 如何將Java字節數組轉換爲Scala字節數組?
- 20. 如何將字符串數組轉換爲BigQuery中的數組?
- 21. 如何將struct數組轉換爲c#中的字節數組?
- 22. 如何將字節數組轉換爲C#中的雙數組?
- 23. 如何將數組字符串轉換爲PHP中的數組?
- 24. 如何將整數轉換爲C中的數字數組?
- 25. 如何將字典轉換爲數組
- 26. 如何將字典數組轉換爲數組數組?
- 27. Python:如何將字符串數組轉換爲數組數組?
- 28. 將整數數組轉換爲數字
- 29. 將整數轉換爲數組數字
- 30. 如何將序列化的數組字符串轉換爲數組?
你是如何確定享受一系列的開始和結束? – Sampson 2010-02-16 05:45:43
@gokul:我編輯你的問題(從標題刪除例如,格式化的正文)。您可以通過正確設置問題來激勵人們提供幫助。 – 2010-02-16 05:45:47