編程題--正則表達式

題目描述

請實現一個函數用來匹配包括'.'和'*'的正則表達式。模式中的字符'.'表示任意一個字符,而'*'表示它前面的字符可以出現任意次(包含0次)。 在本題中,匹配是指字符串的所有字符匹配整個模式。例如,字符串"aaa"與模式"a.a"和"ab*ac*a"匹配,但是與"aa.a"和"ab*a"均不匹配。

分析:

首先,考慮特殊請況

  1. 兩個字符串都爲空,返回true.
  2. 當第一個字符串不空,而第二個字符串空了,返回false(因爲這樣,就無法匹配成功了,而如果第一個字符串空了,第二個字符串非空,還可能匹配成功的。Eg: a*a*a*a*)

正常情況:每次分別在str和pattern中取一個字符進行比較,如果匹配,則匹配下一個字符,否則,返回不匹配。

分析:遞歸實現

   設匹配遞歸函數 match(str, pattern)。

1.  如果模式匹配字符的下一個字符是‘*’:

如果pttern當前字符和str的當前字符匹配,:有以下三種可能情況

  •     pttern當前字符能匹配 str 中的 0 個字符:match(str, pattern+2)
  •     pttern當前字符能匹配 str 中的 1 個字符:match(str+1, pattern+2)
  •     pttern當前字符能匹配 str 中的 多 個字符:match(str+1, pattern)

 如果pttern當前字符和和str的當前字符不匹配:

  •   pttern當前字符能匹配 str 中的 0 個字符:(str, pattern+2)

2.  如果模式匹配字符的下一個字符不是‘.’:

  對於 ‘.’ 的情況比較簡單,’.’ 和一個字符匹配 match(str+1, pattern+1)

3. 如果模式匹配字符的下一個字符是正常字符,且 *str == *pattern,

    遞歸下一個字符 :match(str+1, pattern+1)

 

實現

注:上邊這幾類情況,再代碼實現中,可以進行歸類合併,詳見下面的代碼:

//正則表達式的匹配
	//注:空字符串和“.*”是匹配的
	bool match(char* str, char* pattern)
    {
        //特殊情況處理
		//如果str和pattern都爲NULL, 返回true
        if(*str == '\0' && *pattern == '\0')
		{
			return true;
		}
		//str不爲NULL, pattern爲NULL,一定不匹配,返回false.
		//注:str爲NULL, pattern不爲NULL時,可能匹配。 eg: a*a*a*a*
		if(*str != '\0' && *pattern == '\0')
		{
			return false;
		}

		//遞歸進行處理(正常情況)
		if(*(pattern+1) == '*') //pattern可匹配0次,1次或多次
		{
			if(*pattern == *str || (*str != '\0' && *pattern == '.'))
			{
				return match(str,pattern+2) //*pattern == *str請況下,匹配0個
					|| match(str+1,pattern); //匹配多個
			}
			else //*pattern != *str請況下匹配0次,pattern+2
			{
				return match(str,pattern+2);
			}
		}

        //pattern下一個字符爲. 或正常字符即(*str == *pattern)
		if((*str != '\0' && *pattern == '.') || (*str == *pattern))
		{
			return match(str+1, pattern+1);
		}

		return false;
    }

總結

      在寫這道題時,首先理解什麼是正則表達式,對“*”和“.”的匹配模式進行理解,然後對各種情況進行分析,歸類。再具體寫代碼實現。

圖解

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章