62,620
社区成员
发帖
与我相关
我的任务
分享
import java.util.ArrayList;
public class Sort {
/**
* 回溯法:
* 从1到X这X个数字中选出N个,排成一列,相邻两数不能相同,
* 求所有可能的排法。每个数可以选用零次、 一次或多次。
* 例如,当N=3、X=3时,排法有12种:
* 121、123、131、132、212、213、231、232、312、313、321、323
*/
public static void main(String[] args) {
int X=5;
int N=4;
//要求解数组
int[] src=new int[X];
//标记数组table[index]=false表示index位置的元素可以选用,true则为已被占用
//主要解决相同元素不能相邻的问题
boolean[] table=new boolean[src.length];
//存放结果List
ArrayList<Integer> resArrayList = new ArrayList<Integer>();
//初始化数组
initArray(src, src.length);
//回溯法遍历求解
SortArray(src, table, N, resArrayList, 0);
}
public static int initArray(int[] srcArray,int X)
{
//初始化目标数组 1...X
if(srcArray.length!=X)
{
return -1;
}
for(int i=0;i<X;i++)
{
srcArray[i]=i+1;
}
return 0;
}
public static void SortArray(int[] srcArray,boolean[] signTable,int N,ArrayList<Integer> resList,int deep)
{
//当遍历到达叶子节点(一次深度搜索已完成) 打印结果
if(deep==N)
{
for(int tI=0;tI<resList.size();tI++)
{
System.out.print(resList.get(tI)+" ");
}
System.out.println();
return ;
}else{
//备份标记数组
boolean[] mySignTable=new boolean[signTable.length];
System.arraycopy(signTable, 0, mySignTable, 0, signTable.length);
if(deep>1)
{
//恢复上上次所选可选性
//及为了保证儿子节点和双亲节点不能相同
mySignTable[resList.get(deep-2)-1]=false;
}
for(int i=0;i<mySignTable.length;i++)
{
//找到第一个为false元素 当做双亲节点
int index=sreachZero(mySignTable,i);
if(index!=-1)
{
//下次以此flase元素为起点查找下一个false元素
//及查找此节点的兄弟节点
i=index;
//第一个结果压栈
resList.add(srcArray[index]);
//标记第此元素以被选用
mySignTable[index]=true;
//递归其子节点
SortArray(srcArray, mySignTable, N, resList, deep+1);
//完成一次深度搜索后进行下一次 及遍历其兄弟节点
//清空本次结果
resList.remove(resList.size()-1);
//清空本次标记
mySignTable[index]=false;
}else {
return;
}
}
}
}
public static int sreachZero(boolean[] signTable,int Offset)
{
//重offset的位置开始在signTable中找第一个出现false的位置
int index=-1;
for(int i=Offset;i<signTable.length;i++)
{
if(!signTable[i])
{
index=i;
return index; //返回第一出现false的index
}
}
return index;
}
public static int getZeroNum(boolean [] signTable)
{
//返回signTable中false的个数(PS:这个方法没用的,但我舍不得删)
int num=0;
for(int i=0;i<signTable.length;i++)
{
if(!signTable[i])
{
num++;
}
}
return num;
}
}
public class Test {
public int x,n,no;
public int[][] i;
public Test(int x,int n) {
if(n>x || n<1)
return;
this.x = x;
this.n = n;
int no = x;
for(int j=1;j<n;j++) {
no = no *(x-1);
}
this.no = no;
this.i = new int[no][n];
}
public int getInt(int a,int b) {
if(b == 0) {
return a/(int)Math.pow(x-1,n-1) + 1;
} else {
int i = a%(int)Math.pow(x-1,n-b)/(int)Math.pow(x-1,n-1-b) + 1;
if(i >= getInt(a,b-1))
i = i + 1;
return i;
}
}
public static void main(String[] args) {
Test t = new Test(3,3);
for(int a=0;a<t.no;a++) {
for(int b=0;b<t.n;b++) {
t.i[a][b] = t.getInt(a,b);
System.out.print(t.i[a][b]+" ");
}
System.out.println();
}
}
}