下面是我写的一个程序,基本上能够完美的匹配,但是有一个bug,只能完成第一次匹配,以后还有待改进!下面是源码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
char *do_process(char ruler[],char process_tm[])//对输入的字符串进行预先处理,以求得到简化
{
char *pointer1,*pointer2;
int k=0;
pointer1=ruler;
while(*pointer1!='\0')
{
pointer2=pointer1+1;
if(*pointer1=='?'||*pointer1=='*')
{
while(*pointer2=='?'||*pointer2=='*')
++pointer2; //此时的pointer2指向'?'或者'*'的后一个位置
if(*ruler=='?'&&pointer1==ruler)//有问题
{
while(*pointer1!='\0'&&*pointer1=='?'&&pointer1!=pointer2)
process_tm[k++]=*pointer1++;
if(*--pointer2=='*')
{
k=0;
process_tm[k++]=*pointer1++;
}
else
{
process_tm[k++]=*pointer1++;
}
}
else
{
process_tm[k++]='*';
pointer1=pointer2;
process_tm[k++]=*pointer1;
++pointer1;
}
}
else
process_tm[k++]=*pointer1++;
}
process_tm[k++]='\0';
return process_tm;
}
int myfind (char input[],char ruler[],char output[])
{
int flag=0,len=0,len_ques;
char *pter1,*pter2,*pter1_tm,*next;
char *pter1_cp,*pter1_cpt,*pter2_cp;
char i_value;
char out_tm[MAX],process_tm[MAX];
int i,k=0;
//下面是对字符数组ruler做预处理工作
ruler=do_process(ruler,process_tm);
pter1=input;
pter1_tm=pter1_cp=input;
pter2=ruler;
i_value=*pter2;
if (!(input&&ruler&&output))
return 0;
while(*pter1_cp++!='\0')
++len; //求得输入字符串的长度
--pter1_cp; //让pter_cp指向字符串的末尾‘\0’
while(*pter1!='\0'&&*pter2!='\0') //pter1是指向input的指针,而pter2是指向ruler的指针
{
if(*pter2=='?')
{
//将匹配的元素拷贝到out_tm中
pter2++;
while(*pter2!='\0'&&*pter2=='?')
pter2++;
len_ques=pter2-ruler;//一共有几个问号,在开始的时候
i_value=*pter2;
while(*pter1_tm++!=i_value);
pter1_tm-=1; //使pter1_tm指向i_value的位置。
pter1_tm-=len_ques; //调整指针的位置使其指向相对于‘???’的开始端
while(*pter1_tm!=i_value)
out_tm[k++]=*pter1_tm++;
pter1=pter1_tm;
out_tm[k++]=*pter1++;
++pter2;
break;
}
if(*pter2=='*')
{
i_value=*++pter2;
while(*pter1_tm!=i_value)
out_tm[k++]=*pter1_tm++;//将匹配的元素拷贝到out_tm中
pter1=pter1_tm;
out_tm[k++]=*pter1++;
++pter2;
break;
}
if(*pter1==i_value) //此时找到的pter1和ruler第一个字符相匹配的位置。
{
out_tm[k++]=*pter1++;
++pter2;
break;
}
else
pter1++;
}
//pter1++; //第一个位置已经比较完毕,开始比较第二个
// pter2=(*ruler=='?'||*ruler=='*') ? ruler+2 : ruler+1 ; //根据第一个位置的情况来判断pter2的指针指向。
//找到第一个比配的位置后,然后依次向后匹配
while(*pter1!='\0'&&*pter2!='\0')
{
if(*pter2=='?')//当字符串中间存在‘?’时的处理程序
{
pter2_cp=pter2;//这个地方差点出错,这个部分处理‘?’在尾端时候的情况
++pter2_cp;
if(*pter2_cp=='\0')
{
out_tm[k++]=*pter1;
*pter2='\0'; //用于标示程序已结束
break;
}
out_tm[k++]=*pter1;
pter1++;
pter2++;
if(*pter1==*pter2)
{
out_tm[k++]=*pter1;
pter1++;
pter2++;
continue;
}
else
{
myfind(pter1,input,output);
return 0;
}
}
if(*pter2=='*')//当字符中间存在‘*’时的处理程序
{
pter1_cpt=pter1_cp; //让pter1_cp一直指向字符串的末端
next=++pter2;
if(*next=='\0')//当'*'为最后的情况
{
while(*pter1!='\0')
out_tm[k++]=*pter1++;
break;
}
while(*--pter1_cpt!=*next&&len>0) //将pter1_cp指向*next,这是从后向前寻找
--len;
if(len<=0)
return 0;
while(*pter1!='\0'&&pter1!=pter1_cpt)
{
out_tm[k++]=*pter1++;
}
if(*pter1=='\0')
return 0;
else
{
out_tm[k++]=*pter1;
pter1++;
pter2++;
continue;
}
}
if(*pter1==*pter2)//当处理的字符不是‘?’或者‘*’时的情况
{
out_tm[k++]=*pter1++;
pter2++;
}
else
{
myfind(pter1,input,output);
return 0;
}
}//while 循环从这里结束
if (*pter2=='\0')//根据标志来判断是否打印
flag=1;
if(flag==1)
{
for(i=0;i<k;i++)
output[i]=out_tm[i];
output[i]='\0';
}
else
output="ERROR! ";
return 0;
}
int main()
{
char input[]="abcdefghikl";
char ruler[]="???d*f?";
char output[MAX];
myfind(input,ruler,output);
// do_process(ruler,output);
printf("%s\n",output);
}