经典算法问题的java实现 (二)
1.1 r进制数
数N的r进制可以表示为:
1.2 十进制转换为r进制
十进制数N和其他r进制数的转换是计算机实现计算的基本问题,基解决方案很多,其中一个简单算法基于下列原理:
N = (N div d) * r + N mod r (其中: div为整除运算,mod为求余运算)
问题:如何将非负十进制(Decimal)整数转化为八进制数(Octonary Number)?
将十进制转化为r进制:
- /**
- * 非负十进制整数转换为r进制数
- * @param n 待转换的十进制数
- * @param r 进制数(基数)
- * @return 返回转换后对应r进制数各位数字。
- */
- byte [] dec2RNumber(int n,byte r) {
- if(n < 0 || r < 0) {
- throw new IllegalArgumentException(" the parameter is valid!");
- }
- Stack<Byte> s = new Stack<Byte>();
- while( n != 0){
- s.push(Byte.valueOf((byte) (n%r)));//求余
- n = n/r;//求商
- }
- byte [] rr = new byte[s.size()];
- for (int i = 0; i < rr.length; i++) {
- rr[i] = s.pop();
- }
- return rr;
- }
十进制非负整数转换为八进制:
- dec2RNumber(1348,8)
2.斐波那契数列(Fibonacci Sequence)
2.1 斐波那契数列是以递归的方法来定义:
斐波那契数列是从第0项和第1项开始,之后的项等于其前面相邻两项之和。
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946,......
2.2 兔子生育问题:
- 第一个月初有一对刚诞生的兔子
- 第二个月之后(第三个月初)它们可以生育
- 每月每对可生育的兔子会诞生下一对新兔子
- 兔子永不死去
2.3 兔子问题的分析:
斐波那契数列的java非递归实现:
- int Fibs(int n) {
- if(n < 0) {
- throw new IllegalArgumentException(" the parameter is valid!");
- }
- int n1 = 0;//F(n-2)
- int n2 = 1;//F(n-1)
- int r = n1;//F(n)
- if(n == 1) {
- r = n2;
- }
- for (int i = 2; i <= n; i++) {
- r = n1 + n2 ;//F(n)=F(n-1)+F(n-2)
- n1 = n2;
- n2 = r;
- }
- return r;
- }
3.秦九韶算法求一元n次多项式的值(Compute Polynomial's value)
3.1 秦九韶算法介绍:
秦九韶算法是中国南宋时期的数学家秦九韶提出的一种多项式简化算法。在西方被称作霍纳算法。
秦九韶算法:
一般地,一元n次多项式的求值需要经过[n(n+2)]/2次乘法和n次加法,而从上面的演算可以看出秦九韶算法只需要n次乘法和n次加法。极大地降低了算法复杂度。
参照:http://zh.wikipedia.org/wiki/%E9%9C%8D%E7%B4%8D%E6%BC%94%E7%AE%97%E6%B3%95
3.2 秦九韶算法实现:
- /**
- * 秦九绍算法求一元n次多项式的值
- * f(x) = a[0]*x^n + a[1]*x^(n-1) + ... + a[n]
- * @param a 系数
- * @param x 基数
- * @return
- */
- double qinjiushao(double [] a ,double x) {
- double v = a[0];
- for (int i = 1; i < a.length; i++) {
- v = v * x + a[i];
- }
- return v;
- }
3.3 秦九韶算法应用:
在Java中字符串的hashcode计算中就用到了秦九韶算法。其中基数为31(质数),系数为字符串对应的ASCII值。
- public int hashCode() {
- int h = hash;
- if (h == 0) {
- int off = offset;
- char val[] = value;
- int len = count;
- for (int i = 0; i < len; i++) {
- h = 31*h + val[off++];
- }
- hash = h;
- }
- return h;
- }
测试:
- System.out.println("abc".hashCode());
- 结果:96354 = ax^2 + bx +c //其中( [a,b,c]=[97,98,99];x =31)
- = 97 * 961 + 98 * 31 +99
4.全排列(Full Permutation)
从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。
问题:给定字符串S,生成该字符串的全排列。
以上全排列的算法采用了交换,回溯,递归的方法。
参照地址:http://www.haogongju.net/art/37504
- int count = 0;//统计字符串的全排列数目
- int len = 0;//字符串的长度
- /**
- * 字符串的全排列算法。
- * @param c字符串对应的字符数组
- * @param start 起始位置
- */
- void fullPermutation(char[] c, int start ) {
- if(start == len){
- count++;
- System.out.println(new String(c));//打印当前排列
- } else {
- char temp=' ';
- boolean bool = false;
- for(int i = start; i < c.length; i++){
- bool = (i != start); //i与start相等时不交换。
- //为避免生成重复排列,当不同位置的字符相同时不再交换
- if(bool && c[i] == c[start]) {
- continue;
- }
- if(bool) {//交换
- temp = c[start];
- c[start] = c[i];
- c[i] = temp;
- }
- fullPermutation(c, start + 1);//递归
- if(bool) {//回溯
- c[i] = c[start];
- c[start] = temp;
- }
- }
- }
- }
- /**
- * 测试全排列
- * @param s
- */
- void testFullPermutation(String s) {
- count = 0;
- len = s.length() -1;
- long t1 = Calendar.getInstance().getTimeInMillis();
- fullPermutation(s.toCharArray(), 0);
- long t2 = Calendar.getInstance().getTimeInMillis();
- System.out.println("全排列数:"+count);
- System.out.println("耗时:"+(t2-t1)+"ms");
- }
5.八皇后问题(Eight Queens)
八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法?
上图为八皇后问题的一个例子。
八皇后问题的java实现如下。该算法支持n皇后。当n>=16以后计算时间会很长。
- import java.util.Calendar;
- public class EightQueens {
- //统计解的个数
- int count ;
- //皇后数
- static int N = 8;
- //记录皇后的位置,x[i]表示皇后i放在棋盘的第i行的第x[i]列
- int [] X = new int[N];
- /**
- * 测试皇后k在第k行第x[k]列时是否与前面已放置好的皇后相攻击.
- * (X[j] == X[k]时,两皇后在同一列上,
- * k-j == Math.abs(X[j] - X[k])时,两皇后在同一斜线上。
- * @param k
- * @return
- */
- boolean check(int k) {
- for (int row = 0; row < k; row ++) {
- if ((X[row] == X[k] || k-row == Math.abs(X[row] - X[k]))) {
- return false ;
- }
- }
- return true;
- }
- /**
- * 回溯求皇后的放置方案。
- * 对于八皇后t的最大值为8.
- * @param row row -> [0,1,2,3,4,5,6,7,8]
- */
- void backtrack(int row) {
- //row == N 时,算法搜索至叶结点,得到一个新的N皇后互不攻击的放置方案
- if(row == N) {
- count++;
- printQueen();
- } else {
- for (int col = 0; col < N; col++) {
- X[row] = col;//第row行的皇后放在col列上
- if(check(row)) {//放置成功再放row+1行的
- backtrack(row+1);
- }
- }
- }
- }
- /**
- * 打印皇后
- */
- void printQueen() {
- System.out.println("==================第"+count+"种皇后图==================");
- for (int row = 0; row < N; row++) {
- for (int col = 0; col < N; col++) {
- if (col == X[row]) {
- System.out.print("@ ");
- } else {
- System.out.print("* ");
- }
- }
- System.out.println();
- }
- }
- /**
- * @param args
- */
- public static void main(String[] args) {
- EightQueens queen = new EightQueens();
- long t1 = Calendar.getInstance().getTimeInMillis();
- //从0开始回溯
- queen.backtrack(0);
- long t2 = Calendar.getInstance().getTimeInMillis();
- //打印花费的时间。
- System.out.println("花费:"+(t2-t1)+"ms");
- //打印方案总数
- System.out.println(queen.count);
- }
- }
有兴趣的读者可以参照以下连接,去研究八皇后算法。
- http://www.animatedrecursion.com/advanced/the_eight_queens_problem.html
- http://www.durangobill.com/N_Queens.html
- http://jsomers.com/nqueen_demo/nqueens.html
- http://www.math.utah.edu/~alfeld/queens/queens.html
- http://bridges.canterbury.ac.nz/features/eight.html
- http://c2.com/cgi/wiki?EightQueensInManyProgrammingLanguages
- http://baike.baidu.com/view/698719.htm
- EightQueens.rar (1018 Bytes)
- 下载次数: 23
- TypicalCode1.rar (1.5 KB)
经典算法问题的java实现 (二)的更多相关文章
- 经典算法问题的java实现 (一)
原文链接: http://liuqing-2010-07.iteye.com/blog/1396859 1.如何计算闰年(Leap Year)? 四年一闰:百年不闰:四百年再闰. 具体参照 ...
- 经典算法--冒泡排序(Java)
原理:将相邻元素的较大值赋给右边 思路:① 1.将集合或数组内的第一个元素与第二个元素进行比较,较大值赋给右边: 2.将第二个元素与第三个元素进行比较,较大值赋给右边: ....... (N-1).将 ...
- JAVA经典算法40题及解答
JAVA经典算法40题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...
- Java经典算法四十例编程详解+程序实例
JAVA经典算法40例 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程 ...
- JAVA经典算法40题
1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...
- JAVA经典算法40题(原题+分析)之分析
JAVA经典算法40题(下) [程序1] 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析: ...
- JAVA经典算法40题(原题+分析)之原题
JAVA经典算法40题(上) [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [程 ...
- JAVA经典算法50题(转)
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51097928 JAVA经典算法50题 [程序1] 题目:古典问题:有一对兔子, ...
- JAVA经典算法40题面向过程
JAVA经典算法40题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...
随机推荐
- 11.8Django中的组件content_type
2018-11-8 18:59:11 在Django中已经有一个contenttype这个组件,并且在python manage.py makemigrations 和migrate的时候,一起在数据 ...
- mybatis14--注解的配置
去掉对应的mapper映射文件 在dao文件中增加注解 public interface StudentDao { /** * 新增学生信息 */ @Insert(value="insert ...
- 20.react库 入门
vue插件: 使用方式:Vue.use(插件名称); {}/function 1.对象 export default { install(Vue,options){ } } 2.函数 export d ...
- 20175320 2018-2019-2 《Java程序设计》第5周学习总结
20175320 2018-2019-2 <Java程序设计>第5周学习总结 教材学习内容总结 本周学习了教材的第六章的内容.在这章中介绍了接口与实现,着重讲了接口是如何定义并实现以及如何 ...
- C++标准模板库之vector
vector(向量容器),是 C++ 中十分有用一个容器.它能够像容器一样存放各种类型的对象,vector 是一个能够存放任意类型(类型可以是int, double, string, 还可以是类)的动 ...
- 1.7Oob 方法重载和成员变量,局部变量,构造方法
1:方法调用,如果值有参方法,必须传递实际参数. 2:方法定义了多少个参数,传递的实际参数就 必须有多少个, 方法的作用:1:描述某个类的作用,2:软件的复用 这个复用率低,作用小,价值很低: 3:
- nginx配置框架问题
1.框架源文件没有引入 2.nginx fastcgi.conf配置允许访问上级目录地址 3.使用autoindex on;参数
- office 2016密钥
Office 2016 Pro Plus Retail 版激活密钥:[Key]:3XJTG-YNBMY-TBH9M-CWB2Y-YWRHH[Key]:6TCQ3-NBBJ2-RTJCM-HFRKV-G ...
- python 发送无附件邮件
import smtplibimport tracebackfrom email.mime.text import MIMETextfrom config.config import * ...
- C语言中tm结构体
struct tm { int tm_sec; /* Seconds. [0-60] (1 leap second) */ int tm_min; /* Minutes. [0-59] */ int ...