`
liuqing_2010_07
  • 浏览: 60596 次
  • 性别: 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实现<一>

    在本资源中,我们关注的是"经典算法问题的java实现&lt;一&gt;",这通常涉及到计算机科学中的基础算法,特别是那些用Java编程语言实现的。这些算法是解决各种计算问题的关键,包括排序、搜索、图论、动态规划等。Java作为一...

    Genetic Algorithm遗传算法java GUI应用

    在"Genetic Algorithm遗传算法java GUI应用&lt;一&gt;"这个项目中,开发者已经完成了一个能够运行于Eclipse环境下的遗传算法实例。该程序具有一个基本的GUI界面,用户可以通过此界面观察算法的执行过程和结果。GA的过程...

    25个经典Spark算子的JAVA实现

    根据给定文件的信息,本文将详细介绍25个经典Spark算子的Java实现,并结合详细的注释及JUnit测试结果,帮助读者更好地理解Spark算子的工作原理及其应用方式。 ### Spark算子简介 在Apache Spark框架中,算子是用于...

    Java实现随机森林算法

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

    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...

    Russell And Norvig 的《人工智能 - 一种现代方法》中的算法的 Java 实现.zip

    Maven 信息(用于作为第三方库集成)&lt;dependency&gt; &lt;groupId&gt;com.googlecode.aima-java&lt;/groupId&gt; &lt;artifactId&gt;aima-core&lt;/artifactId&gt; &lt;version&gt;3.0.0&lt;/version&gt;&lt;/dependency&gt;已实现算法的索引数字 页 名称(第 3版...

    jLuhn:Luhn算法的Java实现

    Luhn算法的Java实现 将jLuhn添加到您的项目 玛文 添加以下存储库: &lt;repositories&gt; &lt;repository&gt; &lt;id&gt;jitpack.io&lt;/id&gt; &lt;url&gt;https://jitpack.io&lt;/url&gt; &lt;/repository&gt; &lt;/repositories&gt; 和以下依赖项: ...

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

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

    经典算法的Java实现.zip

    除了上述内容,这个压缩包可能还包含了其他经典算法的Java实现,如二分查找、图的深度优先搜索(DFS)和广度优先搜索(BFS)、动态规划等。二分查找是一种在有序数组中查找特定元素的搜索算法,其时间复杂度为O(log ...

    java实现排序算法

    Java作为广泛应用的编程语言,提供了一种高效的方式来实现各种排序算法。本文将深入探讨七种常见的排序算法及其在Java中的实现。 1. 冒泡排序(Bubble Sort) 冒泡排序是一种简单的排序算法,它重复地遍历待排序的...

    几个推荐算法的java实现

    本项目提供了一些推荐算法的Java实现,包括slopeone、SVD(奇异值分解)以及基于物品邻接的SVD(ItemNeighborSVD)。下面我们将详细探讨这些算法及其在Java中的实现。 1. **slopeone**: - Slope One是一种简单的...

    Java实现货郎担问题

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

    JavaClass二进制文件加密专家

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

    JAVA二维码算法实现

    以上就是使用Java实现二维码算法的基本流程。在实际应用中,我们可能还需要处理各种异常,优化二维码的尺寸、颜色、容错级别等参数,以及考虑在移动设备上的使用场景。这两个标签“QR码”和“JAVA”代表了这个主题的...

    利用 First Fit 算法解决物流3D bin packing问题 Java实现

    本文将详细介绍First Fit算法以及其Java实现的关键点。 First Fit算法的基本思想是:对于每个待装物品,尝试将其放入当前可用的最小容积的箱子里。如果找不到合适的箱子,就创建一个新的箱子。这个策略相对简单,但...

    装载问题-分支限界算法-java实现

    装载问题-分支限界算法-java实现 装载问题 装载问题是一种经典的组合优化问题,目的是在有限的容量内装载尽可能多的物品,以达到最大化总重量或总价值。装载问题有多种变种,包括0/1背包问题、分支限界问题、动态...

    经典算法 C语言和Java实现

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

    TFIDF算法 java实现

    ### TF-IDF算法Java实现详解 #### 一、算法简介 TF-IDF(Term Frequency-Inverse Document Frequency)是一种常用于信息检索与文本挖掘中的权重计算公式。它通过统计单词在文档中出现的频率以及在整个文集中的频率...

Global site tag (gtag.js) - Google Analytics