1 穷举算法
穷举算法(Exhaustive Attack method)是最简单的一种算法.其依赖于计算机的强大
算能力,来穷尽每一种可能的情况,从而达到求解问题的目的。穷举算法效率并不高,但是适合于一些没有明显规律可循的场合。
- 穷举算法基本思想
穷举算法的基本思想就是从所有可能的情况中搜索正确的答案,其执行步骤如下:
- 对于一种可能的情况,计算其结果。
- 判断结果是否满足要求,如果不满足则执行第 1 步来搜索下一个可能的情况;如果满足要求,则表示寻找到一个正确的答案。
在使用穷举算法时,需要明确问题的答案的范围,这样才可以在指定范围内搜索答案。指定范围之后,就可以使用循环语句和条件判断语句逐步验证候选答案的正确性,从而得到正确答案
import java.util.Scanner;
// 穷举法求解鸡兔同笼问题
public class ChickenAndRabbit {
static int chicken, rabbit;
public static boolean methodOfExhaustion(int head, int foot) {
boolean result = false;
int i, j;
for (i = 0; i <= head; i++) {
j = head - i;
if (i * 2 + j * 4 == foot) {
result = true;
chicken = i;
rabbit = j;
}
}
return result;
}
public static void main(String[] args) {
System.out.println("穷举法求解鸡兔同笼问题...");
System.out.print("请输入头数:");
Scanner input = new Scanner(System.in);
int head = input.nextInt();
System.out.print("请输入脚数:");
int foot = input.nextInt();
if (methodOfExhaustion(head, foot))
System.out.println("鸡 " + chicken + " 只,兔 " + rabbit + " 只。");
else
System.out.println("无解。");
}
}
2 递推算法
递推算法是很常用的算法思想,在数学计算等方面有着广泛的应用。递推算法适合有着明显公式规律的场合。
- 递推算法基本思想
递推算法是一种理性思维模式的代表,其根据己有的数据和关系,逐步推导而得到结果。递推算法的执行过程如下:
- 根据已知结果和关系,求解中间结果。
- 判定是否达到要求,如果没有达到,则继续根据已知结果和关系求解中间结果;如果满足要求,则表示寻找到一个正确的答案。
递推算法往往需要用户知道答案和问题之间的逻辑关系。在许多数学问题中,都有着明确的计算公式可以遵循,因此往往可以采用递推算法来实现。
import java.util.Scanner;
public class RabbitLitter {
static int fibonacci(int n) {
if (n == 1 || n == 2) {
return 1;
} else {
return fibonacci(n-1) + fibonacci(n-2);
}
}
public static void main(String[] args) {
System.out.println("递推算法求解兔子产仔...");
System.out.print("请输入时间:");
Scanner scanner = new Scanner(System.in);
int month = scanner.nextInt();
System.out.printf("经过 %d 月,共能繁殖 %d 对兔子\n", month, fibonacci(month));
}
}
递推算法求解兔子产仔...
请输入时间:12
经过 12 月,共能繁殖 144 对兔子
Process finished with exit code 0
3 递归算法
import java.util.Scanner;
public class RecursiveAlgorithm {
static long fact(int n) {
if (n <= 1)
return 1;
else
return n * fact(n - 1);
}
public static void main(String[] args) {
System.out.println("递归算法求解阶乘...");
System.out.print("请输入一个整数:");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.printf("%d 的阶乘为 %d.\n", n, fact(n));
}
}
递归算法求解阶乘...
请输入一个整数:12
12 的阶乘为 479001600.
Process finished with exit code 0
4 分治算法
import java.util.Scanner;
public class DivideAndConquerAlgorithm {
static final int MAXCOINNUM = 30;
static int falseCoin(int[] coin, int low, int high) {
int sum1, sum2;
sum1 = sum2 = 0;
// 递归出口
if (low + 1 == high) {
if (coin[low] < coin[high]) {
return low + 1;// 硬币序号比下标大 1
} else {
return high + 1;
}
}
// 分解问题
if ((high - low + 1) % 2 == 0) {// 当硬币个数为偶数
for (int j = low; j <= low + (high - low) / 2; j++) {
sum1 += coin[j]; // 前一半硬币的重量
}
for (int j = low + (high - low) / 2 + 1; j <= high; j++) {
sum2 += coin[j]; // 后一半硬币的重量
}
if (sum1 > sum2) // 假币在后一半中,在后一半中继续查找
return falseCoin(coin, low + (high - low) / 2 + 1, high);
else // 假币在前一半中,在前一半中继续查找
return falseCoin(coin, low, low + (high - low) / 2);
} else { // 当硬币个数为奇数
for (int j = low; j <= low + (high - low) / 2 - 1; j++) {
sum1 += coin[j]; // 前一半硬币的重量
}
for (int j = low + (high - low) / 2 + 1; j <= high; j++) {
sum2 += coin[j]; // 后一半硬币的重量
}
if (sum1 > sum2) { // 假币在后一半中,在后一半中继续查找
return falseCoin(coin, low + (high - low) / 2 + 1, high);
} else if (sum1 < sum2) { // 假币在前一半中,在前一半中继续查找
return falseCoin(coin, low, low + (high - low) / 2 - 1);
} else { // 假币为中间那个硬币
return low + (high - low) / 2 + 1;
}
}
}
public static void main(String[] args) {
System.out.println("分治算法求假币问题...");
int[] coin = new int[MAXCOINNUM];
System.out.print("请输入硬币总个数:");
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
System.out.println("请逐个输入硬币重量(只能有一枚假币)...");
for (int i = 0; i < n; i++) {
coin[i] = scanner.nextInt();
}
System.out.printf("%d 个硬币中,第 %d 个硬币为假币。\n", n, falseCoin(coin, 0, n - 1));
}
}
分治算法求假币问题...
请输入硬币总个数:13
请逐个输入硬币重量(只能有一枚假币)...
1 5 5 5 5 5 5 5 5 5 5 5 5
13 个硬币中,第 1 个硬币为假币。
Process finished with exit code 0
5 概率算法
import java.util.Scanner;
public class ProbabilityAlgorithm {
static double MonteCarloPI(int n) {
double PI, x, y;
int sum = 0;
for (int i = 0; i < n; i++) {
x = Math.random(); // 产生 0~1 之间的一个随机数
y = Math.random();
// 点落在阴影区域
if (x * x + y * y <= 1)
sum++;
}
// π = 4 * 概率
PI = 4.0 * sum / n;
return PI;
}
public static void main(String[] args) {
System.out.println("蒙特卡罗算法求 π ...");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入点的数量(数量越大,π 的值越精确):");
int n = scanner.nextInt();
double PI = MonteCarloPI(n);
System.out.println("π = " + PI);
}
}
蒙特卡罗算法求 π ...
请输入点的数量(数量越大,π 的值越精确):100000000
π = 3.14146396
Process finished with exit code 0