Math 以编程方式识别一个;顺序;在一系列数字中

Math 以编程方式识别一个;顺序;在一系列数字中,math,coldfusion,sequences,Math,Coldfusion,Sequences,我需要确定一个数字列表的顺序是否正确。特别是一个5的序列 示例1: (原始系列)1,3,4,67,43,20 (订购系列)1,3,4,20,43,67 这是5的序列吗错误 示例2 (原始系列)147,10143432144,23145146 (订购系列)10,23143144145146147432 这是5的序列吗正确(即143-147) current-I在有序列表上循环,检查当前数字是否等于最后一个数字+1,并保留一个计数器。这是可行的,但我很好奇,是否有更好的方法从数学上或编程上实

我需要确定一个数字列表的顺序是否正确。特别是一个5的序列

示例1:

  • (原始系列)
    1,3,4,67,43,20
  • (订购系列)
    1,3,4,20,43,67
  • 这是5的序列吗<代码>错误
示例2

  • (原始系列)
    147,10143432144,23145146
  • (订购系列)
    10,23143144145146147432
  • 这是5的序列吗<代码>正确(即143-147)
current-I在有序列表上循环,检查当前数字是否等于最后一个数字+1,并保留一个计数器。这是可行的,但我很好奇,是否有更好的方法从数学上或编程上实现这一点

<cfscript>
_list1 = [1,3,4,67,43,20]; // should evaluate to FALSE
_list2 = [147,10,143,432,144,23,145,146]; // should evaluate to TRUE

_list = _list2; // switch list in one place - test purposes only.
_seq = 1; // sequence counter
_cap = ''; // value of the upper most number of the sequence
_msg = 'There is not a consecutive sequence of 5.'; // message to user

// sort the array smallest to largest 
arraySort( _list, 'numeric' ); 

// loop the array - compare the last number with the current number 
for ( i=2; i LTE arrayLen( _list ); i++ ) {
    _last = _list[i-1]; // the LAST number - we started at the second element, so we shouldn't error.
    _this = _list[i]; // this current number
    // compare the two numbers
    if ( val( _this ) EQ val( _last ) + 1 ) {
        _seq = _seq + 1; // increment our sequence
        _cap = _this; // set the top number
    }
}

// re-set the message if we meet some threshold (5) is hardcoded here 
if ( val( _seq ) GTE 5 ) {
    _msg = 'Sequence of ' & _seq & ' to ' & _cap;
}

// write the message 
writeoutput( _msg );    
</cfscript>

_列表1=[1,3,4,67,43,20];//应该评估为FALSE
_列表2=[147,10143432144,23145146];//应该评估为真
_列表=_list2;//开关列表在一个位置-仅用于测试。
_seq=1;//序列计数器
_上限=“”;//序列最上面的数字的值
_msg='没有连续的5序列。;//发送给用户的消息
//将数组从最小到最大排序
arraySort(_list,'numeric');
//循环数组-将最后一个数字与当前数字进行比较
对于(i=2;i LTE arrayLen(_list);i++){
_last=_list[i-1];//最后一个数字-我们从第二个元素开始,所以不应该出错。
_this=_list[i];//此当前编号
//比较这两个数字
如果(val(_this)等式val(_last)+1){
_seq=_seq+1;//增加我们的序列
_cap=\u this;//设置最上面的数字
}
}
//如果我们满足此处硬编码的某个阈值(5),请重新设置消息
如果(val(_seq)GTE 5){
_msg='顺序'&_-seq&'到'&_-cap;
}
//写下信息
写输出(_msg);

我将根据序列创建一个数组,然后比较该数组。这里有一个很好的例子:

为了提高性能,我建议使用IF语句包装您的循环,首先检查至少有5个元素;无点循环超过4个元素

然后我会说,如果'seq'=5,在循环中做一个检查,然后立即跳出循环(除非你真的需要找出序列的长度,如果它大于5)


还有一件事你可以考虑尝试一下。在循环之前,可以比较列表的第一个元素和列表的最后一个元素。如果它们之间的差值小于5,那么进行循环就毫无意义。虽然从您的数据来看,这似乎不是一种可能的情况。

听起来您想了解更多的是算法时间复杂性()

您当前的算法首先进行排序,然后迭代所有元素。要确定算法的时间复杂度,我们首先必须知道Coldfusion排序算法的时间复杂度。由于Coldfusion委托Java使用快速排序算法,我们知道算法的排序部分需要
n*log(n)
时间。算法的第二部分迭代数组,需要
n
时间。将这两个时间复杂性加在一起,我们得到
n+(n*log(n))

在分析算法的时间复杂度时,我们只关注最慢的部分:
n*log(n)
。因此,大的O时间复杂度是
O(n*log(n))


这是什么意思?解决方案的排序部分是最糟糕的部分。如果您不需要排序就可以解决问题,那么您可以提高应用程序的速度——假设您的新解决方案不需要比排序花费更多的时间。

我将这个答案放在这里,因为我需要一个函数来输出一系列数字,其中任何内部序列超过2的数字都可以以连字号的形式依次输出(即
1,3,4,5,7
as
1,3-5,7
)并没有很快在其他任何地方找到它。您的代码看起来并不比我的长,因此我的代码可能对您没有好处,尽管它在某种程度上回答了您的问题,因为活动的
cfreturn
给出了最长的序列(您可以与您的5层进行比较)。(我注释掉的
cfreturn
给出了我所需的内部序列缩写):


#林蛙[1]#
-#raNums[idxItem]#
-#努姆霍尔德#,#拉努姆斯[idxItem]#
,#isSeq+1#,#raNums[idxItem]#
,#raNums[idxItem]#

我想你没有领会我的意思-我正在寻找最有效的方法来确定是否存在一个实际的序列-一旦我确定我可以做任何我想做的事情-但这是确定我要寻找的条件的功能。但是谢谢你的链接。我以为你是在尝试评估一个数字序列是否与所需的数字序列。我想我明白你的意思了。你在寻找一个递增1的序列号,它在一个更大的数字序列中,你想知道子序列的长度,对吗?是-1)如果它存在,2)多长,3)我想不出比这更有效的方法,也找不到任何方法。有什么必要提高效率?如果您面临重大的性能问题?也许我们可以从另一个角度来解决这个问题。这个问题的实际应用情况是什么?或者只是数学上的一点乐趣?+1到邓肯下面的答案。修改for循环,使其仅在arraylen(_列表)gte 5时运行。此外,当序列中断时,将_seq重置回1(即,如果序列中有2-4个数字,且列表长度大于5。还需要考虑一些其他事项:如果您的列表包含多个
<cffunction name="fNumSeries" output="1" hint="pass in sorted array, get count of longest sequence">
<cfargument name="raNums" required="1" type="array">
<cfset numHold=raNums[1]>
<cfset isSeq="">
<cfset hasSeq=0>
<cfsavecontent variable="numSeries">
<cfloop from="1" to="#arraylen(raNums)#" index="idxItem">
    <cfif idxItem eq 1>#raNums[1]#<!--- always output the first --->
    <cfelse>
        <!--- if in a sequence and not the last array element, no output --->
        <cfif numHold+1 eq raNums[idxItem] and idxItem neq arraylen(raNums)>
            <!--- capture the first value of the sequence --->
            <cfif len(isSeq) eq 0><cfset isSeq=numHold></cfif>
        <cfelseif len(isSeq)><!--- was in sequence but no longer --->
            <!--- if more than 2 in a row, show as sequence (n-n) --->
            <cfif idxItem eq arraylen(raNums) and raNums[idxItem] gt isSeq+1>
                - #raNums[idxItem]#
                <cfif hasSeq lt numHold - isSeq+1><cfset hasSeq=numHold - isSeq+1></cfif>
            <cfelseif raNums[idxItem] gt isSeq+3>
                - #numHold#, #raNums[idxItem]#
                <cfif hasSeq lt numHold - isSeq+1><cfset hasSeq=numHold - isSeq+1></cfif>
            <!--- otherwise show the 2nd (held) sequential value and current array value --->
            <cfelse>, #isSeq+1#, #raNums[idxItem]#
            </cfif>
            <cfset isSeq="">
        <cfelse>, #raNums[idxItem]#<!--- not in sequence --->
        </cfif>
    </cfif>
    <cfset numHold=raNums[idxItem]>
</cfloop>
</cfsavecontent>
<!--- <cfreturn replace(numSeries, " ,", ",", "all")> --->
<cfreturn hasSeq>
</cffunction>