由一道公共子串題目引起的自我反思



代碼視圖:

在這裏插入圖片描述

大致內容:

第15行 —— 當int型數據錯誤地參與到了unsigned的數值大小的比較之中。
第18行 —— 以及之後的第20、27行,是否使用臨時存儲變量的問題。
第22行 —— 代碼書寫的贅餘、無用功問題。
第24行 —— 藉助臨時變量的方式問題,像自己之前則是直接 iTemp=i; 和 jTemp=j;而不是如此巧妙的使用第三方實現索引變動。
第30行和第33行 —— 巧妙的設計往往不只是驚喜,還會有意外 —— 思維不夠靈敏的話就會引發 k數值大小多1或差1的問題 —— 當然這也是 循環條件不再滿足之後,控制循環的條件變量在循環體作用域內外使用時候的區別和值得小心之處。
第37行 —— 使用 vector 還得去 sort、得去除重複, 不如直接使用set —— 鍵值對的時候使用 map。
第38行和42行 —— 代碼書寫的嚴實與否的問題,太過疏散瞭如此分開 —— 本可以直接在定義的時候同時加以使用。
第39行 —— 通過輸出檢查代碼是否如預期所想 —— 這是筆者從以前的一位大學同學那學來的冷門技能 —— 雖然是自己看了人家代碼的意外收穫,別人是不太會主動分享的、還得靠自己領悟。

**以上代碼來自修改一位只識得姓名(不知真假)的19級學弟,經自己修改之後得以正常運行,並引發自己的一些思考。**

代碼優化之後:

#include<iostream>
#include<string>
#include<set>
using namespace std;
int main(){

	string str1, str2;
	set<string> subsquSet;
	while (cin >> str1 >> str2){
		unsigned int max = 0;
		for (unsigned int i = 0; i < str1.size(); i++){
			for (unsigned int j = 0; j < str2.size(); j++){
				unsigned int k = 0;
				// 注意,下一行的 while循環的條件位置敏感,必須先是索引合法才能夠去訪問元素;
				while ( i + k < str1.size() && j + k < str2.length() && str1[i + k] == str2[j + k]) {
					k++;
				}
				subsquSet.insert(str1.substr(i, k)); // 等價實現: subsquSet.insert(str2.substr(j, k));
				if (max < k) { max = k; } 
			}
		}
		for (set<string>::iterator iter = subsquSet.begin(); iter != subsquSet.end(); ++iter)
		{
			// cout << *iter << endl; // 輸出所有子串(set集合的元素)
			if ((*iter).size() == max) {
				cout << *iter << endl;
				break;
			}
		}
		subsquSet.clear(); // 記得重置集合爲空;
	}
	return 0;
}

後記:

如需交流,可於評論區留言或者發送私信,當然郵件或者添加好友也可以(只要筆者上線)
[email protected]
如需轉發,轉發請註明出處

附上自己的另外一篇博客:最長公共子串與最長公共子序列詳解

2019/11/22 23:12

容器輸出代碼的進一步優化:

for (auto iter : subsquSet )
		{
			// cout << iter << endl; // 輸出所有子串(set集合的元素)包含空串
			if ((iter).size() == max) {
				cout << iter << endl;
				break;
			}
		}
注意區分:迭代器返回的是 地址,需要地址解析符* 讀取數據,而for each則是直接遍歷各個元素數據本身。
故:推薦將其中代碼的 iter 改寫爲 item。

2019/11/23 16:50

發佈了88 篇原創文章 · 獲贊 230 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章