求从 1,2,...,N 这N个不同数字中任取 r 个数字的全部的组合和排列.n,r从键盘输入要求:使用Java完成本课题的程序设计,至少定义2个类。

解决方案 »

  1.   

    尝试写了排列组合的代码,从键盘输入的部分就lz自己完成吧代码使用了接口,内部类,可能比较复杂,lz根据情况改写吧/** 接口,根据索引数组输出一组对象。*/
    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);
    }
    }