Matlab算法问题



同学们,我在开发一种算法时遇到了问题它需要一个有限的实数列表这些实数是按递增顺序排序的还有一个实数N,

-如果存在两个索引ij,使得1 <= i <j <= numel(L)L(i)+L(j)=N,则算法返回sumToN = [L(i) L(j)]对;如果存在多个具有所需属性的索引对,则该函数返回其中一个有效的索引对

-如果索引ij不满足等式L(i)+L(j)=N,使得1 <= i < j <= numel(L),函数返回空对Ret

L = [1 2 2 3];
N = 3;
sumToN = 0;
for i=1:numel(L);
  for j=1:numel(L);
    if i<j;
        if L(i) + L(j) == N;
        sumToN = [L(i) L(j)];
    display(sumToN);
        else
        Ret = [0 0];
        display(Ret);
        end
    end
   end
end

现在,在我用Matlab R2014编写的这段代码中,独立于if条件,我得到了一个奇怪的输出:命令窗口显示向量sumToN的两倍和向量Ret的四倍。对于如何解决这个问题有什么建议吗?

算法正确,显示行为也正确。在你的循环中,i<j满足了6次。这是(i, j)对(1、2),(1,3),(1,4),(2、3),(2、4),(3、4)。因此,根据您的代码,您应该期望显示6次。在基于L中的数据的这些对中,(1,2)和(1,3)可以两次满足条件L(i)+L(j)==3。所以你得到了sumToN显示两次其余的Ret显示4次

如果您想在找到对后立即停止,则应该在检测到L(i)+L(j) == N后立即返回该函数的值。你应该在循环开始前将Ret初始化为[0 0],并在循环结束后返回它。如果没有找到L(i)+L(j) == n,则返回[0 0]

让我们稍微解构一下程序。我要做的第一件事是将循环变量从i, j更改为a, b,因为:使用I和j作为Matlab中的变量。

接下来看

这行
if i<j;

我们总是希望这样,所以让我们这样做。(现在切换到a, b)…

for a=1:numel(L)-1
   for b=a+1:numel(L)

注意,b的循环现在从值a+1开始。所以b 总是大于a,我们不再需要这个检查。我还在numel(L)-1处结束了a循环,因为L(numel(L))之后没有元素可供b占用,我们想确保a+1始终有效。
(还请注意,我已经删除了行尾的分号。它们是不必要的,并且有效地将空行添加到循环中。)

现在我们准备看看L(a), L(b)对是否添加到N,如果是,设置返回值:

if L(a)+L(b) == N
   sumToN = [L(a) L(b)];   

如果您想要在这里显示的值,可以这样做:

   display(sumToN);

或者去掉赋值sumToN = ...

的分号

如果我们在if内部,并且我们已经赋值了返回值,我们希望停止寻找其他答案。我现在假设你应该写出一个独立的函数这就是这个函数应该做的。要结束循环(以及函数的任何进一步处理),您可以在赋值后立即使用return。这使得嵌套循环看起来像这样:

sumToN = [0 0];
for a=1:numel(L)-1
   for b=a:numel(L)
      if L(a)+L(b) == N
         sumToN = [L(a) L(b)];
         return
      end
   end
end

从这里开始,您可以在脚本的开头添加LN的初始化,在结尾添加disp(sumToN);,或者您可以使用函数声明和另一个end创建一个完整的函数:

function sumToEnd = summy(L,N)
   <all the stuff above goes here>
end

如果这是一个更大的脚本的一部分,您不希望在找到pair后完全退出,那么事情就有点复杂了,但这仍然是很可能的。(您必须使用两次break,它每次都退出一个循环,并与一个布尔变量配对,以告诉您何时中断。)

好了,我已经用这种方法解决了这个问题:

L = [1 2 2 3];
N = 3;
sumToN = 0;
Ret = [0 0];
for i=1:numel(L);
  for j=1:numel(L);
    if i<j && L(i) + L(j) == N;
     sumToN = [L(i) L(j)];
    end
  end
end
if sum(sumToN) == N;
     display(sumToN);
else
     display(Ret);
end

但是,即使显示的结果只有一个,在for循环中执行的步数也不会改变。

最新更新