PTA題---求兩個有序序列中位數所體現的思想。


---恢復內容開始---

  近日,在做PTA題目時,遇到了一個這樣的題,困擾了很久。題目如下:已知有兩個等長的非降序序列S1, S2, 設計函數求S1與S2並集的中位數。有序序列A0​​,A1​​,,AN1​​的中位數指A(N1)/2​​的值,

即第(N+1)/2⌋個數(A0​​為第1個數)。輸入分三行。第一行給出序列的公共長度N(0<N≤100000),隨后每行輸入一個序列的信息,即N個非降序排列的整數。數字用空格間隔。

  首先,分析題可知:該題中的序列是一個升序

的序列(可能存在連續幾個相等數的序列),要求這兩個序列的並集,可以使用兩個順序表實現,這兩個順序表所需要的操作是:構造函數、插入函數(用於求集)、析構函數(不需要)、求中位數(因為對象無法訪問其私有成員)、再者就是求並集的函數(是本文的重點,稍后奉上)。其次,在三行中輸入數,我在N值取法還存在很大疑問,也致使本題始終得不到完全正確的結果, 下次重點分析這個問題。

  求兩個序列的並集,會想到的是,遍歷其中一個順序表,將另外一個順序表一次插入到該順序表中。注:連個序列中可能分別存在相同的元素,求並是指,將不同的元素插入。下面具體分析一下這問題。

該函數可以使用順序表作為函數參數的。一個順序表調用該函數,另外一個作為函數參數,傳入進去。

void Seqlist::Union(Seqlist L){
//定義兩個變量去遍歷兩個順序表 int q = 0; int w = 0;
//循環結束的標志是遍歷完兩個順序表,注意的是q在插入w后其長度會變,而w應該不變 while(q <= length && w < L.length){
//當前data[q] < L.data[w]的話,q++,w保持不變。說明w中的數更大,應該插在后面。 if(data[q] < L.data[w]) q++; else if(data[q] == L.data[w]) { q++; w++; }
//當data[q]<L.data[w],執行插入 else insert(q, L.data[w]); }
//當第一個順序表遍歷完成,而第二個未循環完,將第二個循序表的元素全部插入到第一個循序表中 for( w; w < L.length; w++){ data[q-1] = L.data[w]; q++; length++; } }

上面的比較過程是一個完成的過程,如下面兩個序列1 3 5 7 9、 2 3 4 5 6. 首先1 大於 2, 不執行插入,第一個循環表往下,到了3,3相等,不變。接着,4小於5 則執行插入。往后依次類推。

  另附本題的完整答案:

#include<iostream>
using namespace std;
//定義最大連個數列的最大值
const int MaxSize = 100;

class Seqlist{
public:
	Seqlist(){length = 0;}
	Seqlist(int a[], int n);
	~Seqlist(){}
	void insert(int i, int x);
	void Union(Seqlist L2);
	void GetMidNum();
private:
	int length;
	int data[MaxSize];
};
Seqlist::Seqlist(int a[], int n){
	for(int i = 0; i < n; i++)
		data[i] = a[i];
	length = n;
}
void Seqlist::insert(int i, int x){
	for(int j = length; j > i; j--){
		data[j] = data[j - 1];
	}
	data[i] = x;
	length++;
}
void Seqlist::GetMidNum(){
	cout << data[(length - 1) / 2] << endl;
}
void Seqlist::Union(Seqlist L){
	int q = 0;
	int w = 0;
	while(q <= length && w < L.length){
		if(data[q] < L.data[w])
			q++;
		else if(data[q] == L.data[w])
		{
			q++;
			w++;
		}
		else
			insert(q, L.data[w]);
	}
	for( w; w < L.length; w++){
		data[q-1] = L.data[w];
		q++;
		length++;
	}
}
int main(){

	int a[MaxSize] = {0};
	int b[MaxSize] = {0};
	int m ;
	cin >> m;
	int n = 0;
	while(n < 2){
		int k = 0;
		while(k < m){
			if(n == 0)
				cin >> a[k];
			else
				cin >> b[k];
			k++;
		}
		n++;
	}
	Seqlist L1(a, m);
	Seqlist L2(b, m);
	L1.Union(L2);
	L1.GetMidNum();
	return 0;
}

  但是

 

 

 

 

---恢復內容結束---

  近日,在做PTA題目時,遇到了一個這樣的題,困擾了很久。題目如下:已知有兩個等長的非降序序列S1, S2, 設計函數求S1與S2並集的中位數。有序序列A0​​,A1​​,,AN1​​的中位數指A(N1)/2​​的值,

即第(N+1)/2⌋個數(A0​​為第1個數)。輸入分三行。第一行給出序列的公共長度N(0<N≤100000),隨后每行輸入一個序列的信息,即N個非降序排列的整數。數字用空格間隔。

  首先,分析題可知:該題中的序列是一個升序

的序列(可能存在連續幾個相等數的序列),要求這兩個序列的並集,可以使用兩個順序表實現,這兩個順序表所需要的操作是:構造函數、插入函數(用於求集)、析構函數(不需要)、求中位數(因為對象無法訪問其私有成員)、再者就是求並集的函數(是本文的重點,稍后奉上)。其次,在三行中輸入數,我在N值取法還存在很大疑問,也致使本題始終得不到完全正確的結果, 下次重點分析這個問題。

  求兩個序列的並集,會想到的是,遍歷其中一個順序表,將另外一個順序表一次插入到該順序表中。注:連個序列中可能分別存在相同的元素,求並是指,將不同的元素插入。下面具體分析一下這問題。

該函數可以使用順序表作為函數參數的。一個順序表調用該函數,另外一個作為函數參數,傳入進去。

void Seqlist::Union(Seqlist L){
//定義兩個變量去遍歷兩個順序表 int q = 0; int w = 0;
//循環結束的標志是遍歷完兩個順序表,注意的是q在插入w后其長度會變,而w應該不變 while(q <= length && w < L.length){
//當前data[q] < L.data[w]的話,q++,w保持不變。說明w中的數更大,應該插在后面。 if(data[q] < L.data[w]) q++; else if(data[q] == L.data[w]) { q++; w++; }
//當data[q]<L.data[w],執行插入 else insert(q, L.data[w]); }
//當第一個順序表遍歷完成,而第二個未循環完,將第二個循序表的元素全部插入到第一個循序表中 for( w; w < L.length; w++){ data[q-1] = L.data[w]; q++; length++; } }

上面的比較過程是一個完成的過程,如下面兩個序列1 3 5 7 9、 2 3 4 5 6. 首先1 大於 2, 不執行插入,第一個循環表往下,到了3,3相等,不變。接着,4小於5 則執行插入。往后依次類推。

  另附本題的完整答案:

#include<iostream>
using namespace std;
//定義最大連個數列的最大值
const int MaxSize = 100;

class Seqlist{
public:
	Seqlist(){length = 0;}
	Seqlist(int a[], int n);
	~Seqlist(){}
	void insert(int i, int x);
	void Union(Seqlist L2);
	void GetMidNum();
private:
	int length;
	int data[MaxSize];
};
Seqlist::Seqlist(int a[], int n){
	for(int i = 0; i < n; i++)
		data[i] = a[i];
	length = n;
}
void Seqlist::insert(int i, int x){
	for(int j = length; j > i; j--){
		data[j] = data[j - 1];
	}
	data[i] = x;
	length++;
}
void Seqlist::GetMidNum(){
	cout << data[(length - 1) / 2] << endl;
}
void Seqlist::Union(Seqlist L){
	int q = 0;
	int w = 0;
	while(q <= length && w < L.length){
		if(data[q] < L.data[w])
			q++;
		else if(data[q] == L.data[w])
		{
			q++;
			w++;
		}
		else
			insert(q, L.data[w]);
	}
	for( w; w < L.length; w++){
		data[q-1] = L.data[w];
		q++;
		length++;
	}
}
int main(){

	int a[MaxSize] = {0};
	int b[MaxSize] = {0};
	int m ;
	cin >> m;
	int n = 0;
	while(n < 2){
		int k = 0;
		while(k < m){
			if(n == 0)
				cin >> a[k];
			else
				cin >> b[k];
			k++;
		}
		n++;
	}
	Seqlist L1(a, m);
	Seqlist L2(b, m);
	L1.Union(L2);
	L1.GetMidNum();
	return 0;
}

  但是

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM