递归合并两个数组,采用备用元素(Java)

时间:2016-04-07 23:54:46

标签: java arrays recursion merge

我真的需要家庭作业问题的帮助。我已经试图解决这个问题好几天了,非常感谢一些帮助!这是提示:

将两个数组合并为一个。编写一个名为merge的方法,它采用3个整数数组 参数:a,b和soln。 soln保证是a.length + b.length的大小。阵列a和b应该是"合并"通过交替元素分成一个数组。添加第4个参数,该参数指示对于给定的方法递归调用,应该更新soln中的哪个元素。

示例:

merge({1,2,3},{4,5,6},soln,0)应以soln中的以下值结束:{1,4,2,5,3,6}

merge({1,2},{3,4,5},soln,0)应以soln中的以下值结束:{1,3,2,4,5}

我可以让它与数组的工作长度相同,即使数组的长度不同(但只有一个元素)。我无法正确排列索引。我尝试了很多不同的变体,但到目前为止我的目标是:

public static void merge3(int[] a, int[] b, int[] soln, int index) {
    if (index > soln.length-1) {
        return; //if index reaches end of soln length
    }

        int index2 = (int)(index/2); //allows me to pull alternately from a and b arrays. As index goes up, index2 becomes 0, 0, 1, 1, 2, 2, etc.

        if (b.length >= a.length) {
            if (index%2 == 0) {
                if (index2 > a.length-1) {
                    soln[index] = b[index2];
                    merge3(a, b, soln, index+1);
                } else {
                    soln[index] = a[index2];
                    merge3(a, b, soln, index+1);
                }
            } else {
                soln[index] = b[index2];
                merge3(a, b, soln, index+1);
            }

        } else if (b.length < a.length) {
            if (index%2 == 0) {
                soln[index] = a[index2];
                merge3(a, b, soln, index+1);
            } else {
                if (index2 >= b.length) {
                    soln[index] = a[index2];
                    merge3(a, b, soln, index+1);
                } else {
                    soln[index] = b[index2];
                    merge3(a, b, soln, index+1);
                }
            }
        }
}

如果数组a为{1,2,3}且数组b为{4,5,6,7,8,9},则soln变为{1,4,2,5,3,6,7,7 ,而不是它应该是什么,它是{1,4,2,5,3,6,7,8,9}。它已经关闭,因为当我执行索引+ 1时,递归调用会捕获相同的值(index2),当只剩下一个数组时,该值用于在数组之间交替。请帮忙!谢谢!

1 个答案:

答案 0 :(得分:0)

这是一种故意迂腐的思考这类问题的方法。

首先要确定你的状态。将此问题中的所有可能性划分为不同状态的一种方法是:

  • 退出,您只需返回。 (对于每个递归调用的方法,总是需要这个。)
  • 阵列耗尽前
  • ,您仍然在每个输入数组ab中至少留下一个数组元素。
  • 数组耗尽后
  • ,其中所有较小的数组元素已添加到soln
  • 数组a为空,其中第一个数组没有元素。通常你会在递归电话之外处理这个问题,但我们在这里遵循规则......

这些状态中的每一种都代表了处理输入所需的不同方式。

此类结构的伪代码如下所示:

if (test to see if we're in "exit" state) {
    logic handling "exit" state
} else {
    if (test to see if we're in "before array exhaustion" state) {
        logic handling "before array exhaustion" state
    } else {
        if (test to see if we're in "array `a` empty" state ) {
            logic handling "array `a` empty" state
        } else {
            logic handling "after array exhaustion" state

        }

    }
}
recursive call to your method here

您已经拥有(test to see if we're in "exit" state)

if (index > soln.length-1) {

你在这里有logic handling "exit" state

    return; //if index reaches end of soln length

由于这个状态的逻辑return,语法并不要求你将它放在if-else中,就像它在伪代码中一样,但是当你&#它可能更清晰时39;如果你始终使用if-else结构,那就重新掌握Java语法。
之后,您需要有条件的if (test to see if we're in "before array exhaustion" state),但您的代码会假定您在logic handling "before array exhaustion" state并相应地处理它。逻辑很好,但国家不是。您需要使用模板并将该逻辑放在适当的位置,但至少您不必重写它。

现在填写其余的伪代码模板,从测试开始。

试验:
test to see if we're in "array 'a' empty" state只是查看数组a是否为空,因此写入非常简单。
根据a.length,b.length和index,test to see if we're in "before array exhaustion" state检查我们是否已经将所有较小的数组元素复制到了soln中。
数组填充逻辑:
你退出案例下面的内容适用于logic handling "before array exhaustion" state,所以你只需要写一下:

  • logic handling "array 'a' empty" state你已经知道数组a是空的。
  • logic handling "after array exhaustion" state。这是我们用较小的数组完成的部分,我们需要知道从较大的输入数组中提取哪个元素,以便我们可以将它添加到soln中。

所以基本上按照模板编写3个测试(1个已经完成,1个微不足道,还有一个),然后为不同的状态编写逻辑(两个已经完成,一个是微不足道的,还有一个),你和# 39;在那里。

您可能还会考虑重构现有代码,以便只在最后发生一次递归调用。这称为尾递归,即使Java SE 8具有所有优化,它仍然更好。它也更清洁。

希望这是一个有用的模板,用于思考一个简单的问题。