国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【動態(tài)規(guī)劃】【字符串】C++算法:正則表達式匹配

這篇具有很好參考價值的文章主要介紹了【動態(tài)規(guī)劃】【字符串】C++算法:正則表達式匹配。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

作者推薦

視頻算法專題

涉及知識點

動態(tài)規(guī)劃匯總
字符串

LeetCode10:正則表達式匹配

給你一個字符串 s 和一個字符規(guī)律 p,請你來實現(xiàn)一個支持 ‘.’ 和 ‘’ 的正則表達式匹配。
‘.’ 匹配任意單個字符
'
’ 匹配零個或多個前面的那一個元素
所謂匹配,是要涵蓋 整個 字符串 s的,而不是部分字符串。
示例 1:
輸入:s = “aa”, p = “a”
輸出:false
解釋:“a” 無法匹配 “aa” 整個字符串。
示例 2:
輸入:s = “aa”, p = “a*”
輸出:true
解釋:因為 ‘’ 代表可以匹配零個或多個前面的那一個元素, 在這里前面的元素就是 ‘a(chǎn)’。因此,字符串 “aa” 可被視為 ‘a(chǎn)’ 重復(fù)了一次。
示例 3:
輸入:s = “ab”, p = ".
"
輸出:true
解釋:"." 表示可匹配零個或多個('’)任意字符(‘.’)。
提示:
1 <= s.length <= 20
1 <= p.length <= 20
s 只包含從 a-z 的小寫字母。
p 只包含從 a-z 的小寫字母,以及字符 . 和 *。
保證每次出現(xiàn)字符 * 時,前面都匹配到有效的字符

動態(tài)規(guī)劃

時間復(fù)雜度??(nnm) n=s.length m = p.length

動態(tài)規(guī)劃的狀態(tài)表示 p[0,i)和s[0,j)能完全匹配,記錄所有(i,j)
動態(tài)規(guī)劃的狀態(tài)轉(zhuǎn)移方程 如果p[i+1]是*,則p[i,i+2)能否匹配s[j,x);否則p[i]能否匹配s[j]
動態(tài)規(guī)劃的的初始化 {0,0}
動態(tài)規(guī)劃的填表順序 從小到枚舉i
動態(tài)規(guī)劃的返回值 是否存在狀態(tài)(p.length,s.lenght)

滾動哈希集合

轉(zhuǎn)移狀態(tài)時:只需要讀取j1的相關(guān)狀態(tài),寫人j1+1的狀態(tài)。我們用兩個哈希來表示狀態(tài):pre表示j1 相關(guān)狀態(tài),dp 表示j2的相關(guān)狀態(tài),然后swap。

分類討論

.* [min(pre),s.length)
字母x* iPre, 如果s[iPre,pPre+y]都是x ,則[iPre+1,iPre+1+y]都是合法狀態(tài) iPre取自pre
字母x s[j]==x,則j+1也是合法狀態(tài)
. s[j]存在,j+1就是合法狀態(tài)

代碼

核心代碼

class Solution {
public:
	bool isMatch(string s, string p) {
		m_c = s.length();
		unordered_set<int> pre = { 0 };
		for (int i = 0 ; i < p.length(); i++ )
		{	
			const auto& ch = p[i];
			if ('*' == ch)
			{
				continue;
			}
			unordered_set<int> dp;
			if ((i + 1 < p.length()) && ('*' == p[i + 1]))
			{
				if ('.' == ch)
				{
					int iMin = INT_MAX;
					for (const auto& iPre : pre)
					{
						iMin = min(iMin, iPre);
					}
					for (; iMin <= m_c; iMin++)
					{
						dp.insert(iMin);
					}
				}
				else
				{
					dp = pre;
					for (const auto& iPre : pre)
					{
						int j = iPre;
						while (j < m_c)
						{
							if (s[j] == ch)
							{
								dp.insert(++j);
							}
							else
							{
								break;
							}
						}
					}
				}
			}
			else
			{
				for (const auto& iPre : pre)
				{
					if (iPre  < m_c)
					{
						if (('.' == ch) || (s[iPre] == ch))
						{
							dp.insert(iPre + 1);
						}
					}
				}
			}			
			pre.swap(dp);
		}
		return pre.count(m_c);
	}
	int m_c;
};

測試用例

template<class T>
void Assert(const T& t1, const T& t2)
{
	assert(t1 == t2);
}

template<class T>
void Assert(const vector<T>& v1, const vector<T>& v2)
{
	if (v1.size() != v2.size())
	{
		assert(false);
		return;
	}
	for (int i = 0; i < v1.size(); i++)
	{
		Assert(v1[i], v2[i]);
	}
}


int main()
{
	string s, p;

	{
		Solution sln;
		s = "aa", p = "a";
		auto res = sln.isMatch(s, p);
		Assert(false, res);
	}
	{
		Solution sln;
		s = "aa", p = "aa";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "a", p = "a*";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "aa", p = "a*";
		auto res = sln.isMatch(s, p);
			Assert(true, res);
	}
	{
		Solution sln;
		s = "aaa", p = "a*";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "ab", p = ".*";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "aab", p = "c*a*b";
		auto res = sln.isMatch(s, p);
		Assert(true, res);
	}
	{
		Solution sln;
		s = "aaaaaaaaaaaaab", p = "a*a*a*a*a*a*a*a*a*a*";
		auto res = sln.isMatch(s, p);
		Assert(false, res);
	}
}

動態(tài)規(guī)劃的優(yōu)化

時間復(fù)雜度??(nm)
優(yōu)化動態(tài)規(guī)劃的轉(zhuǎn)移方程,改成枚舉s。也要處理匹配多個的問題。比如:連續(xù)多個不匹配任何字符。
不用滾動哈希集合了。

動態(tài)規(guī)劃的狀態(tài)表示 p[0,i)和s[0,j)能完全匹配,dp[i][j]為true;否則為false
動態(tài)規(guī)劃的狀態(tài)轉(zhuǎn)移方程 比較復(fù)雜下文討論
動態(tài)規(guī)劃的的初始化 dp[0][0]=ture,其它false dp[x][0]也要計算
動態(tài)規(guī)劃的填表順序 從小到枚舉i
動態(tài)規(guī)劃的返回值 dp[p.length][s.length]

如果p[i-1]是星號,只需要考慮兩種情況:

  • 匹配0個字符,dp[i][j] = dp[i-2][j]。
  • 匹配n個字符,n>0。 dp[i][j] = dp[i][j-1]

注意
dp[0][x] x>0,無意義全部為false。
dp[x][0] x>0 如果p[0,x)全部是yyyy… ,則為true。 y表示.或字母,兩個y可能不相同。
y* 必須處理號,不能處理y,否則如果以號結(jié)束的時候,會出錯。

動態(tài)規(guī)劃的無后效性

計算dp[i][j]的時候,用到了i,i-1,i-2,j,j-1。 第一層循環(huán)從小到大枚舉i,第二層循環(huán)從小到大枚舉j。i小的先處理,i相等的,j小的先處理。

代碼

class Solution {
public:
	bool isMatch(string s, string p) {
		m_r = p.length();
		m_c = s.length();
		vector<vector<bool>> dp(m_r+1, vector<bool>(m_c+1));
		dp[0][0] = true; 
		for (int i = 1; (i < m_r)&&('*'== p[i]); i+=2 )
		{
			dp[i + 1][0] = dp[i - 1][0];
		}
		for (int i = 1; i <= m_r; i++)
		{
			auto Match = [&p, &s](int i,int j) {return ('.' == p[i]) || (s[j] == p[i]); };
			if ((i < m_r) && ('*' == p[i]))
			{
				continue;//x* 在*號那處理
			}
			for (int j = 1; j <= m_c; j++)
			{	
				if ('*' == p[i-1])
				{
					if (i >= 2)
					{//匹配0個字符
						dp[i][j] = dp[i][j] | dp[i - 2][j];
					}
					if (!Match(i - 2, j-1))
					{
						continue;
					}
					dp[i][j] = dp[i][j] | dp[i][j-1];//dp[i][j-1] 的*號,可能匹配了0次,1次,2次...
				}
				else
				{
					if (!Match(i-1, j-1))
					{
						continue;
					}
					dp[i][j] = dp[i - 1][j - 1];
				}
			}

		}
		return dp[m_r][m_c];
	}
	int m_r, m_c;
};

2022年12月舊版

class Solution {
public:
bool isMatch(string s, string p) {
const int lenS = s.size();
const int lenP = p.size();
//dp[i][j]表示 p的前i個字符能否和s的前j個字符匹配
vector<vector> dp;
dp.assign(lenP + 1, vector(lenS + 1));
dp[0][0] = true;
for (int i = 1; i <= lenP; i++)
{
for (int j = 0; j <= lenS; j++)
{
if (‘’ == p[i-1])
{
if (dp[i -2][j ])
{//匹配0個字符
dp[i ][j ] = true;
}
if (0 == j)
{
continue;
}
if (IsSame(p[i - 2], s[j-1]))
{
//匹配一次和匹配多次
if (dp[i - 2][j] || dp[i ][j-1])
{
dp[i][j] = true;
}
}
}
if (0 == j)
{
continue;
}
if ((i < lenP) && ('
’ == p[i ]))
{
//dp[i + 1 + 1][j + 1] != dp[i][j];
}
else
{
if (IsSame(p[i-1], s[j-1]) && dp[i-1][j-1] )
{
dp[i][j] = true;
}
}
}
}
return dp[lenP][lenS];
}
bool IsSame(const char& ch1, const char& ch2)
{
return (‘.’ == ch1) || (‘.’ == ch2) | (ch1 == ch2);
}
};

【動態(tài)規(guī)劃】【字符串】C++算法:正則表達式匹配,# 算法題,數(shù)據(jù)結(jié)構(gòu)與算法,算法,動態(tài)規(guī)劃,c++,leetcode,正則表達式,字符串,通配符

擴展閱讀

視頻課程

有效學(xué)習(xí):明確的目標 及時的反饋 拉伸區(qū)(難度合適),可以先學(xué)簡單的課程,請移步CSDN學(xué)院,聽白銀講師(也就是鄙人)的講解。
https://edu.csdn.net/course/detail/38771

如何你想快

速形成戰(zhàn)斗了,為老板分憂,請學(xué)習(xí)C#入職培訓(xùn)、C++入職培訓(xùn)等課程
https://edu.csdn.net/lecturer/6176

相關(guān)下載

想高屋建瓴的學(xué)習(xí)算法,請下載《喜缺全書算法冊》doc版
https://download.csdn.net/download/he_zhidan/88348653

我想對大家說的話
聞缺陷則喜是一個美好的愿望,早發(fā)現(xiàn)問題,早修改問題,給老板節(jié)約錢。
子墨子言之:事無終始,無務(wù)多業(yè)。也就是我們常說的專業(yè)的人做專業(yè)的事。
如果程序是一條龍,那算法就是他的是睛

測試環(huán)境

操作系統(tǒng):win7 開發(fā)環(huán)境: VS2019 C++17
或者 操作系統(tǒng):win10 開發(fā)環(huán)境: VS2022 C++17
如無特殊說明,本算法用**C++**實現(xiàn)。

【動態(tài)規(guī)劃】【字符串】C++算法:正則表達式匹配,# 算法題,數(shù)據(jù)結(jié)構(gòu)與算法,算法,動態(tài)規(guī)劃,c++,leetcode,正則表達式,字符串,通配符文章來源地址http://www.zghlxwxcb.cn/news/detail-771371.html

到了這里,關(guān)于【動態(tài)規(guī)劃】【字符串】C++算法:正則表達式匹配的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 12.字符串和正則表達式

    正則表達式相關(guān)知識 在編寫處理字符串的程序或網(wǎng)頁時,經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需要,正則表達式就是用于描述這些規(guī)則的工具,換句話說正則表達式是一種工具,它定義了字符串的匹配模式(如何檢查一個字符串是否有跟某種模式匹配的部分或者從一個

    2024年01月16日
    瀏覽(29)
  • python 正則表達式提取字符串

    python 正則表達式提取字符串

    1、提取字符串的場景及公式、命令 背景 :目前遇到的場景主要是以某個字符串開始、某個字符串結(jié)束,提取中間部分的字符,有的時候需要開始的字符,有時不需要,大概涉及到了4種情況,場景及處理方式如下: 1.1 以某個字符開始、某個字符結(jié)束,期待的提取結(jié)果 包含

    2024年02月02日
    瀏覽(24)
  • 【python】12.字符串和正則表達式

    【python】12.字符串和正則表達式

    正則表達式相關(guān)知識 在編寫處理字符串的程序或網(wǎng)頁時,經(jīng)常會有查找符合某些復(fù)雜規(guī)則的字符串的需要,正則表達式就是用于描述這些規(guī)則的工具,換句話說正則表達式是一種工具,它定義了字符串的匹配模式(如何檢查一個字符串是否有跟某種模式匹配的部分或者從一個

    2024年01月16日
    瀏覽(18)
  • notepad++ 正則表達式查找特定字符串

    批量文本的處理方法 在報文中有很多指標和值都具有固定的格式,比如是? a=\\\"1\\\" 這類格式,那么我們只取前面的指標a,就會比較復(fù)雜,而使用正則表達式就會快樂許多! 采用以下第二種方法 查找目標 =(.+?)\\\"? ? 表示查找以等號開頭,引號和空格? 結(jié)尾的字符串,可以避免查

    2024年02月15日
    瀏覽(23)
  • java之字符串與正則表達式

    java之字符串與正則表達式

    目錄 String 構(gòu)造方法 注意 格式控制字符串 常用方法 StringBuilder與StringBuffer 特點 理解可變與不可變 字符串拼接方法 字符串刪除方法 字符串內(nèi)插入字符 字符串替換方法 字符串反轉(zhuǎn)方法 查字符串對應(yīng)索引處的字符? 截取字符串 正則表達式 正則表達式符號表 正則表達式常用方

    2023年04月22日
    瀏覽(24)
  • 正則表達式中 “$” 并不是表示 “字符串結(jié)束

    作者:Seth Larson 譯者:豌豆花下貓@Python貓 英文:Regex character “$” doesn\\\'t mean “end-of-string” 轉(zhuǎn)載請保留作者及譯者信息! 這篇文章寫一寫我最近在用 Python 的正則表達式模塊( re )開發(fā) CPython 的 SBOM 工具時發(fā)現(xiàn)的一個令人驚訝的行為。 如果用過正則表達式,你可能知道 ^

    2024年04月15日
    瀏覽(24)
  • Python 自學(xué)(五) 之字符串及正則表達式

    Python 自學(xué)(五) 之字符串及正則表達式

    目錄 1. 字符串的分割合并? split()? join()? ? ? ? ?P132 2. 字符串的檢索? ?count() find() index() startswith() endswith()? ? ? ? ?P134 3. 去除空格和特殊字符? ?strip()? lstrip() rstrip()? ? ? ? ? P139 4. 格式化字符串? ?format()? ? ? ? ?P142 5. 字符串編碼轉(zhuǎn)換? encode()? decode()? ? ? ? P145

    2024年01月25日
    瀏覽(29)
  • Unity利用正則表達式判斷字符串是否滿足要求

    首先該方法屬于C#,是C#提供的,不是unity提供的,但我使用這個是在unity中使用的,故此我將其歸入unity筆記。 該方式可用于注冊、登錄等等需要用戶輸入的場景,用以判斷字符串是否滿足正則表達式的要求 首先介紹該API 這里開始介紹,大家可以看看官方的文檔Regex.IsMatch 方

    2024年01月16日
    瀏覽(22)
  • 【深入理解ES6】字符串和正則表達式

    字符串(String)是JavaScript6大原始數(shù)據(jù)類型。其他幾個分別是Boolean、Null、Undefined、Number、Symbol(es6新增)。 字符串里的字符有兩種: 前??個碼位均以16位的編碼單元表示的BMP字符(基本多文種平面。 超過??的UTF-16引入了代理對,以兩個編碼單元32位表示輔助平面字符。 ES5中

    2024年02月13日
    瀏覽(26)
  • 使用正則表達式 移除 HTML 標簽后得到字符串

    使用正則表達式 移除 HTML 標簽后得到字符串

    在上述代碼中,stripHTMLTags 函數(shù)使用正則表達式 /[^]+/g 來匹配所有的 HTML 標簽,并使用空字符串進行替換,從而將 HTML 標簽移除。 最后,返回移除 HTML 標簽后的字符串。

    2024年02月14日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包