1.汉诺塔问题
import javax.swing.JOptionPane;
public class Hanoi {
private static final String DISK_B = "diskB";
private static final String DISK_C = "diskC";
private static final String DISK_A = "diskA";
static String from=DISK_A;
static String to=DISK_C;
static String mid=DISK_B;
public static void main(String[] args) {
String input=JOptionPane.showInputDialog("please input the number of the disks you want me move.");
int num=Integer.parseInt(input);
move(num,from,mid,to);
}
private static void move(int num, String from2, String mid2, String to2) {
if(num==1){
System.out.println("move disk 1 from "+from2+" to "+to2);
}
else {
move(num-1,from2,to2,mid2);
System.out.println("move disk "+num+" from "+from2+" to "+to2);
move(num-1,mid2,from2,to2);
}
}
}
2. 这是一个排列的例子,它所做的工作是将输入的一个字符串中的所有元素进行排序并输出,例如:你给出的参数是"abc" 则程序会输出:
abc
acb
bac
bca
cab
cba
(1)算法的出口在于:low=high也就是现在给出的排列元素只有一个时。
(2)算法的逼近过程:先确定排列的第一位元素,也就是循环中i所代表的元素,
然后low+1开始减少排列元素,如此下去,直到low=high
public static void permute(String str) {
char[] strArray = str.toCharArray();
permute(strArray, 0, strArray.length - 1);
}
public static void permute(char[] list, int low, int high) {
int i;
if (low == high) {
String cout = "";
for (i = 0; i<= high; i++)
cout += list[i];
System.out.println(cout);
} else {
for (i = low; i<= high; i++) {
char temp = list[low];
list[low] = list[i];
list[i] = temp;
permute(list, low + 1, high);
temp = list[low];
list[low] = list[i];
list[i] = temp;
}
}
}
3。这是一个组合的例子,与上述的例子相似,只是它所做的工作是,输出所给字符串中制定数目的元素的组合种类
(1)程序出口在于n=1,此时只要输出目标数组的所有元素即可
(2)逼近过程,当n>1的时候,我们先取第一个元素放入目标数组中,然后n-1,如此下去,最后出来。
import javax.swing.JOptionPane;
public class Combination {
/**
* @param args
*/
public static void main(String[] args) {
String input = JOptionPane.showInputDialog("please input your String: ");
String numString = JOptionPane.showInputDialog("please input the number of your Combination: ");
int num = Integer.parseInt(numString);
Combine(input, num);
}
private static void Combine(String input, int num) {
char[] a = input.toCharArray();
String b = "";
Combine(a, num, b, 0, a.length);
}
private static void Combine(char[] a, int num, String b, int low, int high) {
if (num == 0) {
System.out.println(b);
} else {
for (int i = low; i<a.length; i++) {
b += a[i];
Combine(a, num - 1, b, i+1, a.length);
b=b.substring(0, b.length()-1);
}
}
}
}
⑵ java中递归算法是什么怎么算的
Java递归算法是基于Java语言实现的递归算法。递归算法是一种直接或者间接调用自身函数或者方法的算法。递归算法实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法表示问题的解。递归往往能给我们带来非常简洁非常直观的代码形式,从而使我们的编码大大简化,然而递归的思维确实跟我们的常规思维相逆的,通常都是从上而下的思维问题,而递归趋势从下往上的进行思维。
二、递归算法解决问题的特点:
【1】递归就是方法里调用自身。
【2】在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
【3】递归算法代码显得很简洁,但递归算法解题的运行效率较低。所以不提倡用递归设计程序。
【4】在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等,所以一般不提倡用递归算法设计程序。
【5】在做递归算法的时候,一定把握出口,也就是做递归算法必须要有一个明确的递归结束条件。这一点是非常重要的。其实这个出口就是一个条件,当满足了这个条件的时候我们就不再递归了。
三、代码示例:
代码执行流程图如下:
此程序中n=5就是程序的出口。
⑶ java 算法
//我自己写的,核心算法放在里面,你在加一个主类调一下就行了
//兄弟,我亲自测了,绝对可以
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
//计算组合的算法
public class CombinationClass {
public CombinationClass()
{
}
//对于任意n选m个元素,如果m==0,则此次排法结束,如果m不为0,那么在n个元素中选择m个元素就是要首先在n个元素中选出一个元素,然后
//在其他n-1个元素中选择m-1个元素。因此,对于每一个n来讲,它的任务就是,将当前传入的集合中填充上自己的信息,然后比较是否有其他
//集合与自己所在集合相等如果这个集合长度为0,则重新建立一个集合,然后再把集合传入到其他的数据中。
public ArrayList<HashSet> computeCombine(int cardinalNum, int ordinalNum,int[] numList, HashSet resultSet,ArrayList<HashSet> resultList)
{
//拷贝副本,而不能引用原来的HashSet
HashSet resultSetEnter = (HashSet)resultSet.clone();
//如果m==0则此次排法结束
if(ordinalNum == 0)
{ //完毕一种排法,把它添加到序列中
resultList.add(resultSetEnter);
return resultList;
}
if(numList.length != cardinalNum)
return null;
int newList[] = new int[numList.length - 1];
for(int i = 0; i < numList.length; i ++)
{
//每次随便在cardinalNum中取出一个数,打印出来,然后在在其余的cardinalNum-1个数中取ordinal-1次
//如果集合长度为0,则新建一个集合
HashSet resultSetCopy =(HashSet)resultSet.clone();
if(resultSetCopy.size() == 0)
resultSetCopy = new HashSet();
resultSetCopy.add(numList[i]);
//如果有其他集合与本集合相等,则返回
boolean result = false;
for(int k = 0; k < resultList.size(); k ++)
{
HashSet hashSet = resultList.get(k);
result = HashSetEqual(hashSet,resultSetCopy);
//如果有集合和该集合相等,则跳出循环
if(result == true)
break;
}
//如果有集合和该集合相等,则进行下一次循环
if(result == true)
continue;
//在该集合中添加入该元素
//删掉numList[i]
for(int j = 0;j<i;j++)
{
newList[j] = numList[j];
}
for(int j = i + 1; j <= numList.length - 1; j ++)
{
newList[j - 1] = numList[j];
}
computeCombine(cardinalNum - 1,ordinalNum - 1, newList,resultSetCopy, resultList);
}
return null;
}
public static boolean HashSetEqual(HashSet hashSet, HashSet resultSetCopy)
{ int equal = 1;
Iterator it = hashSet.iterator();
if(resultSetCopy.size() == hashSet.size()){
while(it.hasNext())
{
if(equal == 0)
break;
if(equal == 1){
equal = 0;
int num = ((Integer)it.next()).intValue();
Iterator it2 = resultSetCopy.iterator();
while(it2.hasNext())
{
int num2 = ((Integer)it2.next()).intValue();
if(num == num2){
equal = 1;
break;
}
}
}
}
if(equal == 1)
return true;
else
return false;
}
return false;
}
}
⑷ java有哪些垃圾回收算法
常用的垃圾回收算法有:
(1).引用计数算法:
给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器都为0的对象就是不再被使用的,垃圾收集器将回收该对象使用的内存。
引用计数算法实现简单,效率很高,微软的COM技术、ActionScript、Python等都使用了引用计数算法进行内存管理,但是引用计数算法对于对象之间相互循环引用问题难以解决,因此java并没有使用引用计数算法。
(2).根搜索算法:
通过一系列的名为“GC Root”的对象作为起点,从这些节点向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Root没有任何引用链相连时,则该对象不可达,该对象是不可使用的,垃圾收集器将回收其所占的内存。
主流的商用程序语言C#、java和Lisp都使用根搜素算法进行内存管理。
在java语言中,可作为GC Root的对象包括以下几种对象:
a. java虚拟机栈(栈帧中的本地变量表)中的引用的对象。
b.方法区中的类静态属性引用的对象。
c.方法区中的常量引用的对象。
d.本地方法栈中JNI本地方法的引用对象。
java方法区在Sun HotSpot虚拟机中被称为永久代,很多人认为该部分的内存是不用回收的,java虚拟机规范也没有对该部分内存的垃圾收集做规定,但是方法区中的废弃常量和无用的类还是需要回收以保证永久代不会发生内存溢出。
判断废弃常量的方法:如果常量池中的某个常量没有被任何引用所引用,则该常量是废弃常量。
判断无用的类:
(1).该类的所有实例都已经被回收,即java堆中不存在该类的实例对象。
(2).加载该类的类加载器已经被回收。
(3).该类所对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射机制访问该类的方法。
Java中常用的垃圾收集算法:
(1).标记-清除算法:
最基础的垃圾收集算法,算法分为“标记”和“清除”两个阶段:首先标记出所有需要回收的对象,在标记完成之后统一回收掉所有被标记的对象。
标记-清除算法的缺点有两个:首先,效率问题,标记和清除效率都不高。其次,标记清除之后会产生大量的不连续的内存碎片,空间碎片太多会导致当程序需要为较大对象分配内存时无法找到足够的连续内存而不得不提前触发另一次垃圾收集动作。
(2).复制算法:
将可用内存按容量分成大小相等的两块,每次只使用其中一块,当这块内存使用完了,就将还存活的对象复制到另一块内存上去,然后把使用过的内存空间一次清理掉。这样使得每次都是对其中一块内存进行回收,内存分配时不用考虑内存碎片等复杂情况,只需要移动堆顶指针,按顺序分配内存即可,实现简单,运行高效。
复制算法的缺点显而易见,可使用的内存降为原来一半。
(3).标记-整理算法:
标记-整理算法在标记-清除算法基础上做了改进,标记阶段是相同的标记出所有需要回收的对象,在标记完成之后不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,在移动过程中清理掉可回收的对象,这个过程叫做整理。
标记-整理算法相比标记-清除算法的优点是内存被整理以后不会产生大量不连续内存碎片问题。
复制算法在对象存活率高的情况下就要执行较多的复制操作,效率将会变低,而在对象存活率高的情况下使用标记-整理算法效率会大大提高。
(4).分代收集算法:
根据内存中对象的存活周期不同,将内存划分为几块,java的虚拟机中一般把内存划分为新生代和年老代,当新创建对象时一般在新生代中分配内存空间,当新生代垃圾收集器回收几次之后仍然存活的对象会被移动到年老代内存中,当大对象在新生代中无法找到足够的连续内存时也直接在年老代中创建。
⑸ 常用的算法在java里边怎么做,例
(一) 问题描述
给定由n个整数(可能为负整数)组成的序列a1,a2,a3,···,an,求该序列的子段和的最大值。当所有整数均为负整数是定义其最大子段和为0,一次定义,所求的最优质值为:max{0、max子段和}。
(二) 算法描述
动态规划法的基本思想:
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。
算法设计:
#include "stdafx.h"
int MaxSum(int a[],int n,int &Start,int&End){
intsum=0;
int*b,t;
b=newint[n+1];
b[0]=0;
for(inti=1;i<=n;i++){
if(b[i-1]>0){
b[i]=b[i-1]+a[i];
}
else {
b[i]=a[i];t=i;
}
if(b[i]>sum){
sum=b[i];
Start=t;
End=i;
}
}
delete[]b;
returnsum;
}
int main(int argc, char* argv[])
{
inta[7]={0,-2,11,-4,13,-5,-2},sum,Start,End,i;
sum=MaxSum(a,6,Start,End);
for(i=Start;i<=End;i++){
printf("%d ",a[i]);
}
printf("\n%d\n",sum);
getchar();
getchar();
return0;
⑹ java算法有哪些分别
您好:
java中的算法,常见的有:递归、迭代、查找、排序(包含冒泡排序、选择排序、插入排序、快速排序四种) 等,算法有很多,一般数据结构中涉及到的都可以用java语言实现。
举几个例子:
1.递归的例子:
不一一举例,仅供参考!
⑺ Java的数组的几种经典算法
JAVA中在运用数组进行排序功能时,一般有四种方法:快速排序法、冒泡法、选择排序法、插入排序法。
快速排序法主要是运用了Arrays中的一个方法Arrays.sort()实现。
冒泡法是运用遍历数组进行比较,通过不断的比较将最小值或者最大值一个一个的遍历出来。
选择排序法是将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。
插入排序是选择一个数组中的数据,通过不断的插入比较最后进行排序。下面我就将他们的实现方法一一详解供大家参考。
<1>利用Arrays带有的排序方法快速排序
public class Test2{ public static void main(String[] args){ int[] a={5,4,2,4,9,1}; Arrays.sort(a); //进行排序 for(int i: a){ System.out.print(i); } } }
<2>冒泡排序算法
public static int[] bubbleSort(int[] args){//冒泡排序算法 for(int i=0;i<args.length-1;i++){ for(int j=i+1;j<args.length;j++){ if (args[i]>args[j]){ int temp=args[i]; args[i]=args[j]; args[j]=temp; } } } return args; }
<3>选择排序算法
public static int[] selectSort(int[] args){//选择排序算法 for (int i=0;i<args.length-1 ;i++ ){ int min=i; for (int j=i+1;j<args.length ;j++ ){ if (args[min]>args[j]){ min=j; } } if (min!=i){ int temp=args[i]; args[i]=args[min]; args[min]=temp; } } return args; }
<4>插入排序算法
public static int[] insertSort(int[] args){//插入排序算法 for(int i=1;i<args.length;i++){ for(int j=i;j>0;j--){ if (args[j]<args[j-1]){ int temp=args[j-1]; args[j-1]=args[j]; args[j]=temp; }else break; } } return args; }
⑻ java中的算法,一共有多少种,哪几种,怎么分类。
就好比问,汉语中常用写作方法有多少种,怎么分类。
算法按用途分,体现设计目的、有什么特点
算法按实现方式分,有递归、迭代、平行、序列、过程、确定、不确定等等
算法按设计范型分,有分治、动态、贪心、线性、图论、简化等等
作为图灵完备的语言,理论上”Java语言“可以实现所有算法。
“Java的标准库'中用了一些常用数据结构和相关算法.
像apache common这样的java库中又提供了一些通用的算法
⑼ java排序算法哪些
排序算法有很多,从简单的开始说吧,
如冒泡:
for (int i = 0; i < nums1.length-1; i++) {
for (int j = 0; j < nums1.length-i-1; j++) {
if(nums1[j] > nums1[j+1]){
int temp = nums1[j];
nums1[j] = nums1[j + 1];
nums1[j + 1] = temp;
}
}
}
选择:
for (int i = 0; i < nums.length; i++) {
int min= nums[i];
int minIndex = i;//记录要交换元素的下标
for (int j = i + 1; j < nums.length; j++) {//内循环找最小值
if(min > nums[j]){
min = nums[j];
minIndex = j;
}
}
int temp = nums[i];
nums[i] = nums[minIndex];
nums[minIndex] = temp;
}
快速排序等等。
java中如果数组排序,可以直接用Arrays.sort();
⑽ java最常用的几种加密算法
简单的Java加密算法有:
第一种. BASE
Base是网络上最常见的用于传输Bit字节代码的编码方式之一,大家可以查看RFC~RFC,上面有MIME的详细规范。Base编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base来将一个较长的唯一标识符(一般为-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base编码具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
第二种. MD
MD即Message-Digest Algorithm (信息-摘要算法),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD的前身有MD、MD和MD。
MD算法具有以下特点:
压缩性:任意长度的数据,算出的MD值长度都是固定的。
容易计算:从原数据计算出MD值很容易。
抗修改性:对原数据进行任何改动,哪怕只修改个字节,所得到的MD值都有很大区别。
弱抗碰撞:已知原数据和其MD值,想找到一个具有相同MD值的数据(即伪造数据)是非常困难的。
强抗碰撞:想找到两个不同的数据,使它们具有相同的MD值,是非常困难的。
MD的作用是让大容量信息在用数字签名软件签署私人密钥前被”压缩”成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD以外,其中比较有名的还有sha-、RIPEMD以及Haval等。
第三种.SHA
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于^位的消息,SHA会产生一个位的消息摘要。该算法经过加密专家多年来的发展和改进已日益完善,并被广泛使用。该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。散列函数值可以说是对明文的一种“指纹”或是“摘要”所以对散列值的数字签名就可以视为对此明文的数字签名。
SHA-与MD的比较
因为二者均由MD导出,SHA-和MD彼此很相似。相应的,他们的强度和其他特性也是相似,但还有以下几点不同:
对强行攻击的安全性:最显着和最重要的区别是SHA-摘要比MD摘要长 位。使用强行技术,产生任何一个报文使其摘要等于给定报摘要的难度对MD是^数量级的操作,而对SHA-则是^数量级的操作。这样,SHA-对强行攻击有更大的强度。
对密码分析的安全性:由于MD的设计,易受密码分析的攻击,SHA-显得不易受这样的攻击。
速度:在相同的硬件上,SHA-的运行速度比MD慢。
第四种.HMAC
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。