·问题描述
假设需要生成前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[]是存系数的数组