《剑指offer》:[53]正则表达式匹配

题目:请实现一个函数用来匹配包括’.’和’‘的正则表达式。模式中的字符’.’表示任意一个字符,而’‘表示它前面的字符可以出现任意次(包含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串”aaa”与模式”a.a”和”ab*ac*a”匹配,但是与”aa.a”和”ab*a”均不匹配。

分析;常规中,如果是普通的两个字符串,那很简单,我们直接进行对比就可以了,这里又是要求匹配是指字符串的所有字符匹配整个模式,所以只要直接挨个比较就可以了,如果都相等则返回true;否则返回false;可是这个题目来了一个‘.‘和‘*‘两个比较烦人的东西,它改变了游戏的规则。把游戏变的复杂多变。

首先要明确‘.‘确定了字符的个数为1,并且为任意;‘*‘可以确定它前面的字符的个数包括0次;

第一种情况:当模式的第二个字符不是‘*‘的时候,如果字符串的第一个字符和模式串的第一个字符相等,则都向后移动一个,匹配剩下的字符串和模式串。如果不等则直接返回false;

第二种情况:当模式的第二个字符是‘*‘的时候,这时候就稍复杂点儿,因为这时候存在不同的几种匹配方式:以字符串"aaa"与模式"ab*ac*a"匹配为例:

1、如果模式串中的字符和字符串中的字符不等如(a),且模式串的第二个字符为‘*‘。

选择只有一种:在模式串上向后移动两个字符,忽略掉b和*,因为‘*‘可以匹配0个字符;如下图:

2、如果模式串中的字符和字符串中的字符相等如(b),或者模式串中为‘.‘如(c),并且模式串的第二个字符为‘*‘。其实(b)和(c)是一样的。这时候选择有三种情况:

(1)可以选择在模式串上向后移动两个字符,忽略掉b和*,因为‘*‘可以匹配0个字符,字符串str保持不变;

(2)可以选择越过‘*‘,‘*‘前的a当作有效的字符,且数量为1,str++;

(3)可以选择模式串pattern不变,因为‘*’前的a可以任意数量的,并且和字符串str相等,只需要str++即可;

具体如下图所示:

具体实现代码如下:

#include <iostream>
using namespace std;
bool MatchCore(char *str,char *pattern)
{
	if(*str=='\0' && *pattern=='\0')
		return true;
	if(*str!='\0' && *pattern=='\0')
		return false;
	if(*(pattern+1)=='*')
	{
		if(*pattern==*str || (*pattern=='.' && *str!='\0'))//将‘*’号忽略,‘*’前的作为一个有效的值;
			return MatchCore(str+1,pattern+2)
			|| MatchCore(str+1,pattern) //‘*’号前可以出现任意个,所以pattern可以保持不变
			|| MatchCore(str,pattern+2);//忽略‘*’及‘*’号以前的字符;
		else
			return MatchCore(str,pattern+2);//因为‘*’ 号前的字符与*str不等,所以只能忽略*pattern字符一个选择;
	}
	if(*str==*pattern || (*pattern=='.' && *str!='\0'))
		return MatchCore(str+1,pattern+1);//正常的字符串比较;
	return false;
}
bool match(char *str,char *pattern)
{
	if(str==NULL || pattern==NULL)
		return false;
	return MatchCore(str,pattern);
}
int main()
{
	char str[]="aaa";
	char *pattern[4]={"a.a","ab*ac*a","aa.a","ab*a"};
	for(int i=0;i<4;i++)
	{
		if(match(str,pattern[i]))
			cout<<"The same!"<<endl;
		else
			cout<<"Not the same!"<<endl;
	}
	system("pause");
	return 0;
}

运行结果:

时间: 2024-10-13 21:19:40

《剑指offer》:[53]正则表达式匹配的相关文章

53 - 正则表达式匹配

题目: 请实现一个函数用来匹配包含'.'和'*'的正则表达式. 模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次). 本题中,匹配是指字符串的所有字符匹配整个模式. 例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但与"aa.a"及"ab*a"均不匹配. 解析: 字符串 str = "aaa"; 模式字符串 pattern = "

剑指offer——面试题19:正则表达式匹配

1 #include"iostream" 2 using namespace std; 3 4 bool MatchCore(char*str,char* pattern); 5 6 bool Match(char* str,char* pattern) 7 { 8 if(str==nullptr||pattern==nullptr) 9 return false; 10 return MatchCore(str,pattern); 11 } 12 13 bool MatchCore(

正则表达式匹配/data/misc/wifi/wpa_supplicant.conf的WiFi名称与密码

正则表达式匹配/data/misc/wifi/wpa_supplicant.conf的WiFi名称与密码: String regex_name="ssid=\"(.*?)\""; String regex_psk="psk=\"(.*?)\""; 核心代码: Pattern p_name=Pattern.compile(regex_name); Pattern p_psk=Pattern.compile(regex_psk);

PHP 正则表达式匹配 preg_match 与 preg_match_all 函数

--http://www.5idev.com/p-php_preg_match.shtml 正则表达式在 PHP 中的应用 在 PHP 应用中,正则表达式主要用于: 正则匹配:根据正则表达式匹配相应的内容 正则替换:根据正则表达式匹配内容并替换 正则分割:根据正则表达式分割字符串 在 PHP 中有两类正则表达式函数,一类是 Perl 兼容正则表达式函数,一类是 POSIX 扩展正则表达式函数.二者差别不大,而且推荐使用Perl 兼容正则表达式函数,因此下文都是以 Perl 兼容正则表达式函数为例

正则表达式匹配包括换行符的所有字符

今天在Java中想使用正则表达式来获取一段文本中的任意字符. (.*) 结果运行之后才发现,无法获得换行之后的文本.于是查了一下手册,才发现正则表达式中,"."(点符号)匹配的是除了换行符"\n"以外的所有字符. 查出了一个解决办法,经过一试,果然可以匹配包括换行符在内的任意字符,以下为正确的正则表达式匹配规则: ([\s\S]*)正则表达式匹配包括换行符的所有字符,布布扣,bubuko.com

使用正则表达式匹配IP地址

如何使用正则表达式匹配IP地址?这是很常见的任务.说难也难,说易也易,取决于在匹配的精确度以及正则表达式复杂度之间很好的折中. 通常,IP地址以点分十进制方式表示,IP地址分为4段,以点号分隔.要对IP地址进行匹配,首先要对其进行分析.0.0.0.0 - 255.255.255.255 一个简单的正则表达式: [0-9]+(?:\.[0-9]+){0,3} 或者 ^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$ 它能够完成我们的任务,但是像"3948.3.89.34238"

PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性。

PHP正则提取或替换img标记属性 PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <?php /*PHP正则提取图片img标记中的任意属性*/ $str = '<center><img src="/uploads/images/20100516000.jpg"

用正则表达式匹配汉字,完整总结

提到用正则表达式匹配汉字,很容易搜到这个[\u4e00-\u9fa5],但是它不算全面,不包含一些生僻汉字. 本文对此问题做一个梳理. 以下是比较全面的汉字Unicode分布,截止Unicode 8.0标准(2015年6月): 区块 范围 实际汉字个数 正则式 CJK统一汉字 4E00-62FF, 6300-77FF, 7800-8CFF, 8D00-9FFF. 20,950 [\u4E00-\u9FFF] CJK统一汉字扩展A区 3400-4DBF. 6,582 [\u3400-\u4DBF]

【PYTHON】对整个文件进行正则表达式匹配

1 #coding:utf-8 2 import re 3 def IDXtoSCS(path):#IDX转换为开思的函数 4 IDXfile=open(path,'r') 5 fileread=IDXfile.readlines() 6 IDXfile.close() 7 p='"(\w)*",\s+(\d+\\.\d+),\s+(\d+\\.\d+),\s+(\d+\\.\d+),\s+"(\w*)",' 8 data=re.findall(p,fileread