2012第四届华为编程大赛(高级组)第三题

点击打开链接

下面是我写的一个程序,基本上能够完美的匹配,但是有一个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);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值