Problem Solving using C++

Algorithm Study using C++

#

排序算法总结(5)--快速排序

快速排序(Quick Sort)其是速度最快的排序方式,时间复杂度为O(nlogn),最差情况下为O(n^2).由于O(nlogn)中的系数很小,所以很快,在实际中应用多。其是in place的排序方式,但是unstable(不稳定)
快速排序也是使用分而治之方法的应用,将任务分成子任务(divide),然后解决子任务(conquer),最后将结果组合起来。
其主要由2部分组成,partition(int p,int r)和quicksort(int p,int r).
其中quicksort(int p,int r)
{
    if(p<r)
    {
         int q = parition(p,r);
         quicksort(p,q-1);
         quicksort(q+1,r);
    }
}
而parition(int p,int r)函数只是选取一个pivot,然后将pivot将两部分分开。
具体的代码如下:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>
#include 
<cstdlib>
#include 
<time.h>
#include 
<windows.h>

#define MAXSIZE    
10000000
int arr[MAXSIZE];

using namespace std;

void print(bool flag=false)
{
    
if(flag)
    {
        copy(arr,arr
+MAXSIZE,ostream_iterator<int>(cout," "));
        cout
<<endl;
    }
}

void merge(int A[],int p,int q,int r)
{
    
int left = q-p+1;
    
int right = r-q;
    
    
int* L=new int[left];
    
int* R = new int[right];
    
    
int i,j,k;
    
for(i=0;i<left;i++)
        L[i]
=A[p+i];
    
for(j=0;j<right;j++)
        R[j]
=A[q+j+1];
        
    
for(k=0,i=0,j=0;(i<left)&&(j<right);k++)
    {
        
if(L[i]<=R[j])
            {
                A[p
+k]=L[i];
                i
++;
            }
        
else
        {
            A[p
+k]=R[j];
            j
++;
        }
    }
    
    
if(i<left)
    {
        
for(;i<left;i++,k++)
            A[p
+k]=L[i];
    }
    
if(j<right)
    {
        
for(;j<right;j++,k++)
            A[p
+k]=R[j];
    }
    
    delete [] L;
    delete [] R;
}

void mergesort(int A[],int p, int r)
{
    
if(p<r)
    {
        
int q = (p+r)/2;
        mergesort(A,p,q);
        mergesort(A,q
+1,r);
        merge(A,p,q,r);
    }
}

/*********************************
/**** Heap Sort Functions
/*******************************
*/
void max_heapify(int i,int size)//size stands for heap size
{
    
int left = i<<1;
    
int right = left+1;
    
    
//get the largest of the i/left/right
    int largest;
    
    
if((left<=size)&&(arr[left]>arr[i]))
    {
        largest 
= left;
    }
    
else
        largest 
= i;
        
    
if((right<=size)&&(arr[right]>arr[largest]))
        largest 
= right;
        
    
//exchange the value of i and largest
    if(i!=largest)
    {
        
int temp =arr[i];
        arr[i]
=arr[largest];
        arr[largest]
=temp;
        
        max_heapify(largest,size);
    }
}

void build_max_heap()
{
    
int size = sizeof(arr)/sizeof(arr[0])-1;
    
for(int i=size/2;i>0;i--)
        max_heapify(i,size);
}

void heapsort()
{
    build_max_heap();
    
    
int size = sizeof(arr)/sizeof(arr[0])-1;
    
//int heapsize = size;
    
    
for(int i=size;i>1;i--)
    {
        
int temp = arr[1];
        arr[
1]=arr[i];
        arr[i]
=temp;
        
        
//heapsize--;
        max_heapify(1,i-1);
    }
}

/***********************************
/*********** Quick Sort
/*********************************/
int partition(int p,int r)
{
    int i=p-1;
    int pivot = arr[r];
   
    for(int j=p;j<=r;j++)
    {
        if(arr[j]<pivot)
        {
            i++;
           
            int temp =arr[i];
            arr[i]=arr[j];
            arr[j]=temp;
        }
    }
   
    arr[r]=arr[i+1];
    arr[i+1]=pivot;
   
    return i+1;
}

void quicksort(int p,int r)
{
    if(p<r)
    {
        int q = partition(p,r);
        quicksort(p,q-1);
        quicksort(q+1,r);
    }   
}


int main(int argc,char* argv[])
{
    
int size = MAXSIZE;
    
    
for(int i=0;i<size;i++)
    {
        arr[i] 
= rand()%MAXSIZE;
    }
    
    print();

    DWORD start 
= timeGetTime();
    
    
//mergesort(arr,0,MAXSIZE-1);
    
//heapsort();
    quicksort(0,MAXSIZE-1);
    
    DWORD end 
= timeGetTime();
    
    print();
    
    cout
<<end-start<<endl;
    
    system(
"pause");

    
return 0;
}


posted @ 2007-08-22 22:33 Kingoal Lee's Alogrithm Study using cplusplus 阅读(178) | 评论 (0)编辑 收藏

排序算法总结(4)--堆排序

堆排序(heap sort)应用的是堆数据结构来实现的排队算法
主要是由3部分组成:
max_heapify主要是来维持max heap的数据结构,其算法复杂度为O(lgn)【应用master定理的第二条来得到】
build_max_heap,从整个堆数列长度length的1/2开始到1,进行调用max_heapify函数得到,其算法复杂度为O(n)
heap_sort首先是调用build_max_heap,来构造一大堆,然后再将arr[1]和堆最大长度进行更换,将堆长度减一,再调用max_heapify来完成了排序功能,算法复杂度为O(nlogn)
主要代码实现为:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>
#include 
<cstdlib>
#include 
<time.h>
#include 
<windows.h>

#define MAXSIZE    
100
int arr[MAXSIZE];

using namespace std;

void print(bool flag=true)
{
    
if(flag)
    {
        copy(arr,arr
+MAXSIZE,ostream_iterator<int>(cout," "));
        cout
<<endl;
    }
}

void merge(int A[],int p,int q,int r)
{
    
int left = q-p+1;
    
int right = r-q;
    
    
int* L=new int[left];
    
int* R = new int[right];
    
    
int i,j,k;
    
for(i=0;i<left;i++)
        L[i]
=A[p+i];
    
for(j=0;j<right;j++)
        R[j]
=A[q+j+1];
        
    
for(k=0,i=0,j=0;(i<left)&&(j<right);k++)
    {
        
if(L[i]<=R[j])
            {
                A[p
+k]=L[i];
                i
++;
            }
        
else
        {
            A[p
+k]=R[j];
            j
++;
        }
    }
    
    
if(i<left)
    {
        
for(;i<left;i++,k++)
            A[p
+k]=L[i];
    }
    
if(j<right)
    {
        
for(;j<right;j++,k++)
            A[p
+k]=R[j];
    }
    
    delete [] L;
    delete [] R;
}

void mergesort(int A[],int p, int r)
{
    
if(p<r)
    {
        
int q = (p+r)/2;
        mergesort(A,p,q);
        mergesort(A,q
+1,r);
        merge(A,p,q,r);
    }
}

/*********************************
/**** Heap Sort Functions
/********************************/
void max_heapify(int i,int size)//size stands for heap size
{
    int left = i<<1;
    int right = left+1;
   
    //get the largest of the i/left/right
    int largest;
   
    if((left<=size)&&(arr[left]>arr[i]))
    {
        largest = left;
    }
    else
        largest = i;
       
    if((right<=size)&&(arr[right]>arr[largest]))
        largest = right;
       
    //exchange the value of i and largest
    if(i!=largest)
    {
        int temp =arr[i];
        arr[i]=arr[largest];
        arr[largest]=temp;
       
        max_heapify(largest,size);
    }
}

void build_max_heap()
{
    int size = sizeof(arr)/sizeof(arr[0])-1;
    for(int i=size/2;i>0;i--)
        max_heapify(i,size);
}

void heapsort()
{
    build_max_heap();
   
    int size = sizeof(arr)/sizeof(arr[0])-1;
    int heapsize = size;
   
    for(int i=size;i>1;i--)
    {
        int temp = arr[1];
        arr[1]=arr[i];
        arr[i]=temp;
       
        heapsize--;
        max_heapify(1,heapsize);
    }
}


int main(int argc,char* argv[])
{
    
int size = MAXSIZE;
    
    
for(int i=0;i<size;i++)
    {
        arr[i] 
= rand()%MAXSIZE;
    }
    
    print();

    DWORD start 
= timeGetTime();
    
    
//mergesort(arr,0,MAXSIZE-1);
    heapsort();
    
    DWORD end 
= timeGetTime();
    
    print();
    
    cout
<<end-start<<endl;
    
    system(
"pause");

    
return 0;
}


posted @ 2007-08-22 21:35 Kingoal Lee's Alogrithm Study using cplusplus 阅读(200) | 评论 (0)编辑 收藏

排序算法总结(3)--归并排序

归并排序(Merge Sort),是非常好的一种排序方式。时间复杂度为O(nlogn)。空间复杂度为O(n)
同快速排序相比,其有稳定性以及最差情况下为O(nlogn)等特点。

归并排序是典型的分而治之方法,首先将排序任务分成自任务,即Divide过程,然后将各个子任务初步完成(Conquer),最后将所有的子任务合并(merge)就完成了整个任务。
整个算法框架如下:
void mergesort(int A[],int p,int r)
{
      if(p<r)
    {
           int q=(p+r)/2;
          mergesort(A,p,q);
          mergesort(A,q+1,r);
          merge(A,p,q,r);
    }
}
在merge中,首先将p->q的(q-p+1)个放到一个左边的数组L中,将q+1->r的(r-q)个放到右边的数组R中,然后将数组L和数组R的数按顺序放置到A中。
void merge(A,p,q,r)
{
       //construct the L and R array
         int left=q+1-p;
         int right = r-q;

         int* L=new int[left];
        int* R = new int[right];

//fill the L and R array
         int i,j,k;
    for(i=0;i<left;i++)
        L[i]=A[p+i];
    for(j=0;j<right;j++)
        R[j]=A[q+j+1];
       
//copy the value from L and R to A
//Notice there are three cases
    for(k=0,i=0,j=0;(i<left)&&(j<right);k++)
    {
        if(L[i]<=R[j])
            {
                A[p+k]=L[i];
                i++;
            }
        else
        {
            A[p+k]=R[j];
            j++;
        }
    }
   
    if(i<left)
    {
        for(;i<left;i++,k++)
            A[p+k]=L[i];
    }
    if(j<right)
    {
        for(;j<right;j++,k++)
            A[p+k]=R[j];
    }
   
//delete the L and R
    delete [] L;
    delete [] R;
      
}
整个mergesort的可执行代码如下:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>
#include 
<cstdlib>
#include 
<time.h>
#include 
<windows.h>

#define MAXSIZE    
100
int arr[MAXSIZE];

using namespace std;

void print(bool flag=true)
{
    
if(flag)
    {
        copy(arr,arr
+MAXSIZE,ostream_iterator<int>(cout," "));
        cout
<<endl;
    }
}

void merge(int A[],int p,int q,int r)
{
    
int left = q-p+1;
    
int right = r-q;
    
    
int* L=new int[left];
    
int* R = new int[right];
    
    
int i,j,k;
    
for(i=0;i<left;i++)
        L[i]
=A[p+i];
    
for(j=0;j<right;j++)
        R[j]
=A[q+j+1];
        
    
for(k=0,i=0,j=0;(i<left)&&(j<right);k++)
    {
        
if(L[i]<=R[j])
            {
                A[p
+k]=L[i];
                i
++;
            }
        
else
        {
            A[p
+k]=R[j];
            j
++;
        }
    }
    
    
if(i<left)
    {
        
for(;i<left;i++,k++)
            A[p
+k]=L[i];
    }
    
if(j<right)
    {
        
for(;j<right;j++,k++)
            A[p
+k]=R[j];
    }
    
    delete [] L;
    delete [] R;
}

void mergesort(int A[],int p, int r)
{
    
if(p<r)
    {
        
int q = (p+r)/2;
        mergesort(A,p,q);
        mergesort(A,q
+1,r);
        merge(A,p,q,r);
    }
}

int main(int argc,char* argv[])
{
    
int size = MAXSIZE;
    
    
for(int i=0;i<size;i++)
    {
        arr[i] 
= rand()%MAXSIZE;
    }
    
    print();

    DWORD start 
= timeGetTime();
    
    mergesort(arr,
0,MAXSIZE-1);
    
    DWORD end 
= timeGetTime();
    
    print();
    
    cout
<<end-start<<endl;
    
    system(
"pause");

    
return 0;
}


posted @ 2007-08-22 16:13 Kingoal Lee's Alogrithm Study using cplusplus 阅读(247) | 评论 (0)编辑 收藏

排序算法总结(2)--选择排序和冒泡排序

前面给出了插入排序,其基于插入牌的机制
下面给出选择排序和冒泡排序的原理和实现

选择排序:
就是从后面的部分选择最小值(或者最大值)来代替前者,核心算法为:
for(int i=0;i<size;i++)
{
     //assume the smallest value is at size-1
      int temp = arr[size-1];
      int index = size-1;
 
      //compare the rest(from i--->size-1)
     for(j=i;j<size-1;j++)
     {
           if(arr[j]<temp)
          {
                temp = arr[j];
                index = j;
          }
     }

    //exchange the value
     if(index!=i)
    {
       arr[index]=arr[i];
       arr[i]=temp;
    }
}

具体代码实现为:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>

using namespace std;

int main(int argc,char* argv[])
{
    
int arr[]={5,6,1,2,7,3,8,10,4,9};
    
int size = sizeof(arr)/sizeof(arr[0]);
    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;

    
for(int i=0;i<size;i++)
    {
        
int temp = arr[size-1];
        
int index = size-1;
        
        
for(int j=i;j<size-1;j++)
        {
            
if(arr[j]<temp)
            {
                temp 
= arr[j];
                index 
= j;
            }
        }
        
        
if(i!=index)
        {
            arr[index]
=arr[i];
            arr[i]
=temp;
        }
    }
    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;
    
    system(
"pause");

    
return 0;
}

冒泡算法主要是从后面开始往上面进行冒泡,需要冒泡的话,必须要相邻的元素之间进行比较,其实现代码如下:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>

using namespace std;

int main(int argc,char* argv[])
{
    
int arr[]={5,6,1,2,7,3,8,10,4,9};
    
int size = sizeof(arr)/sizeof(arr[0]);
    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;

   
for(int i=0;i<size;i++)
    for(int j=size-1;j>i;j--)
    {
        if(arr[j]<arr[j-1])
        {
            int temp = arr[j];
            arr[j]=arr[j-1];
            arr[j-1]=temp;
        }
    }

    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;
    
    system(
"pause");

    
return 0;
}

posted @ 2007-08-22 10:38 Kingoal Lee's Alogrithm Study using cplusplus 阅读(259) | 评论 (0)编辑 收藏

排序算法总结(1)---概述

常见的排序方式有6种:
---简单排序里面的有:插入排序、选择排序、冒泡排序,时间复杂度为O(n^2)
---线性对数阶的排序: 归并排序(merge sort),快速排序,堆排序,时间复杂度为O(nlogn)

在n<=50的情况下,最好使用插入排序或者选择排序,由于选择排序移动次数比插入排序少,在数据量比较多的情况,推荐使用选择排序。
如果序列基本上正序了,则使用插入排序、冒泡排序或者随机的快速排序
在n非常大的情况下,使用O(nlogn)的算法,即归并排序、快速排序、堆排序。后2者是不稳定的排序,而merge排序是稳定的排序方式,快速排序是基于比较的排序中的最好的排序方法。

实验条件下算法运行时间:(单位毫秒,10万随机数)
冒泡排序:    56953
选择排序:    20109
插入排序:    14547
归并排序:    134
堆排序:        67
快速排序:    28

三种O(nlogn)的排序时间比较为:
排序算法        10万   100万     1000万
归并排序       134       1309     13985
堆排序           67         865        14292
快速排序       28         513        9815

下面给出insertion sort的原理和实现
insertion sort是稳定排序,在数据量非常小的情况下,非常快速。其原理就如同打牌的时候按顺序插入牌一样(来自introdution to algorithm),从后面往前面找大于最新的牌的数,然后往后面替换,再将最新的牌插入进去完成了前面的牌是已经排序好的。核心算法如下:
for(int i=1;i<size;i++)
{
     //get the new card
    int temp = arr[i];
    int j=i-1;

    while((j>=0)&&(arr[j]>temp))//find the old card bigger than the new card
    {
        arr[j+1]=arr[j];
        j--;
    }

    //get the position of the new card
    arr[j+1]=temp;
}

具体实现为:
#include <iostream>
#include 
<algorithm>
#include 
<iterator>

using namespace std;

int main(int argc,char* argv[])
{
    
int arr[]={5,6,1,2,7,3,8,10,4,9};
    
int size = sizeof(arr)/sizeof(arr[0]);
    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;

    
for(int i=1;i<size;i++)
    {
        
int temp = arr[i];
        
int j=i-1;
        
        
while((arr[j]>temp)&&(j>=0))
        {
            arr[j
+1]=arr[j];
            j
--;
        }
        
        arr[j
+1]=temp;
    }
    
    copy(arr,arr
+size,ostream_iterator<int>(cout," "));
    cout
<<endl;
    
    system(
"pause");

    
return 0;
}



posted @ 2007-08-22 10:22 Kingoal Lee's Alogrithm Study using cplusplus 阅读(294) | 评论 (0)编辑 收藏

求素数的方法

过去一直用的求素数的方法为:
bool isPrime(const int n)
{
     
for(int i=2;i<=sqrt(n);i++)
       
if((n%i)==0)
          
return false;
 
          
return true;
}
但是用这种方法求从2-->n的素数的话,时间复杂度高。
今天发现一种新的方法,效率提高了很多,其核心思想如下:
bool* prime = new bool[n];

for(int i=0;i<n;i++)
prime[i]
=true;

for(int i=2;i<=sqrt(n);i++)
{
      
if(prime[i])
       {
          
for(int j=i*i;j<=n;j++)
               prime[j]
=false;
        }
}
整个测试代码如下:
#include <iostream>
#include 
<string>
#include 
<cmath>
#include 
<ctime>
#include 
<windows.h>

using namespace std;

bool
* sieve(int n)
{
    bool
* prime = new bool[n];
    
    
for(int i=0;i<n;i++)
        prime[i]
=true;
    
    prime[
0]=false;
    prime[
1]=false;
    
    
double maxsqrt=sqrt((double)n);
    
    
for(int i=2;i<=maxsqrt;i++)
    {
        
if(prime[i])
        {
            
for(int j=i*i;j<=n;j+=i)
                prime[j]
=false;
        }
    }
    
    
return prime;
}

int main(int argc,char* argv[])
{
    
int n;
    
while(1)
    {
        cin
>>n;
        
if(n==0)
            
break;
    
        DWORD start 
= timeGetTime();
        
        
        
for(int i=3;i<=n;i++)
        {
            bool flag 
= true;
            
for(int j=2;j<=sqrt(i);j++)
            {
                
if(!(i%j))
                    {
                        flag 
= false;
                        
break;
                    }
            }
            
/*
            if(flag)
                cout<<i<<" ";
                
*/
        }
        
        DWORD median 
= timeGetTime();
        
        bool
* prime = sieve(n);
        
/*
        for(int i=0;i<n;i++)
            if(prime[i])
                cout<<i<<" ";
                
*/
                
        DWORD end 
= timeGetTime();
        
        cout
<<endl;
        cout
<<(median-start)<<" ms "<<(end-median)<<" ms"<<endl;
        
        delete prime;
    }
    
    system(
"pause");
    
return 0;
}



posted @ 2007-08-21 19:10 Kingoal Lee's Alogrithm Study using cplusplus 阅读(787) | 评论 (0)编辑 收藏

字符串匹配算法(3)---String Matching Algorithm

由于有限自动机方法与KMP算法类似,并且有限自动机方法在预处理上的时间复杂度比KMP方法高,所以在本文的讨论中,暂时不讨论有限自动机方法,主要是考虑KMP算法。
KMP算法是一个非常有名的字符串匹配算法,其由Knuth,Morris和Pratt一起提出来的,预处理时间为O(m),其中m为匹配字符串的长度,匹配时间为O(n),其中n为需要匹配的字符串的长度。
核心算法如下:
//预处理部分
int pi[m];
pi[0]=0;
int k = 0;

for(int i=1;i<m;i++)
{
   while((k>0)&&(p[i]!=p[k])
       k=pi[k];

   if(p[i]==p[k])
       k++;

   pi[i]=k;
}

//匹配部分
int k=0;
for(int i=0;i<n;i++)
{
    while((k>0)&&(p[k]!=t[i]))
           k=pi[k];
 
     if(p[k]==t[i])
          k++;

      if(k==m)
       {
            //输出结果,从(i+1-m)开始已经匹配
            k=pi[m-1];//开始下一个匹配
       }
}

具体的可运行的实现代码为:
 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 int main(int argc,char* argv[])
 7 {
 8     char *t=NULL,*p=NULL;
 9     int *pi=NULL;
10     string text,pattern;
11 
12     while(1)
13     {
14         cin>>text>>pattern;
15         int n = text.length();        
16         int m = pattern.length();
17 
18         //t= new char[n+1];
19         //p= new char[m+1];
20         t= new char[n];
21         p= new char[m];
22         pi = new int[m];
23 
24         //strcpy(t,text.c_str());
25         //strcpy(p,pattern.c_str());
26         memcpy(t,text.data(),n);
27         memcpy(p,pattern.data(),m);
28 
29         //calculate the PI array
30         int q = 0;
31         pi[0]=0;
32 
33         for(int i=1;i<m;i++)
34         {
35             while((q>0)&&(p[q]!=p[i]))
36             {
37                 q=pi[q];
38             }
39 
40             if(p[q]==p[i])
41                 q++;
42 
43             pi[i]=q;
44         }
45 
46         //use the KMP matching algorithm
47         q = 0;
48         for(int i=0;i<n;i++)
49         {
50             while((q>0)&&(p[q]!=t[i]))
51             {
52                 q = pi[q];
53             }
54 
55             if(p[q]==t[i])
56                 q++;
57 
58             if(q==m)
59             {
60                 cout<<((i+1)-m)<<endl;
61                 q = pi[m-1];
62             }
63         }
64 
65         delete[] t;
66         delete[] p;
67         delete[] pi;
68     }
69 
70     system("pause");
71     return 0;
72 }
73 


posted @ 2007-08-21 14:37 Kingoal Lee's Alogrithm Study using cplusplus 阅读(1866) | 评论 (2)编辑 收藏

字符串匹配算法(2)---String Matching Algorithm

前面已经说到了naive的方法来匹配字符串,但是该方法的特点是复杂度高,未能充分利用计算得到的值作为下一步计算的结果,因此,复杂度相当比较高。
Rabin-Karp提出了新的字符串匹配方法:
Rabin-Karp方法主要是分2部分:
(1)预处理(pre-processing)
对pattern字符串的m个进行计算,得到其hash值。 复杂度为O(m)
(2)匹配(matching)
for(int i=0;i<n-m;i++)
{
    计算t[i..i+m]的hash值。
    再同pattern字符串的hash值进行对比,如果相同,则使用naive办法,继续一个字符一个字符地比较。
    使用Horner法则计算下一个m字符的hash值。(即h(s+1)=f(h(s))).
}
整个算法的复杂度:
在最差的情况下,复杂度为O(m)+O(m*(n-m+1))
期望的情况为O(n-m+1+cm)=O(n+m).

实验代码如下:(暂时只是考虑支持12345678901234567890 匹配 234等的情况)
 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 #define Q    997 //Should be a prime
 7 #define D    10    //|sizeof character set|
 8 
 9 inline int geth(int m)//h=d^(m-1)%q
10 {
11     int len=1;
12     for(int i=0;i<(m-1);i++)
13     {
14         len*=D;
15     }
16     return len%Q;
17 }
18 
19 int main(int argc,char* argv[])
20 {
21     char *t=NULL,*p=NULL;
22     string text,pattern;
23     int h,p0=0,t0=0;
24 
25     while(1)
26     {
27         int index = 0;
28 
29         cin>>text>>pattern;
30         int n = text.length();        
31         int m = pattern.length();
32 
33         //t= new char[n+1];
34         //p= new char[m+1];
35         t= new char[n];
36         p= new char[m];
37 
38         h = geth(m);
39         p0=t0=0;
40 
41         //strcpy(t,text.c_str());
42         //strcpy(p,pattern.c_str());
43         memcpy(t,text.data(),n);
44         memcpy(p,pattern.data(),m);
45 
46         for(int i=0;i<m;i++)//get the initial value from pattern and text
47         {
48             p0 =(D*p0+(p[i]-'0'))%Q;
49             t0 = (D*t0+(t[i]-'0'))%Q;
50         }
51 
52         for(int i=0;i<(n-m);i++)
53         {
54             if(p0==t0)//should call the naive algorithm to check whether the two string is the same
55             {
56                 bool match = true;
57                 for(int j=0;j<m;j++)
58                 {
59                     if(p[j]!=t[i+j])
60                         match = false;
61                 }
62 
63                 if(match)
64                     cout<<i<<endl;
65             }
66 
67             t0 = ((D*(t0-(t[i]-'0')*h)+t[i+m])-'0')%Q;
68         }
69 
70         delete[] t;
71         delete[] p;
72     }
73 
74     system("pause");
75     return 0;
76 }
77 


posted @ 2007-08-20 21:11 Kingoal Lee's Alogrithm Study using cplusplus 阅读(459) | 评论 (0)编辑 收藏

字符串匹配算法(1)---String Matching Algorithm

作者: kingoal

给定一个输入的字符串t(text),长度为n(n=strlen(t)),给出匹配模式p(pattern),长度为m(m=strlen(p)).
在Introduction to algorithm书(CLRS)中,字符串算法主要是讨论了4种,分别对应的是:

朴素(Naive) ----------O(m*(n-m+1))
Rabin-Karp-----------O(m*(n-m+1))
有限自动机-----------O(n)
Knuth-Morris-Pratt------------------O(n)

下面分4部分具体介绍该4种字符串匹配算法。
Naive算法非常简单,就是将t的字节从0到n-m+1来一一匹配p的m个字符,若所有的m字符都匹配成功,则输出匹配成功,输出当前的index值。

下面给出Naive的实现代码:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 int main(int argc,char* argv[])
 7 {
 8     char *t=NULL,*p=NULL;
 9     string text,pattern;
10 
11     while(1)
12     {
13         int index = 0;
14 
15         cin>>text>>pattern;
16         int n = text.length();        
17         int m = pattern.length();
18 
19         //t= new char[n+1];
20         //p= new char[m+1];
21         t= new char[n];
22         p= new char[m];
23 
24         //strcpy(t,text.c_str());
25         //strcpy(p,pattern.c_str());
26         memcpy(t,text.data(),n);
27         memcpy(p,pattern.data(),m);
28 
29         for(int i=0;i<n-m+1;i++)
30         {
31             bool match=true;
32 
33             for(int j=0;j<m;j++)
34             {
35                 if(t[i+j]!=p[j])
36                     match=false;    
37             }
38             if(match)
39                 cout<<index<<endl;
40 
41             index++;
42         }
43 
44         delete[] t;
45         delete[] p;
46     }
47 
48     system("pause");
49     return 0;
50 }
51 

posted @ 2007-08-20 17:22 Kingoal Lee's Alogrithm Study using cplusplus 阅读(324) | 评论 (0)编辑 收藏

仅列出标题
共2页: 1 2 

My Links

Blog Stats

常用链接

留言簿(1)

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜