Make a little progress every day

药物分子设计上机作业

| drugdesign
假设已经有了一个用于求解中位数的“黑箱”子程序,它在最坏情况下需要线性运行时间。写出一个能解决任意顺序统计量的选择问题的线性时间算法。

源代码

#include <iostream>
#include <cassert>
#include <stack>
#include <math.h>
 using namespace std;
 //划分算法
int PARTITION(int A[],int p,int r,int t)
{
    int i=p-1,k=0;
    for (int j=p;j<=r;j++)
    {
        if (A[j]<t)
        {
            i++;
            swap(A[i],A[j]);
        }
        if (A[j]==t)
        {
            k=j;
        }
    }
    swap(A[i+1],A[k]);
    return i+1;
}

 //快排
void QuickSort(int a[], int low, int high) {
    if (low >= high) {
        return;
    }
 
    int pivot = PARTITION(a, low, high,a[low]);
    QuickSort(a, low, pivot - 1);
    QuickSort(a, pivot + 1, high);
}
 //中位数算法
int EvaluateMedian(int a[],int low ,int high) {
    QuickSort(a, low, high-1 );
    int n;
    n=high;
    if (n % 2 != 0) {
        return a[n / 2];
    } else {
        return (a[n / 2] + a[n / 2 - 1]) / 2;
    }
}
int SELECT(int a[],int low ,int high,int i)
{
    if (low>=high)
    {
        return a[low];
    }
    int x=EvaluateMedian(a,low,high);
    int q=PARTITION(a,low,high,x);
    int k=q-low+1;
    if(i==k)
    {
        return a[q];
    }
    else if (i<k)
    {
       return SELECT(a,low,q-1,i);
    }
    else
    {
        return SELECT(a,q+1,high,i-k);
    }
}
int main() {
    int a[9] = {-5, 345, 88, 203, 554, 1, 89, 909, 1001};
    cout<<"the second order statistic is"<<endl;
    cout<< SELECT(a,0,9,2)<<endl;
    return 0;
}

测试用例

a[9] = {-5, 345, 88, 203, 554, 1, 89, 909, 1001};
SELECT(a,0,9,2)

测试结果
输出第二统计量,为1

实现LCS算法

源代码

#include<iostream>
#include<string>
#define NUM 20
using namespace std;
int c[NUM][NUM];//定义二维数组c[NUM][NUM]代表串1与串2的公共子串的最大值
char b[NUM][NUM];
void LCS_LENGTH(string X, string Y){
	int m = X.length();
	int n = Y.length();
	for (int i = 1; i <= m; i++)
		c[i][0] = 0;
	for (int j = 0; j <= n; j++)
		c[0][j] = 0;//赋初值0
	for (int i = 1; i <= m; i++){
		for (int j = 1; j <= n; j++){
			if (X[i - 1] == Y[j - 1]){
				c[i][j] = c[i - 1][j - 1] + 1;
				b[i][j] = 'a';
			}//若相等则上层值+1,并记录为a
			else if (c[i - 1][j] >= c[i][j - 1]){
				c[i][j] = c[i - 1][j];
				b[i][j] = 'b';
			}
			else{
				c[i][j] = c[i][j - 1];
				b[i][j] = 'c';
			}//若不相等则等于交错值中的最大值,分别记录为b,c
		}
	}
}
 //打印出最长子序列
void PRINT_LCS(string X,int m, int n)
{
	if (m == 0 || n == 0)
		return;
	if (b[m][n] == 'a'){
		PRINT_LCS(X,m - 1, n - 1);
		cout << X[m-1];
	}
	else if (b[m][n] == 'b'){
		PRINT_LCS(X, m - 1, n);
	}
	else
		PRINT_LCS(X, m, n - 1);
}
int main()
{
	string X, Y;
	cin >> X >> Y;
	LCS_LENGTH(X, Y);
	PRINT_LCS(X,X.length(), Y.length());
    return 0;
}

测试用例
两个字符串分别为
qwert
wuorit

测试结果