新浪微博算法題

    這是我在面試過程中遇到的一道代碼算法題,需要我在一定的時間內完成這個題目,題目的描述:

                將某字符串str1中的字符串str2,全部替換成字符串str3。
                例如:str1=”abcecbbccefgxyzbcgbcg”,
str2=”bc”,
str3=”xy”.
替換後爲”axyecbxycefgxyzxygxyg”
        請儘可能考慮各類情況,並保證時間複雜度和空間複雜度最優。

    這個題看似簡單的做法是可以的解決的,我當時也想過簡單的暴力求解法解決。後來我仔細想了想,這個題目應該分爲三步:

1找,2定,3換。先找到服藥要求的串,找出它的下標,替換該字符串。

    我們都知道字符串的查找算法中最有名的就是KMP算法了,所以我決定採用KMP算法去找,找到下標後就可以替換了。若是不懂KMP算法的話,我建議大家去七月的博客上看一下他寫的詳解KMP算法,寫的很詳細很清晰很容易上手。我這裏主要是解決這個題,先就不說KMP算法的原理和部件了。我們主要討論解題的方法,下面我就給出代碼,可能並不是最優的解法,大家若有更好的解法記得跟我交流一下,一起分享一下。

//構造next 數組 
void makeNext(const char *patten,int *arr) 
{ 
	assert(patten); 
	int len = strlen(patten); 
	int pos1 = 1; 
	int pos2 = 0; 
	for(inti = 1; i<len; i++) 
	{ 
	   if(pos1 <= i && patten[pos1-1] == patten[pos2]) 
	   {
		arr[i]=arr[i-1]+1; //若前面已經出現了前綴後綴匹配,則 next 值加一 pos2++;
	   } 
	   else 
	   {
		if(patten[pos1-1]==patten[0])//前面的匹配失敗,可能存在新的前綴後綴匹配
		{
			arr[i]=1; 
			pos2=1;
		}
	   } 
	   ++pos1;
	}
	
	for(inti = len-1; i>0; --i) 
        { 
	    arr[i]=arr[i]-1; 
	} 
	arr[0]=-1;
}

//將配位位置的模式串替換成新串 
void Replace(char *str,const char *newstr,int plen) 
{ 
	assert(str); 
	assert(newstr); 
	for(inti = 0; i < plen; ++i) 
	{
	    str[i] = newstr[i]; 
	} 
}	

//查找匹配的串的位置 
int Find(const char *str,const char *patten,int len,const int *next) 
{ 
	assert(str); 
	assert(patten); 
	assert(next);
	intslen = strlen(str); //主串長度 
	if(slen == 1) //長度爲 1 的字符串,相當於查找單個字符 
	{ 
		for(int i = 0; i < len; ++i)
		{
			if(str[i] == patten[0]) 
				return i;
		}
		return-1;
	}
	int s = 0; // 主串下標 
	int t = 0; // 子串下標 
	while(t<len && s<slen) 
	{ 
		if(str[s] == patten[t]) 
		{ 
			if(t == len-1)//成功匹配 
			{ 
				return(s-t); 
			} 
			++s; 
			++t; 
		 } 
		else//不相等 
		{ 
			if(next[t] == -1) //第一個都不匹配,子串與主串失敗的下一個位置比較 
			{ 
				++s; 
				t = 0; 
				continue; 
			}
			t = next[t]; //前面的已經匹配,不用再比較了
		}
	} 
	return -1;
}

void ReplaceSubstr(char *str,const char *patten,const char *newstr) 
{ /* 目標:將 str中所有的 patten 串換成 newstr 串 */
	//判斷指針是否合法 
	assert(str); 
	assert(patten);
	assert(newstr); 
	assert(strlen(patten) == strlen(newstr));
	//構造 next 數組 
	int plen = strlen(patten);//patten串的長度 
	int *next = newint[plen]; 
	memset(next,0,sizeof(int)*plen); 
	makeNext(patten,next);
	int slen = strlen(str);//主串的長度 char*pstr=str; //pstr 要不斷往前移動
	int curpos = 0;//本次的相對偏移
	while( (curpos = Find(pstr,patten,plen,next) ) != -1) 
	{ 
		Replace(pstr+curpos,newstr,plen); 
		curpos += plen; 
		pstr += curpos; 
	}
	delete[]next;
}

//測試用例 
void TestReplacestr() 
{ /*charstr[]="abcecbbccefgxyzbcgbcg"; char*patten="bc"; char*newstr="xy";*/
	charstr[] = "abcecbbccefgxyzbcgb"; 
	char*patten = "b"; 
	char*newstr = "x"; 
	cout<<str<<endl; 
	ReplaceSubstr(str,patten,newstr); 
	cout<<str<<endl;
}
大家若是覺得有什麼不妥的地方,請你們給我指出!

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