·問題描述
假設需要生成前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[]是存係數的數組