文章出處

業務背景:
航空貨運系統中,“貨運代理商”會定期從“航空公司”領取一定數量的紙質運單(每張紙上有一個單號),這些單號都是連續的(即:每次可以理解為領取一個“號段”),而且每張單子都要向航空公司交納一定的費用(即:單號是有價的資產)。

實際使用中,貨運代理商希望下級的各營業點連續把單號用完,如果出現未連續使用的情況(即:所謂的跳號),要求快速找出來,給予提醒,提示用戶優先使用跳號的運單。(否則這些運單號,一直可能不被注意到,造成浪費,而且每到期末跟航空公司對賬時,也對不清楚)

思路: 

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),正則表達式方式優勢明顯;數組較小于時,手動雙重循環更快


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()