文章出處
文章列表
業務背景:
航空貨運系統中,“貨運代理商”會定期從“航空公司”領取一定數量的紙質運單(每張紙上有一個單號),這些單號都是連續的(即:每次可以理解為領取一個“號段”),而且每張單子都要向航空公司交納一定的費用(即:單號是有價的資產)。
實際使用中,貨運代理商希望下級的各營業點連續把單號用完,如果出現未連續使用的情況(即:所謂的跳號),要求快速找出來,給予提醒,提示用戶優先使用跳號的運單。(否則這些運單號,一直可能不被注意到,造成浪費,而且每到期末跟航空公司對賬時,也對不清楚)
思路:
A:
一個號段的號碼,抽象成一個數組;每個號碼的使用狀態,也抽象成一個等長的數組(Y表示已使用,N表示未使用)
這樣使用狀態就可形成 類似 "YYYYNNYYNYNNN" 的字符串,只找正則表達式找到 "N...Y"的位置,即為跳號的位置(即:下標值),根據該位置,即可方便取出跳號的號碼
B:
如果不使用正則表達式,直接雙重循環,也可以查找到,若某一個元素為“N”,在它后面還有"Y",則表示該元素“被跳號”了
1 <!doctype html> 2 <html> 3 <head> 4 <title>find SKip Number</title> 5 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //號段的運單列表 10 var arrAwbNo = ['001','002','003','004','005','006','007','008','009','010']; 11 12 //該號段的單號使用狀態列表(Y已使用,N未使用) 13 var arrStatus =['Y', 'Y', 'N', 'N', 'Y', 'N', 'Y' , 'N', 'Y', 'N']; 14 15 //利用正則表達式查找 16 alert("正則表達式方法查找結果:" + findSkipNumberA(arrAwbNo,arrStatus) ); 17 18 //利用循環直接查找 19 alert("雙重循環查找結果:" + findSkipNumberB(arrAwbNo,arrStatus) ); 20 21 function findSkipNumberA(awbNos, awbStatus){ 22 var status = awbStatus.join(''); 23 var groups = status.match(/(N+Y)/ig); //利用正則表達式找出 NY,NNY,...,N***Y的跳號部分 24 25 if (groups!=null){ 26 var gapIndex = []; 27 //先找到跳號位置的下標索引 28 for(var i = 0;i<groups.length;i++){ 29 var g = groups[i]; 30 //alert(g); //輔助輸出 31 var start = (gapIndex.length<=0 ? 0 : gapIndex[gapIndex.length-1]); 32 start = (start==0 ? 0 : start + g.length); 33 34 var t = status.indexOf(g,start) 35 gapIndex.push(t); 36 37 //NN...Y的處理 38 if (g.length>2){ 39 for(var j=1;j<g.length-1;j++){ 40 gapIndex.push(t+j); 41 } 42 } 43 } 44 45 //根據索引,直接取出跳號號碼 46 var gapNo = []; 47 for(i =0;i<gapIndex.length;i++){ 48 gapNo.push(awbNos[gapIndex[i]]); 49 } 50 return gapNo; 51 } 52 53 return null; 54 } 55 56 function findSkipNumberB(awbNos, awbStatus){ 57 var skipNumbers = []; 58 for(var i=0 ; i<arrStatus.length-1 ; i++){ 59 for(var j=i+1 ; j<arrStatus.length; j++){ 60 if (awbStatus[i]=="N" && awbStatus[j]=="Y"){ 61 skipNumbers.push(awbNos[i]); 62 break; 63 } 64 } 65 } 66 return skipNumbers; 67 } 68 69 </script> 70 </body> 71 </html>
C#的實現:
1 static String[] findSkipNumberA(Regex reg, String[] awbNos, String awbStatus) 2 { 3 //Regex reg = new Regex("N+Y", RegexOptions.Compiled); 4 List<string> result = new List<string>(); 5 6 MatchCollection matchs = reg.Matches(awbStatus); 7 8 int findStartIndex = 0; 9 foreach (Match m in matchs) 10 { 11 String matchValue = m.Groups[0].Value; 12 findStartIndex = awbStatus.IndexOf(matchValue, (findStartIndex > 0 ? findStartIndex + 1 : 0)); 13 for (int i = 0; i < matchValue.Length - 1; i++) 14 { 15 result.Add(awbNos[findStartIndex + i]); 16 } 17 18 findStartIndex += (matchValue.Length - 1);//更新下次IndexOf查找的起始位置 19 } 20 21 return result.ToArray(); 22 } 23 24 static String[] findSkipNumberB(String[] awbNos, String[] awbStatus) 25 { 26 List<string> result = new List<string>(); 27 for (int i = 0; i < awbStatus.Length - 1; i++) 28 { 29 for (int j = i + 1; j < awbStatus.Length; j++) 30 { 31 if (awbStatus[i] == "N" && awbStatus[j] == "Y") 32 { 33 result.Add(awbNos[i]); 34 break; 35 } 36 } 37 } 38 return result.ToArray(); 39 }
c#版實際測試下來,如果數組較大(>200),正則表達式方式優勢明顯;數組較小于時,手動雙重循環更快
文章列表
全站熱搜