·问题描述
假设需要生成前N个自然数的一个随机置换。例如,{4,3,1,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现两次而数3却没有。这个程序常常用于模拟一些算法。我们假设存在一个随机数生成器RandInt(i,j),它以相同的概率生成i和j之间的一个整数。
//生成前N个自然数的一个随机置换。比较下列三种算法的效率 #include<stdlib.h> #include<stdio.h> #include<time.h> #define CONTAINER 2000000 //#define DEBUG 1 int RandInt(int leftborder, int rightborder);//产生随机数x,leftborder<=x<=rightborder void Algorithm_pow_N_1(int array[], int n);//第一个算法,运行时间=O(N²logN), 传入数组、数组长度 void Algorithm_pow_N_2(int array[], int n);//第二个算法,运行时间=O(NlogN), 传入数组、数组长度 void Algorithm_pow_N_3(int array[], int n);//第三个算法,运行时间=O(N), 传入数组、数组长度 思路神奇好好学习 int main() { clock_t starttime, endtime; int array[CONTAINER]; srand(time_t(NULL)); starttime = clock(); Algorithm_pow_N_3(array, CONTAINER); endtime = clock(); printf("——total running time: %lf s\n",(double)(endtime - starttime) / CLOCKS_PER_SEC); system("pause"); return 0; } //产生随机数x,leftborder<=x<=rightborder int RandInt(int leftborder, int rightborder) { return rand() % (rightborder - leftborder + 1) + leftborder; } //第一个算法,运行时间=OO(N²logN), 传入数组、数组长度 //每次生成随机数都遍历已添入的数据确保不重复 void Algorithm_pow_N_1(int array[], int n) { int i, j; for (i = 0; i < n; i++) { int insert; do { insert = 0; array[i] = RandInt(1, n); for (j = 0; j < i; j++) { if (array[i] == array[j]) { insert = 1; break; } } } while (insert); #ifdef DEBUG printf("test:array[%d]= %d\n", i, array[i]); #endif // DEBUG } } //第二个算法,运行时间=O(NlogN), 传入数组、数组长度 //插旗,给每个已经读入的数据立flag代表使用过 void Algorithm_pow_N_2(int array[], int n) { int used[CONTAINER+1] = { 0 }; for (int i = 0; i < n; i++) { int ran; do { ran = RandInt(1, n); } while (used[ran]); array[i] = ran; used[ran] = 1; #ifdef DEBUG printf("test:array[%d]= %d\n", i, array[i]); #endif // DEBUG } } //第三个算法,运行时间=O(N), 传入数组、数组长度 思路神奇好好学习 void Algorithm_pow_N_3(int array[], int n) { int i; for (i = 0; i < n; i++) array[i] = i + 1; for (i = 0; i < n; i++) { int ran = RandInt(0, n - 1); int swap; swap = array[ran]; array[ran] = array[i]; array[i] = swap; #ifdef DEBUG printf("test:array[%d]= %d\n", i, array[i]); #endif // DEBUG } }
·问题描述:计算F(X)=nΣi=0 x^i 用基础程序和递归程序执行,比较运算时间
//计算F(X)=nΣi=0 x^i 用基础程序和递归程序执行,比较运算时间 #include<stdlib.h> #include<stdio.h> #include<time.h> int simplypower(int x, int n);//求x的n次幂 O(N^2) int recursionpower(int x, int n);//分治递归版 O(NlogN) int main() { int x, n; long int sum = 0; int i; clock_t start, end; printf("please enter a number and the power you want to calculate\n"); scanf("%d%d", &x, &n); start = clock(); for (i = 0; i <= n; i++) sum += recursionpower(x, i); printf("F(X)=nΣi=0 x^i= %d\n", sum); end = clock(); printf("total calulating time: %lf s\n", (end - start) / CLOCKS_PER_SEC); system("pause"); return 0; } int simplypower(int x, int n)//求x的n次幂 { long int result = 1; int i = 0; for (i; i < n; i++) result *= x; return result; } int recursionpower(int x, int n)//分治递归版 { if (n == 1) return x; else if (!n) return 1; else { if (n % 2)//n为奇数 { return recursionpower(x, (n - 1) / 2)*recursionpower(x, (n - 1) / 2)*x; } else return recursionpower(x, n / 2)*recursionpower(x, n/ 2); } }
仍存问题:c中大数的存储——数组或链表字符串的方式存储(未在本函数中尝试实现,待研究)
故本函数对大数处理无力,超出long int数据长度
Horner法则
多项式求值问题,最容易想到的算法是求出每一项的值然后所求值累加起来,这种算法的时间和空间效率都不高,对于数据规模不大的题目来说由于其直观、简单很容易被大家采纳,可一旦数据规模过大时,这种算法就显得无能为力了,下面介绍一种解决这类求值问题的高效算法――霍纳法则。在中国,霍纳法则也被称为秦九韶算法。
思路:不断提出底数x。
例如,当x=3时,计算p(x)=2x^4-x^3+3x^2+x-5的值。对于多项式p(x)=2x^4-x^3+3x^2+x-5,我们按霍纳法则进行变换,有:
p(x)=2x^4-x^3+3x^2+x-5
=x(2x^3-x^2+3x+1)-5
=x(x(2x^2-x+3)+1)-5
=x(x(x(2x-1)+3)+1)-5
代码实现:
poly=0; for(int i=n;i>=0;i--) poly=x*poly+A[i];//A[]是存系数的数组