数据结构之字符串匹配和排序(一)
//字符串匹配+排序
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int bfstr(string a,string b){ //普通模式匹配算法bfstr,返回第一个找到的下标。
for(int i=0,j=0;i<a.size();){
if(a[i]==b[j]){
i++;
j++;
}else{
i=i-j+1;
j=0;
}
if(j>b.size()-1){
return i-b.size();
}
}
return -1;
}
void bubblesort(int *a,int n){ //冒泡排序(大数沉底版)。a传入数组因为需要修改,所以指针型,n表示数字个数
for(int i=0;i<n-1;++i){ //不超过n-1趟排序,因为每次能最终确定1个。
for(int j=0;j<n-i-1;++j){ //每次都把一个最大的数排到后面,那就没必要再比较后面已经排好序的了,i趟确定了i个数
if(a[j]>a[j+1]) swap(a[j],a[j+1]);
}
}
}
void quicksort(int *a,int l,int r){ //快排。传入数组,要排序的起始位置l,终止位置r。
if(l >= r) return; //左侧超出右侧返回空
int i = l - 1, j = r + 1, x = a[(l+r)/2]; //i和j先退出门外,一会往里进。x每次去数组正中间,方便处理,不像严版那样。
while(i < j){
while(a[++i] < x); //i和j从两头开始比较,往中间靠拢,直到走不动。
while(a[--j] > x);
if(i < j) swap(a[i], a[j]); //怕i和j无脑乱走,必须加个if判断,然后交换两个值。
}
quicksort(a,l,j); //对两边递归快排,j和j+1记住
quicksort(a,j+1,r);
}
void mergesort(int *a,int l,int r,int *temp){ //归并。传入原始数组a,起始位置l,终止位置r,传出数组temp。
if(l>=r) return ;
int mid=(l+r)/2; //从数组中间分隔,一前一后,然后类似有序链表合并一样开始比较,塞进新数组
mergesort(a,l,mid,temp); //先递归
mergesort(a,mid+1,r,temp);
int i=l,j=mid+1,k=0; //k是往temp的数组游标
while(i<=mid&&j<=r){
if(a[i]<=a[j]) temp[k++]=a[i++]; //谁小谁先入数组
else temp[k++]=a[j++];
}
while(i<=mid) temp[k++]=a[i++]; //当有一方结束,直接把另一方接入数组
while(j<=r) temp[k++]=a[j++];
for(i=l,j=0;i<=r;++i,++j) a[i]=temp[j]; //再把排序完的数组倒入原来的数组
}
void PrintA(int *a,int n){ //打印数组用。输入要打印的数组a和数组元素个数n
for(int i=0;i<n;++i){
cout<<a[i]<<" ";
}
puts("");
}
void CopyA(int *a,int *b,int n){ //生成数组副本用。输入目标数组a,接受数组b,数组元素个数n
for(int i=0;i<n;++i){
b[i]=a[i];
}
}
int main()
{
string s,t; //主串s,子串(模式串)t
cin>>s>>t;
cout<<bfstr(s,t)<<endl;
cout<<"n:"<<endl;
int n;
cin>>n;
int a[n],tmp[n],x[n],y[n];
for(int i=0;i<n;++i) cin>>a[i];
CopyA(a,x,n);
CopyA(a,y,n);
PrintA(a,n);
PrintA(x,n);
PrintA(y,n);
bubblesort(a,n);
cout<<"bub"<<" ";
PrintA(a,n);
quicksort(x,0,n-1);
cout<<"quic"<<" ";
PrintA(x,n);
mergesort(y,0,n-1,tmp);
cout<<"merg"<<" ";
PrintA(y,n);
return 0;
}