记录一下看到的内容,方便以后回想,也算是有点印记。
对于计算机科学而言,算法(Algorithm)是一个非常重要的概念。它是程序设计的灵魂,是将实际问题同解决问题的计算机程序建立起练习的桥梁。可以这样讲,在编写任何一个计算机程序时(无论使用什么编程语言),都不可避免地要进行算法的设计。
一个程序往往要包含两个方面的描述:一是对数据组织的描述;一是对程序操作流程的描述。对数据组织的描述主要是指定数据的类型和数据的组织形式,称作数据结构;对程序操作流程的描述就是程序的操作步骤,也即算法。数据结构+算法=程序
算法的性质:输入、输出、确定性、有限性。
算法的表示形式很多,包括但不仅限于用自然语言描述、用流程图表示、伪代码等。
穷举法是一种最为直接,实现最为简单,同时又是最为耗时的一种解决实际问题的算法思想。
【实例3-3】寻找1~100之间的素数。
题目分析:判断1至100种的每个数是否是素数即可。
// 3-3 2023年12月25日11点24分-11点28分
# include
# include
int isprime(int num)
{ // 判断num是否是素数,是则返回1,不是则返回0
int flg = 1;
if (num <= 1) // 1不是素数
flg = 0;
else {
for (int i = 2; num > 2 && i <= sqrt(num); ++i)
if (num % i == 0) {
flg = 0;
break;
}
}
return flg;
}
void getPrime(int low, int high)
{ // 寻找[low, high]之间的素数
for (int i = low; i <= high; ++i) {
if (isprime(i)) {
printf("%d ", i);
}
}
}
int main()
{
int low, high;
printf("Please input the domain for searching prime\n");
printf("low limitation:");
scanf("%d", & low);
printf("high limitation:");
scanf("%d", & high);
printf("The whole primes in this domain are\n");
getPrime(low, high);
return 0;
}
【实例3-4】TOM共有5本新书,要借给A、B、C3位同学,每人只能借1本书,则TOM可以有多少种不同的借书方法。
// 3-4 2023年12月25日11点38分-11点43分
# include
void func(void)
{ // 三人借的书不相同
int cnt = 0;
for (int i = 1; i <= 5; ++i) {
for (int j = 1; j <= 5; ++j) {
if (j == i) {
continue;
}
for (int k = 1; k <= 5; ++k) {
if (k == i || k == j) {
continue;
}
printf("<%d,%d,%d>", i, j, k);
++cnt;
if (cnt == 5) {
putchar('\n');
cnt = 0;
} else {
printf(", ");
}
}
}
}
}
int main()
{
printf("There are different methods for TOM to distribute his books to A, B, C\n");
func();
return 0;
}
递归与分治
将一个规模较大的问题分割成规模较小的同类问题,然后将这些小的子问题逐个加以解决,最终也就将整个大的问题解决了。
【实例3-5】计算n的阶乘n!。
// 3-5 2023年12月25日11点55分-11点59分
# include
//int factorial(int num)
//{ // 循环累乘
// int res = 1;
// for (int i = 1; i <= num; ++i) {
// res *= i;
// }
// return res;
//}
int factorial(int num)
{ // 递归
if (num == 0) // 递归结束标志,递归结束的出口
return 1;
else
return num * factorial(num - 1);
}
int main()
{
int n;
printf("Please input a number:");
scanf("%d", & n);
printf("The result is %d", factorial(n));
return 0;
}
【实例3-6】将一个正整数n表示成一系列的正整数之和,被称作正整数n的一个划分。计算整数的划分数。
// 3-6 2023年12月25日12点12分-12点16分
# include
int P(int n, int m)
{
if (m == 1 || n == 1)
return 1;
if (m > n)
return P(n, n);
if (m == n)
return 1 + P(n, m-1);
return P(n, m-1) + P(n-m, m);
}
int main()
{
int n, s;
printf("Please input a integer for getting the number of division\n");
scanf("%d", & n); // 输入正整数n
s = P(n, n); // 求出正整数n的划分数
printf("The number of division of %d is %d\n", n, s);
return 0;
}
【实例3-7】递归的方法实现折半查找。
// 3-7 2023年12月25日15点34分-15点49分
int bin_search(int A[], int low, int high, int x)
{
if (low > high) {
return -1;
} else {
int mid = (high + low) / 2; // 要认真,是相加除以2,不是相减除以2
if (A[mid] == x) {
return mid;
} else if (A[mid] > x) {
return bin_search(A, low, mid - 1, x);
} else {
return bin_search(A, mid + 1, high, x);
}
}
}
# include
int main()
{
int A[10] = {2, 3, 5, 7, 8, 10, 12, 15, 19, 21}; // 初始化数组序列A
printf("The contents of the Array A[10] are\n");
for (int i = 0; i < 10; ++i) {
printf("%d ", A[i]); // 显示数组A中的内容
}
printf("\nPlease input a integer for search\n");
int n;
scanf("%d", & n); // 输入待查找的元素
int addr = bin_search(A, 0, 9, n);
if (-1 != addr) // 查找成功
printf("%d is at the %dth unit in array A\n", n, addr + 1);
else // 查找失败
printf("There is no %d in array A\n", n);
return 0;
}
贪心算法
所谓贪心算法,就是总是做出在当前看来是最好的选择的一种方法。
【实例3-8】有一批集装箱要装入一个载质量为C的货船中,每个集装箱的质量由用户自己输入指定,在货船的装载体积不限的前提下,如何装在集装箱才能尽可能多的将集装箱载入货船中。
// 3-8 2023年12月25日16点08分-16点25分
# include
# include
void sort(int w[], int t[], int n)
{
int *w_tmp = (int *)malloc(sizeof(int) * n); // 动态开辟一个临时数组,存放w[]中的内容,用于排序
for (int i = 0; i < n; ++i)
t[i] = i; // 初始化数组t
for (int i = 0; i < n; ++i)
w_tmp[i] = w[i];
for (int i = 0; i < n-1; ++i) {
for (int j = 0; j < n-1-i; ++j) {
if (w_tmp[j] > w_tmp[j+1]) {
int tmp = w_tmp[j];
w_tmp[j] = w_tmp[j+1];
w_tmp[j+1] = tmp;
tmp = t[j];
t[j] = t[j+1];
t[j+1] = tmp;
}
}
}
}
void Loading(int x[], int w[], int c, int n)
{
int *t = (int *)malloc(sizeof(int) * n); // 动态开辟一个临时数组,存放w[]的下标
sort(w, t, n); // 排序,用数组t存放数组w的下标
for (int i = 0; i < n; ++i)
x[i] = 0; // 初始化数组x
for (int i = 0; i < n && w[t[i]] <= c; ++i) {
x[t[i]] = 1; // 将第t[i]个集装箱装入货船中
c -= w[t[i]]; // 变量c存放货船的剩余载质量
}
}
int main()
{
int x[5], w[5], c;
printf("Please input the maximum loading of the ship\n");
scanf("%d", & c); // 输入货船的最大载质量
printf("Please input the weight of FIVE box\n");
for (int i = 0; i < 5; ++i)
scanf("%d", & w[i]); // 输入每个集装箱的质量
Loading(x, w, c, 5); // 进行最优装载
printf("The following boxes will be loaded\n");
for (int i = 0; i < 5; ++i) // 输出结果
if (1 == x[i])
printf("BOX:%d ", i);
return 0;
}
回溯法
【实例3-9】应用回溯法的思想求解四皇后问题。
// 3-9 2023年12月25日16点32分-16点51分
# include
int count = 0; // 记录四皇后问题解的个数
int isCorrect(int i, int j, int (*Q)[4])
{
for (int s = i, t = 0; t < 4; ++t)
if (Q[s][t] == 1 && t != j) // 判断行
return 0;
for (int s = 0, t = j; s < 4; ++s)
if (Q[s][t] == 1 && s != i) // 判断列
return 0;
for (int s = i-1, t = j-1; s >= 0 && t >= 0; --s, --t)
if (Q[s][t] == 1) // 判断左上方
return 0;
for (int s = i+1, t = j+1; s < 4 && t < 4; ++s, ++t)
if (Q[s][t] == 1) // 判断右下方
return 0;
for (int s = i-1, t = j+1; s >= 0 && t < 4; --s, ++t)
if (Q[s][t] == 1) // 判断右上方
return 0;
for (int s = i+1, t = j-1; s < 4 && t >= 0; ++s, --t)
if (Q[s][t] == 1) // 判断左下方
return 0;
return 1; // 否则返回1
}
void Queen(int j, int (*Q)[4])
{
if (j == 4) {
for (int i = 0; i < 4; ++i) { // 得到了一个解,在屏幕上输出结果
for (int k = 0; k < 4; ++k) {
printf("%d ", Q[i][k]);
}
printf("\n");
}
printf("\n");
++count;
return ;
}
for (int i = 0; i < 4; ++i) {
if (isCorrect(i, j, Q)) { // 如果Q[i][j]可以放置皇后
Q[i][j] = 1; // 放置皇后
Queen(j+1, Q); // 递归深度优先搜索解空间树
Q[i][j] = 0;
}
}
}
int main()
{
int Q[4][4];
for (int i = 0; i < 4; ++i) { // 初始化数组Q
for (int j = 0; j < 4; ++j) {
Q[i][j] = 0;
}
}
Queen(0, Q); // 执行四皇后求解
printf("The number of the answers of FOUR_QUEEN are %d", count);
return 0;
}
数值概率算法
【实例3-10】计算定积分。
// 3-10 2023年12月25日18点27分-18点33分
# include
# include
# include
# include
double Darts(int n)
{
double x, y;
time_t t;
int i, count = 0;
srand((unsigned)time(& t));
for (i = 0; i < n; ++i) {
x = rand() % 100 / 100.0;
y = rand() % 100 / 100.0;
if (y <= 1 - pow(x, 2))
++count;
}
return (double)count / (double)n;
}
int main()
{
int n;
printf("Please input the accuracy\n");
scanf("%d", & n);
printf("The result is about\n");
printf("%f\n", Darts(n));
return 0;
}
要加油啊!