`
liuqing_2010_07
  • 浏览: 59684 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

经典算法问题的java实现<二>

阅读更多
1.数值转换(System Conversion)
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;
}


参照资料:http://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97#.E6.87.89.E7.94.A8

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);
}

}

  有兴趣的读者可以参照以下连接,去研究八皇后算法。
  • 大小: 8.9 KB
  • 大小: 2.5 KB
  • 大小: 31.4 KB
  • 大小: 10.2 KB
  • 大小: 4.7 KB
  • 大小: 13.1 KB
  • 大小: 9.8 KB
3
1
分享到:
评论
1 楼 huchuhan 2013-04-16  
非常感谢 挺厉害的.

相关推荐

    经典算法问题的java实现<一>

    NULL 博文链接:https://liuqing-2010-07.iteye.com/blog/1396859

    Genetic Algorithm遗传算法java GUI应用

    可以导入eclipse直接运行,具有一定的界面。项目情况:完成一次的遗传算法迭代。

    jive.chm

    &lt;br&gt; 3 在java中编程实现数字签名系统 &lt;br&gt; 4 关于Jive1中的验证和相关类的调用 &lt;br&gt;&lt;br&gt; 5 MD5的加密算法(JavaScript) &lt;br&gt;&lt;br&gt; &lt;br&gt; &lt;br&gt;产品介绍&lt;br&gt; 1 Jive简介 &lt;br&gt;&lt;br&gt; Jive Forums&lt;br&gt; 1 Jive Forums特性 &lt;br...

    <原创>java实现的ID3决策树算法改良版

    &lt;原创&gt;java实现的ID3决策树算法改良版,可以随意改变数据源(符合格式就行)

    java实现弗洛伊德算法 经典java实现弗洛伊德算法 经典

    java实现弗洛伊德算法 经典java实现弗洛伊德算法 经典java实现弗洛伊德算法 经典java实现弗洛伊德算法 经典java实现弗洛伊德算法 经典

    hadoop k-means算法实现(可直接命令行运行)

    hadoop k-means算法实现java工程的打包类,可直接在terminal中运行,运行命令为: $HADOOP_HOME/bin/hadoop jar ClusterDemo.jar main.Cluster 然后直接确定就可以看到提示的运行参数或者参考下面: +"&lt;input&gt; ...

    java实现排序算法

    java实现七种排序算法

    Java实现货郎担问题

    用佳点集实现遗传算法,解决货郎担问题,也就是Tsp问题,整个程序用Java实现,为便于学习,程序添加了详尽的注释,以及Javadoc帮助文档。整个程序只注重算法本身,没有添加任何包括图形界面在内的影响阅读的代码。...

    JavaClass二进制文件加密专家

    &lt;br&gt; JavaClass文件加密专家通过分析Class文件的结构,将Class二进制代码中耗时较多的部份抽出并替换为Native C代码,&lt;br&gt;并且使用1024位加密算法将Class文件数据加密,任何Java反编译工具均不可能对加密后的文件...

    JAVA规则引擎原理

    &lt;br&gt;&lt;br&gt;第一部分简要介绍了规则引擎的产生背景和基于规则的专家系统,&lt;br&gt;第二部分介绍了什么是规则引擎及其架构和算法,&lt;br&gt;第三部分介绍了商业产品和开源项目实现等各种Java规则引擎,&lt;br&gt;第四部分对Java规则引擎...

    经典算法 C语言和Java实现

    经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法 C语言和Java实现经典算法...

    Java实现随机森林算法

    在Java中实现随机森林算法通常需要使用机器学习库,比如Weka或者Apache Spark的MLlib。下面我将展示一个使用Weka库的简单示例,来说明如何使用随机森林算法对数据进行分类。 首先,你需要在项目中引入Weka库。如果...

    经典算法的Java实现.zip

    经典算法Java实现,排序等

    几个推荐算法的java实现

    java实现的几个推荐算法:slopeone SVD,RSVD,ItemNeighborSVD 内有readme,相关内容在blog.csdn.net/lgnlgn

    java编写的递归下降分析器

    1、使用递归下降分析算法分析表达式文法:&lt;br&gt;exp ::= exp addop term | term&lt;br&gt;addop ::= + | -&lt;br&gt;term ::= term mulop factor | factor&lt;br&gt;mulop ::= * | /&lt;br&gt;factor ::= (exp) | number&lt;br&gt;其中number可以是多...

    BP算法的java实现

    BP算法的JAVA实现,BP神经网络的数学原理及其算法实现,实验使用IRIS数据集,BP神经网络,BP即Back Propagation的缩写,也就是反向传播的意思,顾名思义,将什么反向传播?文中将会解答。不仅如此,关于隐层的含义...

    关联规则算法实现 java

    1、基于模拟数据集,实现Apriori算法以获得频繁项集。&lt;br&gt;2、基于上一步得到的频繁项集,编写算法得到关联规则。&lt;br&gt;3.有文档,源代码在文档中,与jar包

    java中的经典算法经典算法

    java经典算法java经典算法java经典算法java经典算法java经典算法java经典算法

Global site tag (gtag.js) - Google Analytics