边城愚人

如果我不在边城,我一定是在前往边城的路上。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  31 随笔 :: 0 文章 :: 96 评论 :: 0 Trackbacks
    网上看到一道java算法题,题目如下: 用1,2,2,3,4,5,这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234,412345等,要求:“4”不能排第3位,“1”与“5”不能相连。
    我的解题思路是这样的:这是一个典型的遍历题型,可以用递归实现。在每一次递归中,要解决的问题包括,“4”不能排第3位,“1”与“5”不能相连,“2”的个数最多为2个且要保证不能重复,其他数字也要不重复。最难解决的就是要使“2”不重复,我假定两个2的顺序不变,也就是在排列组合中两个2始终保持一种出现顺序,这样就不会重复。其他的约束看一下注释就可以明白了。网上有个使用图的解法,尽管很有创意,但原理性差不多,而使用TreeSet的方法颇让人跌眼镜。Java代码如下:
package test;

/**
 * 用1,2,2,3,4,5,这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234,412345等,要求:“4”不能排第3位,“1”与“5”不能相连。
 * 
@author kafka0102
 *
 
*/

public class ATest {

    
private static boolean is1Or5(char a,char b){
        
if(a=='1' && b=='5')return true;
        
if(a=='5' && b=='1')return true;
        
return false;
    }

    
    
private static int countOf2(char[] num,int index){
        
int n=0;
        
for(int i=0;i<index;i++){
            
if(num[i]=='2')n++;
        }

        
return n;
    }

    
    
private static boolean hasSameNumber(int index,char a, char[] num){
        
for(int i=0;i<index;i++){
            
if(num[i]==a)return true;
        }

        
return false;
    }

    
    
public static int testArrange(char[] number,char[] num,int index){
        
int size = 0;//组合的个数
        int pos1=1,pos2=2;//该变量为重复的2的数组位置,可以提取出来作为参数
        int emp = countOf2(num,index);//得到当前的数组中有几个2
        for(int i=0;i<num.length;i++){
            
if(number[i]=='2'){//当前的数字为2
                if(emp >= 2){//数组中2的个数多于2个
                    continue;
                }
else if(emp == 1){//数组中有一个2时,要求当前的2不能为位置1的2
                    if(i==pos1)continue;
                }
else{
                    
if(i==pos2)continue;//数组中没有2时,要求当前的2不能为位置2的2
                }

            }
else{
                
if(index==2 && number[i]=='4')continue;//去除4
                if(index>0 && is1Or5(num[index-1],number[i]))continue;//去除相邻的1和5
                if(hasSameNumber(index,number[i], num))continue;//去除重复数字
            }

            num[index] 
= number[i];
            
if(index==5){
                System.out.println(num);
                size
++;
            }
else{
                size 
= size + testArrange(number,num,index+1);
            }

        }

        
return size;
    }

    
    
public static void aTest(){
        
char[] number = {'1','2','2','3','4','5'};
        
char[] num = new char[number.length];
        
int size =0;
        size 
= testArrange(number,num,0);
        System.out.println(
"size="+size);
    }

    
    
public static void main(String[] args) {
        aTest();
    }


}

posted on 2007-03-13 09:06 kafka0102 阅读(4515) 评论(12)  编辑  收藏 所属分类: DS&Algorithms

评论

# re: 一道java算法题 2007-03-13 10:24 lang
多搞点这样 的题出来 研究研究,总是 看什么 hibernate头都锈 了  回复  更多评论
  

# re: 一道java算法题 2007-03-13 12:14 ronghai
我没有仔细看,但是我提一个思路就是把一个2替换为其他数字,最后再替换回来,这样结果会多出一半,然后再 去掉一般的结果,用 。HashMap就可以  回复  更多评论
  

# re: 一道java算法题 2007-03-13 13:00 kdboy
生成所有可能的序列,然后再过滤掉不符合要求的。
效率可能低点,不过,这样应该更容易些。  回复  更多评论
  

# re: 一道java算法题 2007-03-13 16:03 kafka0102
我本身也不会多少算法题,我想的是,这样的题要求的是实现技巧,而不单单是结果。这道题蛮可以for循环嵌套,将得到的每一个排列放到Set中让Set过滤,但这样效率极低,而且Set如果自己实现(比如TreeSet)也很复杂。做了这么多年Java,感觉就是基本的数据结构还行,算法方面就差很多(也许没有使用机会吧),但算法是很基础的东西,值得好好学习。  回复  更多评论
  

# re: 一道java算法题 2007-03-13 16:50 LeeYue_0530@hotmail.com
//不知道我这样写算不算 算法
void arithmetic1()
{
/*******
* 用1,2,2,3,4,5,这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234,412345等,要求:“4”不能排第3位,“1”与“5”不能相连。
* @author kafka0102
*
*/
char[] numbers = {'1','2','2','3','4','5'};
int startNum = 122345;
int endNum = 543221;

for(int i = startNum ; i < endNum ;i++)
{
String tmpNumber = String.valueOf(i);
if(
//循环数字符合数据的判断
tmpNumber.indexOf("1") != -1
&& tmpNumber.indexOf("3") != -1
&& tmpNumber.indexOf("4") != -1
&& tmpNumber.indexOf("5") != -1
&& countOf2(tmpNumber,'2')
//符合要求:“4”不能排第3位
&& tmpNumber.indexOf("4") != 2
//符合要求:“1”与“5”不能相连判断
&& tmpNumber.indexOf("1")+1 != tmpNumber.indexOf("5")
&& tmpNumber.indexOf("5")+1 != tmpNumber.indexOf("1")
)
{
System.out.println(tmpNumber);
}
}
}
boolean countOf2(String s,char c)
{
int count = 0;
for(int i = 0 ; i < s.length() ; i++)
{
if(c == s.charAt(i))
{
count++;
}
}
if(count == 2)
{
return true;
}
else
{
return false;
}
}  回复  更多评论
  

# re: 一道java算法题 2007-03-13 19:33 踏雪赤兔
看上去没多少算法味哦~  回复  更多评论
  

# re: 一道java算法题 2007-03-14 10:56 key
}else{
if(i==pos2)continue;//数组中没有2时,要求当前的2不能为位置2的2
}

这段代码其实永远跑不到  回复  更多评论
  

# re: 一道java算法题 2007-03-14 11:02 key
@key
看错了…… 能跑到  回复  更多评论
  

# re: 一道java算法题 2007-03-18 20:11 Belle
如果就这么几个数字,几种算法间并无太大差异。
但是,如果有100个数字或更多那就惨了, 递归就用不上了 ,会STACK溢出的。
所以可以 试试一种叫动态算法——也可以说是一种反递归,TOPCODE上经常用的一种。  回复  更多评论
  

# re: 一道java算法题 2008-07-08 16:30 ラノ
高手!  回复  更多评论
  

# re: 一道java算法题[未登录] 2008-09-08 10:40 落叶
我还很兴趣试了试,你们帮忙看看

int count=0;
String[] arr={"1","2","2","3","4","5"};
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
for(int m=0;m<6;m++){
for(int n=0;n<6;n++){
for(int p=0;p<6;p++){
for(int q=0;q<6;q++){
if(i!=j&&i!=m&&i!=n&&i!=p&&i!=q&&j!=m&&j!=n&&j!=p&&j!=q&&m!=n&&m!=p&&m!=q&&n!=p&&n!=q&&p!=q){
if(m!=4){ // "4"不能排第三位
if(i-j!=5&&j-i!=5&&j-m!=5&&m-j!=5&&m-n!=5&&n-m!=5&&n-p!=5&&p-n!=5&&p-q!=5&&q-p!=5){ // "1"和"5"不能相连
System.out.println("第"+(++count)+"种"+arr[i]+arr[j]+arr[m]+arr[n]+arr[p]+arr[q]);
}
}
}
}
}
}
}
}
}  回复  更多评论
  

# re: 一道java算法题[未登录] 2008-09-08 10:42 落叶
有问题联系我,谢谢提出意见哦

QQ:185604870  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: