Java回溯问题

时间:2011-09-03 12:20:05

标签: java algorithm

嘿伙计们。几个小时我一直在讨价还价。任何人都可以帮我一把吗?这是问题所在:

编号从1到n

n骆驼是排列顺序。我想重新排列,以便每只骆驼在前面都有不同的骆驼。

这是我到目前为止所做的:

import java.util.*;

public class NCamile{
static int size;
static int count;
static char[] arrN= new char[100];

public static void main(String[] args){
    System.out.print("Enter word: ");
    String numar = getInt();
    size = numar.length();
    count=0;

    for(int i=0; i < size ; i++){
        arrN[i] = numar.charAt(i);
    }
backtraking(size);  
}

public static void backtraking(int newsize){

    if (newsize == 1){
        return;
    }

    for(int i=0 ; i < newsize; i++){

        backtraking(newsize - 1);


            if(newsize == 2 ){

                    display();

                }




        rotate(newsize);
    }

}
public static void rotate(int newsize){
    int position = size - newsize;

    for(int i = position + 1; i < newsize; i++){
        char gigi;
        gigi = arrN[i - 1];
        arrN[i - 1] = arrN [i];
        arrN[i] = gigi;
    }
}

public static void display(){
    if (count < 9){
        System.out.print(" ");
    }

    System.out.print(++count+ ")" + " ");

    for(int i = 0 ; i < size ; i++)
        System.out.print(arrN[i]);
        System.out.print(" ");


    if(count % 10 == 0){
        System.out.println(" ");
    }
}


public static String getInt(){
    Scanner scan = new Scanner(System.in);
    String s = scan.next();
    return s;

}

}

有了这个,算法向我展示了重新排列一个字符串的每个有效解决方案,但它不会尊重问题的最后条件。我试过这个:

for(int j = 0 ; j < size ; j++){

   if (array[j] !=[array[j + 1] )
      display()
}

但是在我添加之后,我得到了大约10倍的显示单词然后它应该显示给我

任何人都可以告诉我应该怎么做?

2 个答案:

答案 0 :(得分:1)

如果您只是被要求投保

i)产生了一个新的安排,

ii)新安排必须满足每只骆驼沿着与原始安排所遵循的骆驼不同的骆驼的条件,

然后你可以通过颠倒骆驼列表来轻松满足这个要求。

答案 1 :(得分:0)

当然这不是优化的解决方案,但对于简单的gettin结果,我会考虑检查所有的排列。产生每个排列的方法并不难写(参见例如String permutation)并且检查某些驼峰是否具有相同的回溯将完全没有任何努力。

---编辑 所以...很少有东西可以补救,很少有东西不是: 我在String上工作,而不是char数组。 Char数组在这个问题上完全被误解了。最好使用String对象(实际上是因为String是char数组)或int数组(这对我来说很难,因为我没有找到任何使用这种参数的置换方法)。所以主要方法现在看起来:

private static String word;

public static void main(String[] args)
{
    System.out.print("Enter word: ");
    Scanner scan = new Scanner(System.in);
    word = scan.next();
    permutation(word);
}

我删除了你的类变量(长度,计数等等),因为它们现在是不必要的。写出字符串很简单,如果你想改变输出格式 - 请改用String.length属性。

置换方法是从提到的源复制而来的,很少修改。它看起来如下:

public static void permutation(String s)
{
    permutation("", s);
}

private static void permutation(String prefix, String s)
{
    int n = s.length();
    if (n == 0)
            {
        if (camelFit(prefix))
            System.out.println(prefix);
            }
    else
    {
        for (int i = 0; i < n; i++)
            permutation(prefix + s.charAt(i),
                    s.substring(0, i) + s.substring(i + 1, n));
    }

}

如果您要取消注释行检查if(camelFit(prefix))它将显示输入String的每个排列。但!我们只想打印这些符合问题条件的骆驼链。我们如何检查给定链是否如此?简单的方法:

private static boolean camelFit(String prefix)
{
    for (int i = 0; i < word.length() - 1; i++)
    {
        char camel = word.charAt(i);
        char camelFollow = word.charAt(i+1);
        for (int j = 0; j < prefix.length() - 1; j++)
        {
            if (prefix.charAt(j)==camel && prefix.charAt(j+1)==camelFollow)
            {
                return false;
            }
        }
    }
    return true;
}

也许不是那么简单,因为我们必须检查每对输入链(每个跟随者并跟随)与每对输出链。如果任何两对之间没有任何匹配 - 给定的链很好。

请注意,此解决方案绝对未经优化。寻找排列是O(n!)复杂度,检查对是O(n ^ 2)复杂度。最终的复杂性是O(n ^ 2)* O(n!)非常非常高。