??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产91色在线,日韩三级影视,中文字幕国产在线http://www.aygfsteel.com/jlin/category/51569.htmlzh-cnThu, 27 Mar 2014 21:03:10 GMTThu, 27 Mar 2014 21:03:10 GMT60扑և数组中唯一重复的数http://www.aygfsteel.com/jlin/archive/2014/03/27/411576.htmlflyflyThu, 27 Mar 2014 11:40:00 GMThttp://www.aygfsteel.com/jlin/archive/2014/03/27/411576.htmlhttp://www.aygfsteel.com/jlin/comments/411576.htmlhttp://www.aygfsteel.com/jlin/archive/2014/03/27/411576.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/411576.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/411576.html题目Q?/p>

数组a[N]Q?至N-1qN-1个数存放在a[N]中,其中某个数重复一ơ。写一个函敎ͼ扑և被重复的数字?/p>

Ҏ(gu)一Q异或法?/p>

数组a[N]中的N个数异或l果?至N-1异或的结果再做异或,得到的值即为所求?/p>

  • N复数为AQ其余N-2个数异或l果为B?/span> 
  • N个数异或l果为A^A^B 
  • 1至N-1异或l果为A^B 
  • ׃异或满交换律和l合律,且X^X = 0  0^X = X; 
  • 则有 
  • (A^B)^(A^A^B)=A^B^B=A 

代码Q?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #include<time.h>  
  5. void xor_findDup(int * a,int N)    
  6. {    
  7.     int i;    
  8.     int result=0;    
  9.     for(i=0;i<N;i++)    
  10.     {    
  11.         result ^= a[i];    
  12.     }    
  13.       
  14.     for (i=1;i<N;i++)     
  15.     {    
  16.         result ^= i;    
  17.     }    
  18.       
  19.     printf("%d\n",result);    
  20.       
  21. }    
  22.  
  23.  
  24.  
  25. int main(int argc, char* argv[])    
  26. {    
  27.     int a[] = {1,2,1,3,4};    
  28.     xor_findDup(a,5);    
  29.     return 0;    
  30. }   

 Ҏ(gu)二:数学法?/p>

Ҏ(gu)l的所有项求和Q减?至N-1的和Q即为所求数?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #include<time.h>  
  5. void xor_findDup(int * a,int N)    
  6. {    
  7.     int tmp1 = 0;  
  8.       
  9.     int tmp2 = 0;  
  10.       
  11.     for (int i=0; i<N-1; ++i)  
  12.           
  13.     {  
  14.           
  15.         tmp1+=(i+1);  
  16.           
  17.         tmp2+=a[i];  
  18.           
  19.     }  
  20.     tmp2+=a[N-1];  
  21.     int result=tmp2-tmp1;     
  22.     printf("%d\n",result);    
  23.       
  24. }    
  25.  
  26.  
  27.  
  28. int main(int argc, char* argv[])    
  29. {    
  30.     int a[] = {1,2,4,3,4};    
  31.     xor_findDup(a,5);    
  32.     return 0;    
  33. }   

对于求和Q可以直接根据公式定义一个宏?define sum(x)  (x*(x+1)/2)
 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #include<time.h>  
  5. #define sum(x)  (x*(x+1)/2)   
  6. void xor_findDup(int * a,int N)    
  7. {    
  8.     int tmp1 = sum((N-1));//注意N-1要加括号     
  9.     int tmp2 = 0;  
  10.       
  11.     for (int i=0; i<N; ++i)       
  12.     {             
  13.         tmp2+=a[i];   
  14.     }  
  15.     int result=tmp2-tmp1;     
  16.     printf("%d\n",result);        
  17. }    
  18.  
  19. int main(int argc, char* argv[])    
  20. {    
  21.     int a[] = {1,2,4,2,3};    
  22.     xor_findDup(a,5);    
  23.     return 0;    
  24. }   

 Ҏ(gu)三:标志数组?/p>

甌一个长度ؓn-1且均?0'l成的字W串。然后从头遍历a[n]数组Q取每个数组元素a[i]的|其对应的字W串中的相应位置|?Q如果已l置q?的话Q那么该数就是重复的数。就是用位图来实现的?如果考虑I间复杂度的话,其空间OQNQ?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #include<time.h>  
  5. #define sum(x)  (x*(x+1)/2)   
  6. void xor_findDup(int * arr,int NUM)    
  7. {    
  8.     int *arrayflag = (int *)malloc(NUM*sizeof(int));      
  9.     int i=1;  
  10.       
  11.     while(i<NUM)  
  12.     {  
  13.         arrayflag[i] = false;  
  14.         i++;  
  15.     }     
  16.       
  17.     for( i=0; i<NUM; i++)         
  18.     {         
  19.         if(arrayflag[arr[i]] == false)            
  20.             arrayflag[arr[i]] = true;          // |出现标? 
  21.           
  22.         else      
  23.         {   
  24.             printf("%d\n",arr[i]);  
  25.             return ; //q回已经出现的? 
  26.         }  
  27.           
  28.      }    
  29. }    
  30.  
  31. int main(int argc, char* argv[])    
  32. {    
  33.     int a[] = {1,3,2,4,3};    
  34.     xor_findDup(a,5);    
  35.     return 0;    
  36. }    

 Ҏ(gu)四:固定偏移量法

a[N]Q里面是1至N-1。原数组a[i]最大是N-1Q若a[i]=K在某处出现后Q将a[K]加一ơNQ做标记Q当某处a[i]=K再次成立Ӟ查看a[K]卛_知道K已经出现q。该Ҏ(gu)不用另外开辟O(N)的内存空_但是在查重之后要数l进行恢复?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <math.h>  
  4. #include<time.h>  
  5. void xor_findDup(int * arr,int NUM)    
  6. {    
  7.     int temp=0;       
  8.     for(int i=0; i<NUM; i++)          
  9.     {  
  10.           
  11.         if(arr[i]>=NUM)           
  12.             temp=arr[i]-NUM;            // 该值重复了Q因为曾l加q一ơ了        
  13.         else              
  14.             temp=arr[i];          
  15.                   
  16.         if(arr[temp]<NUM)         
  17.         {         
  18.             arr[temp]+=NUM; //做上标记            
  19.         }  
  20.           
  21.         else              
  22.         {             
  23.             printf("有重?nbsp;%d\n",temp);              
  24.             return;           
  25.         }         
  26.     }  
  27.               
  28.     printf("无重?);  
  29.     return ;   
  30. }    
  31. void clear(int *data,int num)//清理数据  
  32. {  
  33.     for(int i=0;i<num;i++)  
  34.     {  
  35.         if(data[i]>num)  
  36.             data[i]-=num;  
  37.     }  
  38.  
  39. }  
  40. int main(int argc, char* argv[])    
  41. {    
  42.     int a[] = {2,4,3,4,1};    
  43.     xor_findDup(a,5);    
  44.     clear(a,5);  
  45.     return 0;    
  46. }    

 Ҏ(gu)五:W号标志?/p>

上个Ҏ(gu)出现后是加NQ也可以出现后加个负P是W号标志法?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <math.h>  
  5. #include<time.h>  
  6.  
  7. void xor_findDup(int * arr,int NUM)    
  8. {         
  9.     int temp=0;          
  10.     for(int i=0; i<NUM; i++)        
  11.     {                    
  12.         if(arr[i]<0)     
  13.             temp=0-arr[i];  // 该值重复了Q因为曾l加q一ơ了     
  14.         else                           
  15.             temp=arr[i];                
  16.         if(arr[temp]>0)             
  17.         {                    
  18.             arr[temp]=0-arr[temp]; //做上标记        
  19.         }                
  20.         else              
  21.         {               
  22.             printf("有重?nbsp;%d\n",temp);      
  23.             return;               
  24.         }            
  25.     }                
  26.     printf("无重?);    
  27.     return ;    
  28.  }     
  29.  void clear(int *data,int num)//清理数据  
  30.  {     
  31.      for(int i=0;i<num;i++)     
  32.      {        
  33.          if(data[i]<0)           
  34.              data[i]=0-data[i];     
  35.    }     
  36. }    
  37.  int main(int argc, char* argv[])    
  38.  {        
  39.      int a[] = {3,2,1,4,1};       
  40.      xor_findDup(a,5);     
  41.      clear(a,5);      
  42.      return 0;    
  43.  }      

以上的方法对数组元素的值的范围是有限制的,如果数组元素的g是在1至N-1范围Ӟ可以先求出数l元素的最大倹{?/p>

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <string.h>  
  4. #include <math.h>  
  5. #include<time.h>  
  6.  
  7. int  do_dup_mal(int arr[], int n, int *pre, int *back)  
  8. {  
  9.     int MAX = -1;  
  10.     int i = 0;  
  11.     int sameVal = -1;  
  12.     *pre = *back = -1;  
  13.       
  14.     for (int j=0; j<n; j++)  
  15.     {  
  16.         if (arr[j] > MAX) MAX = arr[j];//扑և数组中的最大数  
  17.     }  
  18.       
  19.     char *arrayflag = new char[MAX+1] ;  
  20.     if (NULL == arrayflag)  
  21.         return -1;  
  22.     memset(arrayflag, 0, MAX+1 ); // '\0' == 0  
  23.     for(i=0; i<n; i++)  
  24.     {  
  25.         if(arrayflag[arr[i]] == '\0')  
  26.             arrayflag[arr[i]] = '\1'// |出现标? 
  27.         else 
  28.         {  
  29.             sameVal = arr[i]; //q回已经出现的? 
  30.             *back = i;  
  31.             break;  
  32.         }  
  33.     }  
  34.     delete[] arrayflag;  
  35.     if (i < n)  
  36.     {  
  37.         for (int j=0; j<n; j++)  
  38.         {  
  39.             if (sameVal == arr[j])  
  40.             {  
  41.                 *pre = j;  
  42.                 return true;  
  43.             }  
  44.         }  
  45.     }  
  46.     return false;  
  47. }  
  48.  
  49.  
  50.  
  51.  
  52.  
  53. void main(int argc, char *argv[])  
  54. {  
  55.     int prePos = -1, backPos = -1;  
  56.     int myArry[11];  
  57.     myArry[0] = 1;  
  58.     myArry[1] = 3;  
  59.     myArry[2] = 3;  
  60.     myArry[3] = 4;  
  61.     myArry[4] = 5;  
  62.     myArry[5] = 22;  
  63.     myArry[6] = 7;  
  64.     myArry[7] = 13;  
  65.     myArry[8] = 9;  
  66.     myArry[9] = 2;  
  67.     myArry[10] = 12;  
  68.       
  69.       
  70.     if (do_dup_mal(myArry, 11, &prePos, &backPos) )  
  71.         printf("%d\n",myArry[prePos]);  
  72. }  
  73.    

转:http://buptdtt.blog.51cto.com/2369962/749049  



fly 2014-03-27 19:40 发表评论
]]>
快速排序(QuicksortQ的Javascript实现Q{Q?/title><link>http://www.aygfsteel.com/jlin/archive/2013/04/11/397675.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Wed, 10 Apr 2013 16:35:00 GMT</pubDate><guid>http://www.aygfsteel.com/jlin/archive/2013/04/11/397675.html</guid><wfw:comment>http://www.aygfsteel.com/jlin/comments/397675.html</wfw:comment><comments>http://www.aygfsteel.com/jlin/archive/2013/04/11/397675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jlin/comments/commentRss/397675.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jlin/services/trackbacks/397675.html</trackback:ping><description><![CDATA[<p>目前Q最常见的排序算法大概有七八U,其中<a target="_blank">"快速排?</a>QQuicksortQ用得最q泛Q速度也较快。它是图灵奖得主C. A. R. HoareQ?934--Q于1960时提出来的?/p> <p><img src="http://image.beekka.com/blog/201104/bg2011040402.jpg" alt="" /></p> <p>"快速排?的思想很简单,整个排序q程只需要三步:</p> <blockquote> <p>  Q?Q在数据集之中,选择一个元素作?基准"QpivotQ?/p> <p>  Q?Q所有小?基准"的元素,都移?基准"的左边;所有大?基准"的元素,都移?基准"的右辏V?/p> <p>  Q?Q对"基准"左边和右边的两个子集Q不断重复第一步和W二步,直到所有子集只剩下一个元素ؓ止?/p></blockquote> <p>举例来说Q现在有一个数据集{85, 24, 63, 45, 17, 31, 96, 50}Q怎么对其排序呢?</p> <p>W一步,选择中间的元?5作ؓ"基准"。(基准值可以Q意选择Q但是选择中间的值比较容易理解。)</p> <p><img src="http://image.beekka.com/blog/201104/bg2011040403.png" alt="" /></p> <p>W二步,按照序Q将每个元素?基准"q行比较QŞ成两个子集,一?于45"Q另一?大于{于45"?/p> <p><img src="http://image.beekka.com/blog/201104/bg2011040404.png" alt="" /></p> <p>W三步,对两个子集不断重复第一步和W二步,直到所有子集只剩下一个元素ؓ止?/p> <p><img src="http://image.beekka.com/blog/201104/bg2011040405.png" alt="" /></p> <p><img src="http://image.beekka.com/blog/201104/bg2011040406.png" alt="" /></p> <p><img src="http://image.beekka.com/blog/201104/bg2011040407.png" alt="" /></p> <p><img src="http://image.beekka.com/blog/201104/bg2011040408.png" alt="" /></p> <p>下面参照|上的资料(<a target="_blank">q里</a>?a target="_blank">q里</a>Q,用Javascript语言实现上面的算法?/p> <p>首先Q定义一个quickSort函数Q它的参数是一个数l?/p> <blockquote> <p>var quickSort = function(arr) {</p> <p>};</p></blockquote> <p>然后Q检查数l的元素个数Q如果小于等?Q就q回?/p> <blockquote> <p>var quickSort = function(arr) {</p> <p>  <strong>if (arr.length <= 1) { return arr; }</strong></p> <p>};</p></blockquote> <p>接着Q选择"基准"QpivotQ,q将其与原数l分,再定义两个空数组Q用来存放一左一右的两个子集?/p> <blockquote> <p>var quickSort = function(arr) {</p> <p>  if (arr.length <= 1) { return arr; }</p> <p>  <strong>var pivotIndex = Math.floor(arr.length / 2) ;</strong></p> <p>  <strong>var pivot = arr.splice(pivotIndex, 1)[0];</strong></p> <p>  <strong>var left = [];</strong></p> <p>  <strong>var right = [];</strong></p> <p>};</p></blockquote> <p>然后Q开始遍历数l,于"基准"的元素放入左边的子集Q大于基准的元素攑օ双的子集?/p> <blockquote> <p>var quickSort = function(arr) {</p> <p>  if (arr.length <= 1) { return arr; }</p> <p>  var pivotIndex = Math.floor(arr.length / 2) ;</p> <p>  var pivot = arr.splice(pivotIndex, 1)[0];</p> <p>  var left = [];</p> <p>  var right = [];</p> <p>  <strong>for (var i = 0; i < arr.length; i++){</strong></p> <p>    <strong>if (arr[i] < pivot) {</strong></p> <p>      <strong>left.push(arr[i]);</strong></p> <p>    <strong>} else {</strong></p> <p>      <strong>right.push(arr[i]);</strong></p> <p>    <strong>}</strong></p> <p>  <strong>}</strong></p> <p>};</p></blockquote> <p>最后,使用递归不断重复q个q程Q就可以得到排序后的数组?/p> <blockquote> <p>var quickSort = function(arr) {</p> <p>  if (arr.length <= 1) { return arr; }</p> <p>  var pivotIndex = Math.floor(arr.length / 2);</p> <p>  var pivot = arr.splice(pivotIndex, 1)[0];</p> <p>  var left = [];</p> <p>  var right = [];</p> <p>  for (var i = 0; i < arr.length; i++){</p> <p>    if (arr[i] < pivot) {</p> <p>      left.push(arr[i]);</p> <p>    } else {</p> <p>      right.push(arr[i]);</p> <p>    }</p> <p>  }</p> <p>  <strong>return quickSort(left).concat([pivot], quickSort(right));</strong></p> <p>};</p></blockquote> <p>使用的时候,直接调用quickSort()p了?</p> <p><img src="http://image.beekka.com/blog/201104/bg2011040409.png" alt="" /></p> <p>Q完Q?br /></p><!-- /div --><img src ="http://www.aygfsteel.com/jlin/aggbug/397675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jlin/" target="_blank">fly</a> 2013-04-11 00:35 <a href="http://www.aygfsteel.com/jlin/archive/2013/04/11/397675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java实现快速排??http://www.aygfsteel.com/jlin/archive/2013/04/11/397674.htmlflyflyWed, 10 Apr 2013 16:30:00 GMThttp://www.aygfsteel.com/jlin/archive/2013/04/11/397674.htmlhttp://www.aygfsteel.com/jlin/comments/397674.htmlhttp://www.aygfsteel.com/jlin/archive/2013/04/11/397674.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/397674.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/397674.html

         快速排序的基本思想Q?/p>

         通过一排序将待排序记录分割成独立的两部分Q其中一部分记录的关键字均比另一部分关键字小Q则分别对这两部分l进行排序,直到整个序列有序?/p>

       先看一下这q图Q?/p>


把整个序列看做一个数l,把第零个位置看做中uQ和最后一个比Q如果比它小交换Q比它大不做M处理Q交换了以后再和的那端比,比它?yu)不交换Q比他大交换。这样@环往复,一排序完成,左边是比中轴小的,双是比中轴大的,然后再用分治法,分别对这两个独立的数l进行排序?/p>

    

  1. public int getMiddle(Integer[] list, int low, int high) {  
  2.         int tmp = list[low];    //数组的第一个作Z?nbsp; 
  3.         while (low < high) {  
  4.             while (low < high && list[high] > tmp) {  
  5.                 high--;  
  6.             }  
  7.             list[low] = list[high];   //比中轴小的记录移C?nbsp; 
  8.             while (low < high && list[low] < tmp) {  
  9.                 low++;  
  10.             }  
  11.             list[high] = list[low];   //比中轴大的记录移到高?nbsp; 
  12.         }  
  13.         list[low] = tmp;              //中u记录到尾  
  14.         return low;                   //q回中u的位|?nbsp; 
  15.     }  

       递归形式的分L序算法:

 

      

  1. public void _quickSort(Integer[] list, int low, int high) {  
  2.         if (low < high) {  
  3.             int middle = getMiddle(list, low, high);  //list数组q行一分ؓ?nbsp; 
  4.             _quickSort(list, low, middle - 1);        //对低字表q行递归排序  
  5.             _quickSort(list, middle + 1, high);       //寚w字表q行递归排序  
  6.         }  
  7.     }  

  
  1. public void quick(Integer[] str) {  
  2.         if (str.length > 0) {    //查看数组是否为空  
  3.             _quickSort(str, 0, str.length - 1);  
  4.         }  
  5.     }  

   ~写试Ҏ(gu)Q?

 

 

  1. public class TestMain {  
  2.   
  3.     /**  
  4.      * @param args  
  5.      */  
  6.     public static void main(String[] args) {  
  7.         // TODO Auto-generated method stub  
  8.          Integer[] list={34,3,53,2,23,7,14,10};  
  9.          QuicSort qs=new QuicSort();  
  10.          qs.quick(list);  
  11.          for(int i=0;i<list.length;i++){  
  12.              System.out.print(list[i]+" ");  
  13.          }  
  14.          System.out.println();  
  15.     }  
  16.   
  17. }  
     看一下打印结果吧Q?

 

     2 3 7 10 14 23 34 53
   

     q样排序好了,快速排序是对冒泡排序的一U改q,q_旉复杂度是O(nlogn)?br />



fly 2013-04-11 00:30 发表评论
]]>
字符串匹配算法ȝQ{Q?/title><link>http://www.aygfsteel.com/jlin/archive/2012/04/29/377004.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Sat, 28 Apr 2012 16:06:00 GMT</pubDate><guid>http://www.aygfsteel.com/jlin/archive/2012/04/29/377004.html</guid><wfw:comment>http://www.aygfsteel.com/jlin/comments/377004.html</wfw:comment><comments>http://www.aygfsteel.com/jlin/archive/2012/04/29/377004.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/jlin/comments/commentRss/377004.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/jlin/services/trackbacks/377004.html</trackback:ping><description><![CDATA[<div class="wmqeeuq" id="article_content" class="article_content"> <p>我想说一?#8220;我日Q我讨厌KMPQ?#8221;?br />KMP虽然l典Q但是理解v来极其复杂,好不Ҏ(gu)理解好了Q便L(fng)来巨ȝQ?br />老子是今天图书馆在写了几个时才勉强写了一个有bug的、效率不高的KMPQ特别是计算next数组的部分?br /><br />其实Q比KMP法速度快的法大把大把Q而且理解h更简单,Z非要抓住KMP呢?W试出现字符串模式匹配时直接上sunday法Q既单又高效Q何乐而不为?<br />说实话,惛_sunday法的那个hQ绝Ҏ(gu)发散思维Q绝对牛。当我在被KMP折磨的够呛的时候,我就琢磨Q有没有别的好算法呢Q?琢磨了半天也没想Z所以然来。笨啊,脑子不够发散?br /><br />下面贴上一位兄弟写的算法ȝQ很单(KMP部分׃用看了,看了费脑子)?br />参见Q?a >http://hi.baidu.com/willamette/blog/item/02bd0b5599c8b4c0b645ae06.html</a></p> <p>着做Presentation的功夫,Z做一个ȝ</p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">字符串匹配:</p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman">---willamette</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">在匹配串中寻找模式串是否出现Q注意和最长公共子序列相区?span style="font-family: Times New Roman">(LCS: Longest Common Substring)</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><br /><strong>-Q?/strong><span style="font-family: Times New Roman"><strong>Brute Force(BF或蛮力搜?</strong></span><strong>法Q?/strong></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">q是世界上最单的法了?br />首先匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">速度最慢?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">那么Q怎么改进呢?</p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">我们注意?span style="font-family: Times New Roman">Brute Force</span>法是每ơ移动一个单位,一个一个单位移动显然太慢,是不是可以找C些办法,让每ơ能够让模式串多Ud一些位|呢Q?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">当然是可以的?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">我们也注意到Q?span style="font-family: Times New Roman">Brute Force</span>是很?span style="font-family: Times New Roman">intelligent</span>的,每次匚w不成功的时候,前面匚w成功的信息都被当作废物丢弃了Q当Ӟ如现在的变废ؓ宝一P我们也同样可以将前面匚w成功的信息利用v来,极大地减计机的处理时_节省成本?span style="font-family: Times New Roman">^_^</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman">注意Q蛮力搜索算法虽焉度慢,但其很通用Q文章最后会有一些更多的关于蛮力搜烦的信息?/span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><br /><strong>-: KMP法<br /></strong><br />首先介绍的就?span style="font-family: Times New Roman">KMP</span>法?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">原始论文Q?span style="font-family: Times New Roman">Knuth D.E., Morris J.H., and Pratt V.R., Fast pattern matching in strings, SIAM Journal on Computing, 6(2), 323-350, 1977.</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">q个法实在是太有名了,大学上的法评除了最W的<span style="font-family: Times New Roman">Brute Force</span>法Q然后就介绍?span style="font-family: Times New Roman">KMP</span>法。也难怪,呵呵。谁?span style="font-family: Times New Roman">Knuth D.E.</span>q么<span style="font-family: Times New Roman">world famous</span>呢,不仅拿了囄奖,而且q写Z计算机界?span style="font-family: Times New Roman">Bible <The Art of Computer Programming>(</span>业内人士一般简U?span style="font-family: Times New Roman">TAOCP).</span>E稍提一下,有个?span style="font-family: Times New Roman">H.A.Simon</span>的家伙,不仅拿了<span style="font-family: Times New Roman">Turing Award</span>Q顺手拿了个<span style="font-family: Times New Roman">Nobel Economics Award</span>Q做?span style="font-family: Times New Roman">AI</span>的爸爸,q是<span style="font-family: Times New Roman">Chicago Univ</span>?span style="font-family: Times New Roman">Politics PhD</span>Q可谓全才?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: 'Times New Roman'">KMP的具体描q略去,教科书一大把?/span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><br /><strong>-QHorspool法<br /></strong><br /><span style="font-family: Times New Roman">Horspool</span>法?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">当然Q有市场有竞争Q字W串匚wq么大一个市场,不可能让<span style="font-family: Times New Roman">BF</span>?span style="font-family: Times New Roman">KMP</span>全部占了Q于是又出现了几个强劲的Ҏ(gu)?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">W一个登场的?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">论文Q?span style="font-family: Times New Roman">Horspool R.N., 1980, Practical fast searching in strings, Software - Practice & Experience, 10(6):501-506</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman">Horspool</span>法的思想很简单的。不q有个创C处就是模式串是从叛_左进行比较的。很好很强大Qؓ后来的算法媄响很大?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman"><span style="color: red">abcbc</span>sdxzcxx</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="color: red"><span style="font-family: Times New Roman">cbcac</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">q个时候我们从叛_左进行对暗号Q?span style="font-family: Times New Roman">c-c</span>Q恩对上了,W二?span style="font-family: Times New Roman">b-a</span>Q不对啊Q我们应该怎么办?Np么放弃么。于是,模式串从不匹配的那个字符开始从叛_左寻扑֌配串中不匚w的字W?span style="font-family: Times New Roman">b</span>的位|,l果发现居然有,赶快对上赶快对上Q别耽误了?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman">ab<span style="color: red">cbcsd</span>xzcxx</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="font-family: Times New Roman"><span> </span><span style="color: red">cbcac</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">然后l箋从最双的字W从叛_左进行比较。这时候,我们发现了,<span style="font-family: Times New Roman">d-c</span>不匹配啊Q而且模式IK面没有噢Q没办法Q只好移动一个模式串长度的单位了?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman">abcbcsd<span style="color: red">xzcxx</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="font-family: Times New Roman"><span> </span><span>     </span><span style="color: red">cbcac<br /><br /><span style="color: #000000"><strong><span style="font-family: andale mono,times">-QBoyer-Moore法</span></strong><br /></span><br /></span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">对于BM法Q下面推荐一个讲解非怼U的文章,可谓图文q茂啊,而且q是个MM写的?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">Boyer-Moore l典单模式匹配算?br /><a >http://blog.csdn.net/iJuliet/archive/2009/05/19/4200771.aspx</a><br /><br /><br /><strong>-QSunday法</strong></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">最后一个是<span style="font-family: Times New Roman">Sunday</span>法Q实际上?span style="font-family: Times New Roman">Boyer-Moore</span>q快Q呵c长江后推前浪?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">原始论文Q?span style="font-family: Times New Roman">Daniel M. Sunday, A very fast substring search algorithm, Communications of the ACM, v.33 n.8, p.132-142, Aug. 1990</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">看原始论文的题目Q?span style="font-family: Times New Roman">D.M. Sunday</span>貌似是故意想气气<span style="font-family: Times New Roman">Boyer-Moore</span>两位大牛似的。呵c不q实际上的确<span style="font-family: Times New Roman">Sunday</span>法的确?span style="font-family: Times New Roman">BM</span>法要快Q而且更简单?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman">Sunday</span>的算法思想?span style="font-family: Times New Roman">Horspool</span>有些怼Q但是。当出现不匹配的时候,却不是去扑֌配串中不匚w的字W在模式串的位置Q而是直接找最双寚w的右一位的那个字符在模式串的位|?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">比如Q?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman"><span style="color: red">abcbc</span>zdxzc</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="color: red"><span style="font-family: Times New Roman">zbcac</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">恩,q里我们看到<span style="font-family: Times New Roman">b-a</span>没有对上Q我们就看匹配串中的<span style="font-family: Times New Roman">z</span>在模式串的位|,然后Q嘿ѝ?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman">abcbc<span style="color: red">zdxzc</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="font-family: Times New Roman"><span>     </span><span style="color: red">zbcac</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">如果模式串中的没有那个字W怎么办呢Q很单,跌d?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman"><span style="color: red">abcbc</span>edxzcs</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="color: red"><span style="font-family: Times New Roman">zbcac</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal"><span style="font-family: Times New Roman">e</span>不在模式串中出现</p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">那么我们?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">匚wԌ<span style="font-family: Times New Roman">abcbce<span style="color: red">dxzcs</span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">模式Ԍ<span style="font-family: Times New Roman"><span>      </span><span style="color: red">zbcac<br /><br />(2009/10/20补充)<br /><strong><span style="color: #000000">RK法</span></strong></span></span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">某一天在图书馆的一本算法分析设计书上翻到的。思\很新颖!和大家分享下?br />在串匚w的简单算法中Q把文本每m个字W构成的字符D作Z个字D,和模式进行匹配检查。如果能对一个长度ؓm的字W?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">串赋以一个Hash函数。那么显然只有那些与模式h相同hash函数值的文本中的字符串才有可能与模式匚wQ这是必要条?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">Q而没有必要去考虑文本中所有长度ؓm的字D,因而大大提高了串匹配的速度。因此RK法的思想和KMPQBMQSunday{?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">路E然不同!<br />Q事实上Q之前的串匹配方法,是将模式串的一个一个字W作为小的特征去分别q行匚wQ而RK法则是串整体作ؓ一?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">特征Q难难在单个字W的特征很容易想得到Q整体作Z个特征就没那么容易想得到了)<br />如果把整体作Z个特征,那么如何快速的求出q个整体特征的特征|Q?br />模式串的特征g需求一ơ即可。对于文本中的Q意m个字W构成的字串如何快速的求特征就是个隄了?br />抛砖引玉Q这里给Z个简单的特征计算?字W串的每一个字W看做一个数Q那么这个字W串的就是一个数字数l,?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">q积分向量可以快速Q意一个长度子字符串的向量和。可以把字符串的对应的字W数l的元素和看做这个字W串整体特征?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">q个特征是可以再OQ?Q的旉内求出的。其实原始的RK法里面是把字符串看做一?6q制数在计算特征的。这里就不啰</p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">嗦了Q有兴趣的可以深入查?/p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">aab<span style="color: #ff0000">see</span>sds 模式?ees<br />      <span style="color: #ff0000">ees</span></p> <p style="margin: 0cm 0cm 0pt" class="MsoNormal">发现 see向量?== ees的向量和<br />然后对see和ees做逐个字符的比较。发C匚wl箋往下走<br />aabs<span style="color: #ff0000">ees</span>ds 模式?ees<br />        <span style="color: #ff0000">ees</span><br />发现 ees向量?== ees的向量和 <br />然后对ees和ees做逐个字符的比较。发现匹配OK?br /><br />另外q有 字符串匹配自动机 后缀树算法(分在U和非在U两U){?见如下文章。不能说那个比那个更好,各个法都有自己的优势及最?jng)_用场合。参考:<br /><a >http://blog.csdn.net/yifan403/archive/2009/06/16/4272793.aspx</a><br /><br />另外Q关于多模式字符串匹?有AC法Q字W串匚w自动机思想Q?WM法QBM在多模式的推q应用)<br />参考:<br /><a >http://blog.csdn.net/ijuliet/category/498465.aspx</a> 该女子的blog有很多好文章?br /><br />===============================================================================<br />一个sunday法的实?br /><a >http://hi.baidu.com/azuryy/blog/item/10d3d3460b97af0e6b63e5cd.html</a></p> <p>头文件定义:<br />/* Sunday.h */<br />class Sunday <br />{<br />public:<br />   Sunday();<br />   ~Sunday();<br /><br />public:<br />    int find(const char* pattern, const char* text);<br /><br />private:<br />    void preCompute(const char* pattern);<br /><br />private:<br />    //Let's assume all characters are all ASCII<br />    static const int ASSIZE = 128;<br />    int _td[ASSIZE] ;<br />    int _patLength;<br />    int _textLength;<br />};<br /><br /><br />源文?br />/* Sunday.cpp */<br /><br />Sunday::Sunday()<br />{<br />}<br /><br />Sunday::~Sunday()<br />{<br />}<br /><br />void Sunday::preCompute(const char* pattern)<br />{<br />    for(int i = 0; i < ASSIZE; i++ ) <br />        _td[i] = _patLength + 1;<br /><br />    const char* p;<br />    for ( p = pattern; *p; p++)<br />        _td[*p] = _patLength - (p - pattern);<br />}<br /><br />int Sunday::find(const char* pattern, const char* text)<br />{<br />    _patLength = strlen( pattern );<br />    _textLength = strlen( text );<br /><br />    if ( _patLength <= 0 || _textLength <= 0)<br />        return -1;<br /><br />    preCompute( pattern );<br /><br />    const char *t, *p, *tx = text;<br /><br />    while (tx + _patLength <= text + _textLength) <br />    {<br />        for (p = pattern, t = tx; *p; ++p, ++t)<br />        {<br />            if (*p != *t)<br />                break;<br />        }<br />        if (*p == 0)<br />            return tx-text;<br />        tx += _td[tx[_patLength]]; <br />    }<br />    return -1;<br />}<br /><br />单测试下Q?br />int main()<br /><br />{<br />    char* text = "blog.csdn,blog.net";<br />    char* pattern = "csdn,blog"    ;<br />    Sunday sunday;<br /><br />    printf("The First Occurence at: %d/n",sunday.find(pattern,text));<br /><br />    return 1;<br />}<br /><br />////////////////////////////////////////////<br />strstr的实现?br />需要说明的是strstr是c语言提供的用Brute Force实现的字W串匚wQ简单、通用是其最大的优点。时间复杂度是O(mn)<br />// 下面是Microsoft的实?br />//l典法<br />//比KMP法?没有KMP法高效<br />char * __cdecl strstr (<br />        const char * str1,<br />        const char * str2<br />        )<br />{<br />        char *cp = (char *) str1;<br />        char *s1, *s2;<br />        if ( !*str2 )<br />            return((char *)str1);<br />        while (*cp)<br />        {<br />                s1 = cp;<br />                s2 = (char *) str2;<br />                while ( *s1 && *s2 && !(*s1-*s2) )<br />                        s1++, s2++;<br />                if (!*s2)<br />                        return(cp);<br />                cp++;<br />        }<br />        return(NULL);<br />} </p> <p>本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/whoismickey/archive/2009/02/08/3869367.aspx</a></p> <h4 id="subjcns!7AC7C90F5324ACF3!219" class="beTitle">strstr</h4> <div class="wmqeeuq" id="msgcns!7AC7C90F5324ACF3!219" class="bvMsg"> <div>  glibc里的strstr函数用的是brute-force(naive)法Q它与其它算法的区别是strstr不对pattern(needle)q行预处理,所以用h很方ѝ理论复杂度O</div> <div>(mn), 实际上,q_复杂度ؓO(n), 大部分情况下高度优化的算法性能要优于基于自动机的匹配算法,关于串匹配算法可参?a >http://www-igm.univ-mlv.fr/~lecroq/string/</a>?nbsp;glibc中用了Q?QStephen R. van den Berg的实玎ͼ在他的基上,Q?Q?span style="font-family: 'Courier New'">Tor Myklebust </span><a >http://sources.redhat.com/ml/libc-alpha/2006-07/msg00028.html</a>l出了更复杂的实玎ͼ当然也更高效?/div> <div>  BF有一个重要性质是事先不用知道串的长度,而基于蟩跃的法是需要用字符串长度来判断l束位置的。如何快速的定字符串结束位|,可参?a >http://www.cppblog.com/ant/archive/2007/10/12/32886.html</a>Q写的很仔细?/div> <div> 两U思想l合hQ可以做出更快的strstrQ?Q。约定(1Q?为strstrBerg; (2) 为strstrBergoQ(3QؓlstrstrQ(4Qؓglibc中的strstrQ简单测试了一下:</div> <div>从长度ؓ2k的文本中查找长度???的模式串Q结果如?/div> <div>        1               2              9</div> <div>Q?Q?.000006 0.000006 0.000012    </div> <div>Q?Q?.000007 0.000004 0.000008</div> <div>Q?Q?.000002 0.000002 0.000005</div> <div>Q?Q?.000005 0.000005 0.000011<br /><a >下蝲strstr和测试程?/a>Q?<br />下蝲后执?: <br />            unzip testStrstr.zip<br />            cd testStrstr<br />            make test</div> <div><a target="_blank">Zsse2的strstr函数</a> 是用sse2指o集对strstr的优?/div></div></div><img src ="http://www.aygfsteel.com/jlin/aggbug/377004.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/jlin/" target="_blank">fly</a> 2012-04-29 00:06 <a href="http://www.aygfsteel.com/jlin/archive/2012/04/29/377004.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boyer-Moore l典单模式匹配算法(转)http://www.aygfsteel.com/jlin/archive/2012/04/28/377001.htmlflyflySat, 28 Apr 2012 14:59:00 GMThttp://www.aygfsteel.com/jlin/archive/2012/04/28/377001.htmlhttp://www.aygfsteel.com/jlin/comments/377001.htmlhttp://www.aygfsteel.com/jlin/archive/2012/04/28/377001.html#Feedback0http://www.aygfsteel.com/jlin/comments/commentRss/377001.htmlhttp://www.aygfsteel.com/jlin/services/trackbacks/377001.html阅读全文

fly 2012-04-28 22:59 发表评论
]]>
վ֩ģ壺 ̩| ̨| ¡| | | ʡ| ÷| ƴ| ̳| ױ| | ʲ| ˹| ״| | | Ƿ| | ν| ٲ| ʲ| | | ƽ| żҴ| | ¹Ȫ| Ϫ| ʩ| Ƕ| ˺| | | Ͽ| | | Դ| ƽ| Ȩ| | Դ|