1. 程式人生 > >第五屆藍橋杯軟體大賽C/C++本科B組決賽解題報告

第五屆藍橋杯軟體大賽C/C++本科B組決賽解題報告

3,訊號匹配
    從X星球接收了一個數字訊號序列。
    現有一個已知的樣板序列。需要在訊號序列中查詢它首次出現的位置。這類似於串的匹配操作
    如果訊號序列較長,樣板序列中重複數字較多,就應當注意比較的策略了。可以仿照串的KMP演算法,進行無回溯的匹配。這種匹配方法的關鍵是構造next陣列。
    next[i] 表示第i項比較失配時,樣板序列向右滑動,需要重新比較的項的序號。如果為-1,表示母序列可以進入失配位置的下一個位置進行新的比較。
    下面的程式碼實現了這個功能,請仔細閱讀原始碼,推斷劃線位置缺失的程式碼。
// 生成next陣列 
int* make_next(int pa[], int pn)
{
	int* next = (int*)malloc(sizeof(int)*pn);
	next[0] = -1;
	int j = 0;
	int k = -1;
	while(j < pn-1){
		if(k==-1 || pa[j]==pa[k]){
			j++;
			k++;
			next[j] = k;
		}
		else
			k = next[k];
	}
	
	return next;
}
// da中搜索pa, da的長度為an, pa的長度為pn 
int find(int da[], int an, int pa[], int pn)
{
	int rst = -1;
	int* next = make_next(pa, pn);
	int i=0;  // da中的指標 
	int j=0;  // pa中的指標
	int n = 0;
	while(i<an){
		n++;
		if(da[i]==pa[j] || j==-1){
			i++;
			j++;
		}
		else
			__________________________;  //填空位置
		
		if(j==pn) {
			rst = i-pn;
			break;
		}
	}
	
	free(next);
		
	return rst;
}

int main()
{
	int da[] = {1,2,1,2,1,1,2,1,2,1,1,2,1,1,2,1,1,2,1,2,1,1,2,1,1,2,1,1,1,2,1,2,3};
	int pa[] = {1,2,1,1,2,1,1,1,2};
	
	int n = find(da, sizeof(da)/sizeof(int), pa, sizeof(pa)/sizeof(int));
	printf("%d\n", n);
	
	return 0;
}

注意:通過瀏覽器提交答案。只填寫缺少的內容,不要填寫任何多餘的內容(例如:說明性文字或已有符號)
答案:j=next[j]