一个简单的模式字符串查找(支持通配符‘*’)

数据结构课的一些作业还是有些难度的,对于部分有价值或下了苦工的问题还是传上来好叻,回头写注释,纪念菜鸡生涯

【问题描述】
 
在当前目录下的文件string.in中查找给定的字符串,并将查找到的字符串和行号输出到当前目录下的文件string.out中。要求:
 
1)从键盘输入给定的字符串,该字符串中只包含大小写字母、数字字符、中括号字符‘[’和‘]’、‘*’,以及字符‘^’。字符串的长度不超过20。
 
2)字符‘^’只能出现在中括号内,且只能作为中括号内的第一个字符出现。除了字符‘^’,中括号中至少包含一个以上的字母或数字。
 
3)字符*不会出现在中括号内
 
4)在给定字符串中,中括号最多出现一次。若中括号内未出现字符‘^’,表示该位置上的字符只要与中括号内的任一字符相同,则匹配成功;若中括号内出现字符‘^’,表示该位置上的字符与中括号内的所有字符都不相同时,匹配成功。
 
5)字符*可以同零个字符或者多个任意字符相匹配
 
6)在给定的字符串中,*号最多仅出现一次
 
7)*号的作用范围局限于一行,不会跨越行进行匹配
 
8) 有多个字符串和*号匹配时,仅仅输出一个,并且输出这些串中长度最短的那个
 
9)查找字符串时大小写无关。
 
10)先输出查到的行号(行号从1开始),行号后跟冒号‘:’,然后是查找到的字符串,多个字符串之间用逗号‘,’隔开。各行之间用一个回车换行符隔开。
 
【输入形式】
 
首先从标准输入(键盘)读入待查找的字符串。待查找的文件string.in位于当前目录下。
 
【输出形式】
 
将查找到的结果输出到当前目录下的string.out中。
 
【样例输入1】
 
zh[ao]ng
假如string.in文件内容为:
Zhang ying ju zhu zai ZhongGuo. 
Ta zheng zai du gao zhong.
Bie ren dou jia ta xiao zhang.
 
【样例输出1】
 
string.out文件内容为:
1:Zhang,Zhong
2:zhong
3:zhang
 
【样例1说明】
 
给定字符串中有中括号,表示第三个字符可以是a也可以是o,且大小写无关,因此文章中第一行的Zhang和Zhong与给定字符串匹配,故输出1:Zhang,Zhong。其它类推。
 
【样例输入2】
 
a[^ab]a
string.in文件内容为:
Do you like banana?
ABA is the abbreviation of American Bankers Association.
 
【样例输出2】
 
string.out文件内容为:
1:ana,ana
 
【样例2说明】
 
给定字符串中括号内有字符‘^’,表示第一个和第三个字符都为a,第二个字符不能为a或b,因此文章中第一行的banana内有两个字符串ana与给定字符串匹配,故输出1:ana,ana。第二行中ABA的第二个字符为B,由于大小写无关,与给定字符串中括号内的b相同,故不能匹配。
 
【样例输入3】
 
w*d
string.in文件内容为:
wwwdd
world is a nice word
 
【样例输出3】
 
string.out文件内容为:
1:wwwd,wwd,wd
2:world,word
 
【样例3说明】
 

给定的字符串中有‘*’,表示在一行内,可以和以'w'开头,以'd'结尾的任意字符串相匹配。在一行中,对于第一个字符'w',同时有字符串"wwwd"以及"wwwdd"与之相匹配,根据上述第8条规则,应该匹配"wwwd"。一次类推得到'wwd'和'wd'。同样的规则用于第二行,得到"world"和"word"


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char tolower(char s)
{
	if (s >= 'A'&&s <= 'Z')
		s += 'a' - 'A';
	return s;
}

// This function judges whether from a given position(pos_scans), in the string(scans[]),
// the following letters can match the pattern given in the regular expression(regex[]).
// If so, the string matching the pattern is to be stored in the string(prints[]), and return 1
int regex_match(char scans[], int pos_scans, char regex[], char prints[]) 
{
	int iter_regex = 0; // iter_regex records the position of scanner in regex[]
	int iter_scans = 0; // iter_scans records the position of scanner in scans[]
	int len_regex = strlen(regex); 
	char dic[81];       // dic[] stores the pattern in a wildcard box "[]"
	int i, j;

	while (iter_regex < len_regex)
	{ 
		if (regex[iter_regex] != '[' && regex[iter_regex] != '*') 
		{// the scanner in regex[] gets a letter (']' is not included. this is guaranteed in '[' case)
			if (tolower(regex[iter_regex]) == tolower(scans[pos_scans + iter_scans])) 
			{// simply check whether the same letter appears in scans[]
				iter_regex++;
				iter_scans++;
			}
			else break;
		}
		else if (regex[iter_regex] == '[')
		{// the scanner starts a wildcard box "[]"
			i = 0;
			iter_regex++;
			while (regex[iter_regex] != ']')
			{// store the pattern in this box into dic[]	
				dic[i++] = regex[iter_regex];	
				iter_regex++;
			}
			dic[i] = '\0';
			if (dic[0] == '^')
			{// if '^' is there in the box, the criteria is opposite
				for (j = 1; j < i; j++)
				{// the letter scanned in scans[] cannot appear in the box
					if (tolower(scans[pos_scans + iter_scans]) == tolower(dic[j]))
						break;
				}
				if (j == i)
				{// "j" reaches "i", meaning a success
					iter_scans++;
					iter_regex++;
				}
				else break; 
			}
			else
			{// no '^' is there in the box
				int flag = 0;
				for (j = 0; j < i; j++)
				{
					if (tolower(scans[pos_scans + iter_scans]) == tolower(dic[j]))
					{// it is a match only if the letter scanned in scans[] appears in the box
						flag = 1;
						break;
					}
				}
				if (flag)
				{
					iter_regex++;
					iter_scans++;
				}
				else break;
			}
		}
		else if (regex[iter_regex] == '*')
		{// '*' means any letter (or letters) can match
			if (iter_regex == len_regex - 1)
			{// if the scanner has already reached the end of regex[]
				iter_regex++;
				while (scans[pos_scans + iter_scans] != '\0') iter_scans++; // all the remaining letters in scans[] can match 
				break;
			}
			else if (regex[iter_regex + 1] != '[')
			{// if the scanner gets a letter following '*'
				while (tolower(scans[pos_scans + iter_scans]) != tolower(regex[iter_regex + 1]))
				{// scanner in scans[] can go forward until it gets the same letter as scanned in regex[]
					iter_scans++;
					if (scans[pos_scans + iter_scans] == '\0') break;
				}
				if (tolower(scans[pos_scans + iter_scans]) == tolower(regex[iter_regex + 1]))
				{// if the scanner in scans[] meets the same letter as scanned in regex[], the match is a success
					iter_scans++;
					iter_regex+=2;
				}
				else break;// otherwise the scanner goes to the end of scans[], meaning the match is a failure
			}
			else if (regex[iter_regex + 1] == '[')
			{// it the scanner finds a '[' following '*'
				i = 0;
				iter_regex++;
				while (regex[iter_regex] != ']')
				{// store the pattern into dic[]
					dic[i++] = regex[iter_regex];
					iter_regex++;
				}
				dic[i] = '\0';
				while (scans[pos_scans + iter_scans] != '\0')
				{// check the scanner has not reached the end of scans[]
					if (dic[0] == '^')
					{// if '^' starts this "[]" box
						for (j = 1; j < i; j++)
						{// if the letter scanned in scans[] does not appear in the box
						 // it means a success of matching "*[]"
							if (tolower(scans[pos_scans + iter_scans]) == tolower(dic[j]))
							{// if the letter appears, we should scan the next letter in scans[]
								iter_scans++;
								break;
							}
						}
						if (j == i)
						{// the letter scanned in scans[] does not appear in the box
							iter_scans++;
							iter_regex++;
							break;
						}
					}
					else
					{
						int flag = 0;
						for (j = 0; j < i; j++)
						{
							if (tolower(scans[pos_scans + iter_scans]) == tolower(dic[j]))
							{// if the letter appears in the box, meaning the match is a success
								flag = 1;
								break;
							}
						}
						if (flag)
						{
							iter_regex++;
							iter_scans++;
							break;
						}
						else iter_scans++;// if not, we scan the next letter in scans[]
					}
				}
			}
		}
		if (scans[pos_scans + iter_scans] == '\0') break; // the scanning of scans[] ends
	}

	if (iter_regex == len_regex)
	{// if the scanning of regex is finished, it means the match of regex[] is a success
		for (j = 0; j < iter_scans; j++)
			prints[j] = scans[pos_scans + j];
		prints[j] = '\0';
		return 1;
	}
	else return 0;
}

int main()
{
	FILE *fin, *fout;
	char regex[21];
	char scans[81];
	char prints[161];
	int line = 0;
	int i;

	if ((fin = fopen("string.in", "r")) == NULL)
		exit(1);
	if ((fout = fopen("string.out", "w")) == NULL)
		exit(1);
	scanf("%s",regex);
	while (fgets(scans, 81, fin) != NULL)
	{
		line++;
		int flag = 1;
		for (i = 0; scans[i] != '\0'; i++)
		{
			if (regex_match(scans, i, regex, prints))
			{
				if(flag) fprintf(fout, "%d:", line);
				else fprintf(fout, ",");
				fprintf(fout, "%s", prints);
				flag = 0;
			}
		}
		if (!flag) fprintf(fout,"\n");
	}

	fclose(fin);
	fclose(fout);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值