新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论Java, J2SE, J2ME, J2EE, 以及Eclipse, NetBeans, JBuilder等Java开发环境,还有JSP, JavaServlet, JavaBean, EJB以及struts, hibernate, spring, webwork2, Java 3D, JOGL等相关技术。
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Java/Eclipse 』 → 一著名软件公司的java笔试算法题! 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 5420 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 一著名软件公司的java笔试算法题! 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     DMman 帅哥哟,离线,有人找我吗?魔羯座1984-1-11
      
      
      威望:1
      头衔:数据挖掘青年
      等级:研二(Pi-Calculus看得一头雾水)(版主)
      文章:803
      积分:5806
      门派:W3CHINA.ORG
      注册:2007/4/9

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给DMman发送一个短消息 把DMman加入好友 查看DMman的个人资料 搜索DMman在『 Java/Eclipse 』的所有贴子 点击这里发送电邮给DMman 访问DMman的主页 引用回复这个贴子 回复这个贴子 查看DMman的博客楼主
    发贴心情 一著名软件公司的java笔试算法题!

    原题如下:用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列,如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连.
    一楼的答案:
    解决思路:强化题目,用1、2、2、3、4、5这六个数字排列“递增”序列。其他要求不变。
    算法思路:显然是递归,初始序列122345,先从末两位(45)变化(45,54),然后末三位(345) ... 直到最后六位.怎样解决重复问题?很简单,由于是递增序列,每生成新序列可与前一生成序列比较,如<放弃当前序列。当然有更好效率,如预先预测。代码如下:
    class test
    {
      // 当前固定部分
      private String CurFixPart;
      private String PreGenNum;
      
    public static void main(String[] args)
    {
    test t=new test();
    t.GenControll("122345");
    }

    // 调整字符串s位置pos字符到最前
    private String shift(String s, int pos)
    {
    String newStr;
    if (s.length()>pos+1)
      newStr=s.substring(pos, pos+1)
            +s.substring(0, pos)
            +s.substring(pos+1);
    else
      newStr=s.substring(pos)
            +s.substring(0, pos);
    return newStr;
    }

    protected int Validate(String newNum)
    {
      String newGenNum=CurFixPart+newNum;
      if (Integer.valueOf(newGenNum)<=Integer.valueOf(PreGenNum))
        return 0;
      if (newGenNum.substring(2,3).equals("4") ||
           (newGenNum.indexOf("35")!=-1) || (newGenNum.indexOf("53")!=-1))
        return 0;
          
      PreGenNum=newGenNum;
    System.out.println(newGenNum);
    return 0;
    }

    public void GenControll(String Base)
    {
      PreGenNum="0";
    CurFixPart="";
    GenNext(Base, 0);
    }

    void GenNext(String varPart, int curPos)
    {
    if (varPart.length()==2)
    {
      Validate(varPart);
      Validate(shift(varPart, 1));
      return;
    }
    // Next Layer
    String newGen=shift(varPart, curPos);
    String SavedFixPart=CurFixPart;
    CurFixPart=CurFixPart+newGen.substring(0,1);
    GenNext(newGen.substring(1), 0);
    CurFixPart=SavedFixPart;
    // 同层递增
    if (curPos==varPart.length()-1)  
      return;
    GenNext(varPart, curPos+1);
    }
    }
    序列122345测试通过。
    有什么意见请大家多多提点。

    二楼的答案:
    1 把问题归结为图结构的遍历问题。实际上6个数字就是六个结点,把六个结点连接成无向连通图,对于每一个结点求这个图形的遍历路径,所有结点的遍历路径就是最后对这6个数字的排列组合结果集。
    2 显然这个结果集还未达到题目的要求。从以下几个方面考虑:
      1. 3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。
      2. 不能有重复: 考虑到有两个2,明显会存在重复结果,可以把结果集放在TreeSet中过滤重复结果
      3. 4不能在第三位: 仍旧在结果集中去除满足此条件的结果。

    采用二维数组定义图结构,最后的代码是:

    import java.util.Iterator;
    import java.util.TreeSet;

    public class TestQuestion {

    private String[] b = new String[]{"1", "2", "2", "3", "4", "5"};
    private int n = b.length;
    private boolean[] visited = new boolean[n];
    private int[][] a = new int[n][n];
    private String result = "";
    private TreeSet set = new TreeSet();

    public static void main(String[] args) {
    new TestQuestion().start();
    }

    private void start() {

    // Initial the map a[][]
    for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
    if (i == j) {
    a[i][j] = 0;
    } else {
        a[i][j] = 1;
    }
    }
    }

    // 3 and 5 can not be the neighbor.
    a[3][5] = 0;
    a[5][3] = 0;

    // Begin to depth search.
    for (int i = 0; i < n; i++) {
        this.depthFirstSearch(i);
    }

    // Print result treeset.
    Iterator it = set.iterator();
    while (it.hasNext()) {
    String string = (String) it.next();
    // "4" can not be the third position.
    if (string.indexOf("4") != 2) {
    System.out.println(string);
    }
    }
    }

    private void depthFirstSearch(int startIndex) {
    visited[startIndex] = true;
    result = result + b[startIndex];
    if (result.length() == n) {
    // Filt the duplicate value.
    set.add(result);
    }
    for(int j = 0; j < n; j++) {
    if (a[startIndex][j] == 1 && visited[j] == false) {
    depthFirstSearch(j);
    } else {
    continue;
    }
    }

    // restore the result value and visited value after listing a node.
        result = result.substring(0, result.length() -1);
        visited[startIndex] = false;
    }
    }
    3,5不能相连:实际要求这个连通图的结点3,5之间不能连通, 可在构造图结构时就满足改条件,然后再遍历图。
    代码中请注意这几行:
    // 3 and 5 can not be the neighbor.
    a[3][5] = 0;
    a[5][3] = 0;

    只要这样定义图,根本不用在代码中写IF ELSE语句。
    实际上基于图的算法好处在于,只要你能定义好满足题目要求的图结构,遍历的结果就是你要的结果,不用任何对遍历结果做任何处理。包括本题中的:4不能在第三位置,3,5不能相连,唯一
    性要求,其实都可以在体现在构造的图形结构里,然后直接遍历图取得自己要的结果。而不用再次处理结果集。

    只是说这里实际上对其它要求要体现在图结构里有困难(理论上是可以的),但起码3,5不能相接是很好构造的,就是上面的代码段来解释的。

    关于图形数据结构建议先看看数据结构的书,主要是将如何利用二维数组描述图结构,再看看图的深度遍历实现原理。最后再应用到这个问题上来,自然就不难明白了。

    三楼给出的答案:
    当然,如果要消除重复,用递归的方法的问题是,递归中不知道整体的信息,因此没有办法比较整体的串间是否有重复。如果不怕占用大量的内存资源,可以先存储所有的排列串,然后再一个个比较,删除重复的即可,如下(仅仅示意,简单写,程序中应该还有些问题,特别在删除重复串时):
    import java.util.*;
    public class test {
    static LinkedList list=new LinkedList();
    public static void main(String[] arg) {
    Scanner r=new Scanner(System.in);
    String s=r.nextLine();
    Pailie(s,"");
    for(int i=0; i<list.size(); i++)
    for(int j=i+1; j<list.size(); j++)
    if(((String)list.get(i)).compareTo((String)list.get(j))==0)
    list.remove(j);
    for(int i=0; i<list.size(); i++)
    System.out.println(list.get(i));
    }
    static void Pailie(String s,String p) {
    if(s.length()<1) {
    String n=new String(p);
    list.add(n);
    }
    else {
    for(int i=0; i<s.length(); i++) {
    Pailie(s.substring(1),p+s.substring(0,1));//递归调用
    s=s.substring(1)+s.substring(0,1);//循环移位
    }
    }
    }
    }
    这样,你的结果就得到了:
    1223(输入行)
    1223
    1232
    1322
    2231
    2213
    2312
    2321
    2123
    2132
    3122
    3221
    3212
    否则,则必须转化条件,让递归算法在程序中就能判断和剔出重复的情况。比如,对于只可能有两个字符重复的情况,所有重复的串的情况出现在两个紧邻的字符相同的情况下,我们则可以修改递归显示条件为当没有两个相邻字符相同时发生(同样,这条件可能不对,但只是说明问题),程序如下:
    import java.util.*;
    public class test {
    static LinkedList list=new LinkedList();
    public static void main(String[] arg) {
    Scanner r=new Scanner(System.in);
    String s=r.nextLine();
    Pailie(s,"");
    }
    static void Pailie(String s,String p) {
    if(s.length()<1) System.out.println(p);
    else {
    for(int i=0; i<s.length(); i++) {
    if(s.length()<2 || (s.charAt(0)!=s.charAt(1)))
    Pailie(s.substring(1),p+s.substring(0,1));//递归调用
    s=s.substring(1)+s.substring(0,1);//循环移位
    }
    }
    }
    }
    运行结果为:
    1223(输入行)
    1232
    1223
    2312
    2321
    2123
    2132
    2231
    2213
    3212
    3221

    有兴趣的朋友到 下面去看看该帖子的激烈讨论吧!
    http://community.csdn.net/Expert/topic/5294/5294835.xml?temp=.7436029


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    数据挖掘青年 http://blogger.org.cn/blog/blog.asp?name=DMman
    纪录片之家 (很多纪录片下载)http://www.jlpzj.com/?fromuid=137653

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/6/3 15:31:00
     
     guoqsbyte 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:2
      积分:68
      门派:XML.ORG.CN
      注册:2007/9/3

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给guoqsbyte发送一个短消息 把guoqsbyte加入好友 查看guoqsbyte的个人资料 搜索guoqsbyte在『 Java/Eclipse 』的所有贴子 引用回复这个贴子 回复这个贴子 查看guoqsbyte的博客2
    发贴心情 
    public static void main(String[] args) { 
    int m=0;
    for(int i=12345;i<=54321;i++){
    if(String.valueOf(i).indexOf('0')==-1&&String.valueOf(i).indexOf("35")==-1&&String.valueOf(i).indexOf("53")==-1){
     
    m=Integer.valueOf(""+String.valueOf(i).charAt(0))+Integer.valueOf(""+String.valueOf(i).charAt(1))+Integer.valueOf(""+String.valueOf(i).charAt(2))+Integer.valueOf(""+String.valueOf(i).charAt(3))+Integer.valueOf(""+String.valueOf(i).charAt(4));
      if(m==15){
       System.out.println(i);
      }
     }
    }
     }
    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/9/6 16:22:00
     
     guoqsbyte 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:2
      积分:68
      门派:XML.ORG.CN
      注册:2007/9/3

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给guoqsbyte发送一个短消息 把guoqsbyte加入好友 查看guoqsbyte的个人资料 搜索guoqsbyte在『 Java/Eclipse 』的所有贴子 引用回复这个贴子 回复这个贴子 查看guoqsbyte的博客3
    发贴心情 
    public class rr {

     /**
      * @param args
      */
     public static void main(String[] args) {
      // TODO Auto-generated method stub
      int[] m=new int[10];
     
      
    for(int i=12345;i<=54321;i++){
     int flag=1;
     for(int k=0;k<10;k++) {
      m[k]=0;
     }
     for(int t=0;t<5;t++){
      m[Integer.valueOf(""+String.valueOf(i).charAt(t))]=Integer.valueOf(""+String.valueOf(i).charAt(t));
     }
     for(int j=1;j<=5;j++){
      flag*=m[j];
     
     }
     if(flag!=0&&String.valueOf(i).indexOf("35")==-1&&String.valueOf(i).indexOf("53")==-1&&String.valueOf(i).indexOf('4')!=2){
      System.out.println(i);
     }
    }
     }

    }

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/9/6 17:00:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Java/Eclipse 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2025/1/3 1:52:53

    本主题贴数3,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    92.773ms