我需要识别 if 数字列表是否按照真实顺序。特别是5的序列。
示例1:
1,3,4,67,43,20
1,3,4,20,43,67
FALSE
示例2
147,10,143,432,144,23,145,146
10,23,143,144,145,146,147,432
TRUE
(即143-147)目前 - 我遍历有序列表,并检查当前号码是否等于最后一个号码+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>
答案 0 :(得分:2)
对于性能,我会说你的循环包装在IF语句中,首先检查至少有5个元素;没有点循环4个元素。
然后我会说,如果'seq'= 5,在循环内做一个检查,并立即退出循环(除非你实际上需要找出序列的长度,如果它大于5)。
你可能会考虑另外一件事。在循环之前,您可以比较列表的第一个元素和列表的最后一个元素。如果它们之间的差异小于5,则完全没有必要进行循环。虽然根据您的数据看起来这可能不太可能发生。
答案 1 :(得分:1)
听起来你想要了解更多关于算法时间复杂度(https://en.wikipedia.org/wiki/Time_complexity)的内容。
您当前的算法首先进行排序然后迭代所有元素。要确定算法的时间复杂度,我们首先要知道Coldfusion的排序算法的时间复杂度。由于Coldfusion委托给Java,Java Arrays使用QuickSort算法,我们知道算法的排序部分需要n*log(n)
时间。迭代数组的算法的第二部分需要n
次。将这两个时间复杂性加在一起,我们得到n+(n*log(n))
。
在分析算法的时间复杂度时,我们只关注最慢的部分:n*log(n)
。因此,Big O时间复杂度为O(n*log(n))
。
这是什么意思?解决方案的排序部分是最糟糕的部分。如果您可以在不进行排序的情况下解决问题,那么您可以提高应用程序的速度 - 假设您的新解决方案没有做任何比排序需要更多时间的事情。
答案 2 :(得分:0)
我会在序列中创建一个Array,然后比较Array。这是一个很好的例子:link
答案 3 :(得分:0)
我在这里提出这个答案是因为我需要一个函数来输出一系列数字,其中任何内部序列的序列都超过2个连字符(即1,3,4,5,7
为1,3-5,7
)并且没有'在其他任何地方快速找到它。你的代码看起来不再是我的了,所以我的帮助可能对你不利,尽管它可以回答你的问题,因为活跃的cfreturn
提供了最长的序列(你可以将你的5楼作为比较)。(我的评论out cfreturn
给出了我所需的内部序列缩写:
<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>