Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 数组递归_Java_Arrays_Algorithm_Recursion - Fatal编程技术网

Java 数组递归

Java 数组递归,java,arrays,algorithm,recursion,Java,Arrays,Algorithm,Recursion,我有一个任务我搞不懂,任何指点都会很感激的,它是这样的: 有一系列灯泡表示为一组真/假,每个灯泡都有一个开关,通过单击任何灯泡的开关,可以切换它以及两个相邻的灯泡(一个从左,另一个从右;如果单击边缘上的开关灯泡,当然只有一个相邻的灯泡被切换) 需要实现的是一种方法,该方法接受一系列打开/关闭的灯泡阵列,另一个表示在单击某些开关后假定第一个阵列的另一个状态。。! 因此,必须使用递归来确定是否存在将数组1转换为数组2的开关单击组合 这是该方法的签名: public static boolean di

我有一个任务我搞不懂,任何指点都会很感激的,它是这样的:

有一系列灯泡表示为一组真/假,每个灯泡都有一个开关,通过单击任何灯泡的开关,可以切换它以及两个相邻的灯泡(一个从左,另一个从右;如果单击边缘上的开关灯泡,当然只有一个相邻的灯泡被切换)

需要实现的是一种方法,该方法接受一系列打开/关闭的灯泡阵列,另一个表示在单击某些开关后假定第一个阵列的另一个状态。。! 因此,必须使用递归来确定是否存在将数组1转换为数组2的开关单击组合

这是该方法的签名:

public static boolean disco(boolean[] init, boolean[] target)
如果可以将数组init转换为目标,则返回true,否则返回false。 方法必须是静态的,并且不使用循环&任何其他静态和全局变量,只使用局部变量

例如:

boolean[] init = {true, false, true, false, true, false};
boolean[] target = {false, true, false, true, false, true};
对于以上两个阵列,disco(初始化,目标)将返回true,因为切换第一个和第四个灯泡将产生目标状态(记住相邻的灯泡也被切换)。

下面是我将如何操作的:

如果只剩下少于或等于3个灯泡,很容易检查它们是否可以切换,以确保正确

如果有三个以上的灯泡,请执行以下操作:

检查第一个灯泡是否正确。如果是这样,则从第二个灯泡开始递归地继续子阵列


如果第一个灯泡不正确,则切换第二个灯泡(切换第一个灯泡将不起作用,因为之前的灯泡会被切换回来)。现在,第一个灯泡是正确的。继续从第二个灯泡开始的子阵列。

新版本

public static boolean disco(boolean[] init, boolean[] target)  
{  
  return recurse(init,boolean,0);  
}  

public static boolean recurse(boolean[] init, boolean[] target, int min)  
{  
  if (min == init.length)  
    if (init == target)  
      return true;  
    else  
      return false;  
  boolean[] temp = "init with a change at min";  
  boolean a = recurse(init, target, min+1);  
  boolean b =   recurse(temp, target, min+1);  
  return a||b;
}  
新版本

public static boolean disco(boolean[] init, boolean[] target)  
{  
  return recurse(init,boolean,0);  
}  

public static boolean recurse(boolean[] init, boolean[] target, int min)  
{  
  if (min == init.length)  
    if (init == target)  
      return true;  
    else  
      return false;  
  boolean[] temp = "init with a change at min";  
  boolean a = recurse(init, target, min+1);  
  boolean b =   recurse(temp, target, min+1);  
  return a||b;
}  
我把它分为三种情况:

案例1:长度%3=0
通过更改第一个灯泡和第二个灯泡,可以仅影响第三个灯泡的更改。 然后更改为4和5将使第6个成为唯一更改的。我们看到,我们可以用指数除以3来改变每个灯泡。
向后工作(从末尾开始),我们也可以这样做,但这一次我们可以用指数(i+1)除以3来更换灯泡。
将两者结合起来,我们可以看到,如果我们想要改变索引0,1 mod 3,我们可以。但是要改变一个2,我们只需要改变一个相邻的0,1对,然后改变中间的一对。所以在所有情况下,这些都是可解的

案例2:长度%3=1
就像第一种情况一样,但是我们可以影响0,2 mod 3的单个更改,从而压缩1 mod 3的情况

案例3:长度%3=2
向前和向后操作只会产生0 mod 3的情况。剩下的唯一动作是对灯泡进行两次更改(因为我们可以忽略对位置0的任何更改)。更改1或2将反转由两个0包围的位置,而更改0将交换1,2的相邻块中的奇偶校验,这些块之间有一个0(如果您绘制它会更容易)。但到目前为止,我所展示的是0都可以被纠正,在任何相邻的1,2中,如果它们都是错误的,您可以在不改变任何其他内容的情况下修复它们。如果其中一个错误,则将更改传播到相邻的1,2对。如有必要,可以移动此更改。这意味着,1,2位置的任何偶数错误都可以固定,但奇数则不能。可以修复位置0处的所有错误

public static boolean disco(boolean[] init, boolean[] target)  
{  
  if (init.length%3 == 0 || init.length%3 == 1)
    return true;
  return recurse(init,target,0, true);
}

public static boolean recurse(boolean[] init, boolean[] target, int index, boolean even)
{
  if (index = init.length)
    return even;
  if (init[index] != target[index] && index%3 != 0)
    even = !even;
  return recurse(init, target, index+1, even);
}

提示:设a1、a2、…、ak、…、an为输入,b1、b2、…、bk、…、bn为所需输出

您可以递归地测试左侧和右侧,然后合并结果。棘手的部分是合并结果

从左边开始

  • 测试a1,a2,…,ak,符合b1,b2,…,bk,符合要求。
  • 如果为真,则测试a1、a2、…、ak至b1、b2、…、bk。
  • 如果为真,则从a1、a2、…、ak到b1、b2、…、bk的解决方案不能包括切换kth开关
  • 如果为假,则从a1、a2、…、ak到b1、b2、!bk必须包括切换第k个开关
  • 如果为假,则测试a1、a2、…、ak至b1、b2、…、bk
  • 如果为真,则从a1、a2、…、ak到b1、b2、…、bk的解决方案必须包括切换kth开关
  • 如果为假,则从a1,a2,…,ak到b1,b2,。。。,!bk不能包括切换kth开关

  • 在左侧进行两次测试后,您可以在右侧执行类似的测试。您将能够组合测试的值,因为您将知道是否切换了第k个开关。

    感谢所有人的帮助,这就是我想到的:

    public static boolean disco(boolean[] init, boolean[] target)
    {
        if (java.util.Arrays.equals(init, target)) {
            return true;
        } else {
            return disco(init, target, 0);
        }
    }
    
    private static boolean disco(boolean[] init, boolean[] target, int i)
    {
        if (i > init.length-1) {
            return false;
        }
    
        disco(init, target, i+1);
        boolean t = false;
    
        if (init[i] != target[i]) {
            switchBulb(init, target, i);
        }
    
        if (java.util.Arrays.equals(init, target)) {
            t = true;
        }
    
        return t;
    }
    
    private static void switchBulb(boolean[] init, boolean[] target, int i)
    {
        if ( (i > 1) && (init[i-1] != target[i-1]) && (init[i-2] != target[i-2]) ) {
            // If there's a series of 3 opposite-to-target bulbs, switch the middle one & from both sides
            init[i-1] = !init[i-1];
            init[i] = !init[i];
            init[i-2] = !init[i-2];
        } else if (i > 0 && i < init.length-1) {
            // There's only 1 bulb or 2 adjacent bulbs that are opposite of target.
            if (i == 1 && (init[0] != target[0]) ) {
                // First 2 bulbs are opposite of target's, so switch the 1st one.
                init[i-1] = !init[i-1];
                init[i] = !init[i];
            } else if ( (i == init.length-2) && (init[i+1] != target[i+1]) ) {
                init[i+1] = !init[i+1];
                init[i] = !init[i];
            } else {
                init[i] = !init[i];
                init[i-1] = !init[i-1];
                init[i+1] = !init[i+1];
            }
        } else {
            // First bulb or last bulb.
            init[i] = !init[i];
            if (i == 0) {
                init[i+1] = !init[i+1];
            } else {
                init[i-1] = !init[i-1];
            }
        }
    }
    
    publicstaticbooleandisco(boolean[]init,boolean[]target)
    {
    if(java.util.Arrays.equals(init,target)){
    返回true;
    }否则{
    返回disco(初始,目标,0);
    }
    }
    私有静态布尔disco(布尔[]初始化,布尔[]目标,int i)
    {
    如果(i>初始长度-1){
    返回false;
    }
    disco(初始,目标,i+1);
    布尔t=false;
    if(init[i]!=target[i]){
    开关灯泡(初始、目标、i);
    }
    if(java.util.Arrays.equals(init,target)){
    t=真;
    }
    返回t;
    }
    专用静态无效开关灯泡(布尔[]初始,布尔[]目标,int i)
    {
    如果((i>1)&&(init[i-1]!=目标[i-1])&&(init[i-2]!=目标[i-2])){
    //如果目标灯泡对面有一系列3个灯泡,则切换中间的灯泡&从两侧切换
    init[i-1]=!init[i-1];
    init[i]=!init[i];
    init[i-2]=!init[i-2];
    }else if(i>0&&i