求从 1,2,...,N 这N个不同数字中任取 r 个数字的全部的组合和排列.n,r从键盘输入要求:使用Java完成本课题的程序设计,至少定义2个类。
解决方案 »
- 想匹配2个文件A B的字符串,输出不同的行数。实现不了
- java2d的缩放问题
- 怎么从1到10 中产生随机数,不能重复产生,直到1到10 个数字都全部列出来为止
- 請問一下程序中的System.gc()代錶什么?????
- 求助:关于IBM的AGLET,出现错误
- 为什么String str1 = "abc";String str2= "abc";中的str1和str2是相同的?
- 继“关于java socket的问题”
- 我想在applet中使用java.swing.tree控件,不知道是否applet支持swing控件?
- 关于Jbuilder5中JDataStore的注册问题(一定给分!!!!!)
- 请问:我的tomcat出了什么问题?来者有分!!!
- 你能回答吗?谢谢了
- 关于 java StdDraw library
interface OutputMethod {
void action(final int[] indexes);
}
/** 实现了OutputMethod接口的用于输出自然数的类 */
class NumberOutput implements OutputMethod {
public void action(final int[] indexes) {
System.out.print("[");
for(int i:indexes) System.out.print(" "+(i+1));
System.out.println(" ]");
}
}/**
* 全排列,P(n,n)表示n个数的全排列。<br>
* 全排列序列的输出,采用递归算法
*/
class CompletePermutation {
private final int n;
private OutputMethod method;
private int[] arrIndexes;
public CompletePermutation(int n) {
this.n = n;
if (n>0) {
arrIndexes = new int[n];
}
}
/** 初始化函数,重新求序列之前需要调用该函数 */
private void initIndexes() {
for(int i=0; i<n; i++)
arrIndexes[i]=i;
}
/** 交换列表中的两个元素 */
private void swapIndexes(int i, int j) {
if(i != j) {
int temp=arrIndexes[i];
arrIndexes[i]=arrIndexes[j];
arrIndexes[j]=temp;
}
}
/**
* 递归求取全排列的排列顺序.
* @param i 当前递归到了哪个元素
*/
private void getPermutationArray(int i) {
if (i == n) {
method.action(arrIndexes);
} else {
for(int j=i; j<n; j++) {
swapIndexes(i, j);
getPermutationArray(i+1);
swapIndexes(i, j);
}
}
}
/**
* 输出全排列的所有序列,输出方法由method决定
* @param method 外部指定的输出方法
*/
public void printResultSet(final OutputMethod method) {
initIndexes();
this.method = method;
getPermutationArray(0);
}
}/**
* 组合,C(m,r)表示m个数中取r个的组合。 <br>
* 维护当前索引数组,从最后一个索引开始修改,不断产生新数组
*/
class Combination {
private final int n, r;
private int[] maxIndexes;
private int[] curIndexes;
public Combination(int n, int r) {
this.n = n;
this.r = r;
if(r<=n && r>0){
curIndexes = new int[r];
maxIndexes = new int[r];
}
}
/** 初始化函数,重新求序列之前需要调用该函数 */
private void initIndexes() {
for(int i=0; i<r; i++)
curIndexes[i]=i;
for(int i=0; i<r; i++)
maxIndexes[i]=n-r+i;
}
/**
* 根据当前组合索引序列获取下一个序列
* @return true,获取成功; false,获取失败
*/
private boolean GetNextArray( ) {
int count=r;
int[] curIdx = curIndexes;
int[] maxIdx = maxIndexes;
if( curIdx[count-1] < maxIdx[count-1] ) {
curIdx[count-1]++;
return true;
} else {
for( int i=count-2; i>=0; i-- ) {
if( curIdx[i] < maxIdx[i] ) {
++ curIdx[i];
for( int j=i+1; j<count; j++ ) {
curIdx[j]=curIdx[j-1]+1;
}
return true;
}
}
}
return false;
}
/**
* 显示符合条件的序列,组合数类只实现了索引,具体如何显示由传入的method决定
* @param method 输出方法,决定序列如何输出
*/
public void printResultSet(final OutputMethod method) {
if( r<=0 || r>n ) {
System.out.println("Invalid params.");
return ;
}
initIndexes();
do {
method.action(curIndexes);
} while(GetNextArray());
}
}/**
* 排列,P(n,r)表示从n个元素中取r个的排列 <br>
* 这个类继承至组合,对每个组合进行全排列,得到了所有排列
*/
class Permutation extends Combination {
CompletePermutation completePerm;
public Permutation(int n, int r) {
super(n, r);
completePerm = new CompletePermutation(r);
}
/**
* 输出序列,重载了父类方法;通过组合索引与全排列索引,得到排列索引
*/
public void printResultSet(final OutputMethod method) {
super.printResultSet(new OutputMethod(){
public void action(final int[] combIdx) {
completePerm.printResultSet(new OutputMethod(){
public void action(final int[] permIdx){
int[] realIdx = new int[combIdx.length];
for(int i=0; i<realIdx.length; i++)
realIdx[i] = combIdx[permIdx[i]];
method.action(realIdx);
}
});
}
});
}
}/**
* 对排列组合类进行简单测试
*/
public class MathTest {
public static void main(String[] args) {
NumberOutput numOut = new NumberOutput();
System.out.println("C(6,3) is shown:");
new Combination(6,3).printResultSet(numOut);
System.out.println("P(4,3) is shown:");
new Permutation(4,3).printResultSet(numOut);
}
}