算法--以自動機實現的字符串匹配

字符串匹配

性質

給定模式集合,和源集合。
算法輸出源集合中和模式匹配的所有相關處的起始位置。

接口設計

template<typename T>
class CharacterMatch
{
public:
	CharacterMatch();
	~CharacterMatch();
public:
	DataStruct::Array::DynArray<int> RunInAutoMachine(
		const DataStruct::Array::DynArray<T>& arrPattern_,
		const DataStruct::Array::DynArray<T>& arrSource_);
};

實現

構造

template<typename T>
CharacterMatch<T>::CharacterMatch()
{

}

析構

template<typename T>
CharacterMatch<T>::~CharacterMatch()
{

}

算法運行

template<typename T>
DataStruct::Array::DynArray<int> CharacterMatch<T>::RunInAutoMachine(
	const DataStruct::Array::DynArray<T>& arrPattern_,
	const DataStruct::Array::DynArray<T>& arrSource_)
{
	int _nPatternLen = arrPattern_.GetSize();
	int _nSourceLen = arrSource_.GetSize();
	int _nPreMaxMatchLen = 0;
	int _nCurMaxMatchLen = 0;
	DataStruct::Array::DynArray<int> _arrRet;
	for (int _i = 0; _i < _nSourceLen; _i++)
	{
		if (_nPreMaxMatchLen == _nPatternLen)
		{
			for (int _nCurMayMaxMatchLen = _nPreMaxMatchLen; _nCurMayMaxMatchLen >= 0; _nCurMayMaxMatchLen--)
			{
				bool _bSuccess = true;
				int _k = 0;
				while (_k < _nCurMayMaxMatchLen)
				{
					if (arrSource_[_i - _k] == arrPattern_[_nCurMayMaxMatchLen - 1 - _k])
					{
						_k++;
					}
					else
					{
						break;
					}
				}

				if (_k == _nCurMayMaxMatchLen)
				{
					_bSuccess = true;
				}
				else
				{
					_bSuccess = false;
				}

				if (_bSuccess)
				{
					_nCurMaxMatchLen = _nCurMayMaxMatchLen;
					break;
				}
			}
		}
		else
		{
			if (arrSource_[_i] == arrPattern_[_nPreMaxMatchLen])
			{
				_nCurMaxMatchLen = _nPreMaxMatchLen + 1;
			}
			else
			{
				for (int _nCurMayMaxMatchLen = _nPreMaxMatchLen; _nCurMayMaxMatchLen >= 0; _nCurMayMaxMatchLen--)
				{
					bool _bSuccess = true;
					int _k = 0;
					while (_k < _nCurMayMaxMatchLen)
					{
						if (arrSource_[_i - _k] == arrPattern_[_nCurMayMaxMatchLen - 1 - _k])
						{
							_k++;
						}
						else
						{
							break;
						}
					}

					if (_k == _nCurMayMaxMatchLen)
					{
						_bSuccess = true;
					}
					else
					{
						_bSuccess = false;
					}

					if (_bSuccess)
					{
						_nCurMaxMatchLen = _nCurMayMaxMatchLen;
						break;
					}
				}
			}
		}

		if (_nCurMaxMatchLen == _nPatternLen)
		{
			_arrRet.Add(_i - _nPatternLen + 1);
		}

		_nPreMaxMatchLen = _nCurMaxMatchLen;
	}
}

算法目標&正確性證明

算法正確性證明:
算法以迭代方式實現
以迭代方式實現的算法正確性證明依賴於循環不變式
循環不變式:
每次迭代開始時,我們總是可以得到到上次迭代位置爲止,可以與模式產生的最大匹配的長度

若循環不變式成立,
可知,我們在每次迭代結束,得到本次迭代位置爲止,可以與模式產生的最大匹配的長度
若該長度 等於 模式本身長度,則 得到的一次模式的匹配。
如此,必可得到 所有關於模式的匹配信息。得證。

循環不變式證明:
初始時,
在首次迭代前,_nPreMaxMatchLen = 0,循環不變式成立。
對於第k次迭代,
依據循環不變式,_nPreMaxMatchLen表示到上次位置爲止可以與模式產生的最大匹配的長度
若
本位置元素 等於 模式第(_nPreMaxMatchLen+1)處元素
易於知道,此時
從當前位置往前共(_nPreMaxMatchLen+1)個元素,分別依次與模式第(_nPreMaxMatchLen+1)到第一個元素依次相等。
故,當前位置位置 可與模式達成的最大匹配長度必然 >= (_nPreMaxMatchLen+1)
假設 當前位置位置 可與模式達成的最大匹配長度 爲len > (_nPreMaxMatchLen+1)
則,可推導出 當前上一位置爲止 可與模式達成的最大匹配長度 必然 >= (len-1) > _nPreMaxMatchLen
這與事實矛盾,故當前位置位置 可與模式達成的最大匹配長度爲 (_nPreMaxMatchLen+1)

若
本位置元素 不等於 模式第(_nPreMaxMatchLen+1)處元素
假設當前位置位置 可與模式達成的最大匹配長度 爲len > (_nPreMaxMatchLen+1)
則,可推導出 當前上一位置爲止 可與模式達成的最大匹配長度 必然 >= (len-1) > _nPreMaxMatchLen
這與事實矛盾,故當前位置位置 可與模式達成的最大匹配長度不會大於 (_nPreMaxMatchLen+1)
假設當前位置位置 可與模式達成的最大匹配長度 爲len = (_nPreMaxMatchLen+1)
則,可推導出 本位置元素 等於 模式第(_nPreMaxMatchLen+1)處元素,
這與事實矛盾,故當前位置位置 可與模式達成的最大匹配長度不會等於 (_nPreMaxMatchLen+1)
綜合,當前位置位置 可與模式達成的最大匹配長度只會<= (_nPreMaxMatchLen)
而我們對_nPreMaxMatchLen,...,0可能的匹配長度依次進行考察
故,考察完畢必可得到正確的_nCurMaxMatchLen

綜合,一次迭代結束,我們總是能得到 當前位置爲止可能與模式產生的最大匹配的長度,
進而,循環不變式成立。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章