【问题标题】:summing portions of a vector using while loop使用 while 循环对向量的各个部分求和
【发布时间】:2014-11-03 21:57:30
【问题描述】:

我对 matlab 不是很有经验,并且正在努力处理 while 循环。我正在尝试使用 while 循环来求和零之间的向量部分,并创建这些和的新向量。这是一个例子:

n=[1,3,0,5,1,2,0,4,3]

我想要一个输出向量

m=[4,8,7]

我什至试图找到一个循环,它只会对初学者的第一部分求和,但我尝试过的所有 while 循环都只是无限运行。

例如

n = [1,3,0,5,1,2,0,4,3];

while n > 0

    m=sum(A)

end

【问题讨论】:

  • 按照您定义 n 的方式,您的谓词 n > 1 永远不会计算为逻辑 0(即 MATLAB 的错误),您确实会陷入无限循环。
  • 是否有两个连续的零?另外,请记住,您不应该在 MATLAB 中使用 while 循环来解决此类问题。您可以使用更好的方法。
  • 有些情况下连续的零,如果确实会更好,我愿意学习如何在没有while循环的情况下做到这一点。
  • 查看this 答案并将其应用于您的案例。
  • @user4212064 您应该通过单击左侧的复选标记来接受最适合您的答案。

标签: matlab vector while-loop


【解决方案1】:

cumsum 函数非常适合这类事情。它将在零上相加,因此您在每个零处获取值(之前或之后无关紧要,因为零不会影响总和),然后找到零之间的总和变化了多少——这就是之间的数字之和。我们将确保从第一个零的总和中减去任何内容。

sums = cumsum(n(:));
sums = [0; sums(n == 0); sums(end)];
m = diff(sums)

这将为您提供一个列向量,如果您想要一个行向量,请在最后一行使用转置 (')。

可以像 quickbug 那样在开头和结尾强制为零:

sums = cumsum([0; n(:); 0]);
m = diff(sums(n == 0))

如果有连续的零,我的回答会将它们视为具有零长度子列表,因此该子列表的总和(零)将出现在结果中的适当位置。

【讨论】:

    【解决方案2】:

    首先,您需要查看数学作品中的示例 while 循环 documentation 以便更好地理解。

    您的问题是陈述 (n > 0) 总是正确的。如果你添加另一个变量index,你可以得到类似的东西

    n = [1,3,0,5,1,2,0,4,3];
    index = 1;
    m = 0;
    while n(index) ~= 0
        m = m + n(index);
        index = index + 1;
    end
    

    这会让你得到m = 4; 你将不得不添加另一个循环来生成整个向量(使用这种方法)。您可以添加第二个循环,其中的另一个索引一直运行到index > length(n)

    但是,如果您还没有,请阅读有关 while 循环、for 循环以及您认为相关的任何其他内容的 mathworks 文档。

    编辑:更好的解决方案

    我使用了findlength 并将一些值连接在一起。

    n = [1,3,0,5,1,2,0,4,3];   
    idx = find(n ==0); %find where n = 0;
    idx = [0 idx length(n)+1]; %add start and endpoints of the vector
    for i = 1:length(idx)-1 %loop through each space that contains numbers
        m(i) = sum(n(idx(i)+1:idx(i+1)-1)); %sum up the values in between the indices 
    end
    

    如果有任何连续的零,它们将生成一个等于0的m值;您可以使用删除它

    m(m==0) = '';

    【讨论】:

      【解决方案3】:
      n=[1,3,0,5,1,2,0,4,3] ;
      n = [0, n, 0] ;
      ix = find(n==0) ;
      m = zeros(1,length(ix)-1) ;
      for k=2:length(ix)
          m(k-1) = sum(n(ix(k-1):ix(k))) ;
      end
      

      【讨论】:

        【解决方案4】:

        您可以使用while 迭代n 并根据您触摸的值更新m

        n = [1,3,0,5,1,2,0,4,3];
        m = 0;
        idx = 1;
        while idx <= numel(n)
            if n(idx) > 0
                m(end) = m(end) + n(idx);
            else
                m(end+1) = 0;
            end
            idx = idx + 1;
        end
        

        如果n(idx) 是正数(我从代码 sn-p 中获取您对正值感兴趣,如果您对非零值感兴趣,只需将其更改为 n(idx)~=0),将其添加到m 中的最后一个元素,否则将新元素添加到 m 以适应下一次运行。原则上这是一个for 循环,因此您可以将其重写为

        n = [1,3,0,5,1,2,0,4,3];
        m = 0;
        for idx = 1:numel(n)
            if n(idx) > 0
                m(end) = m(end) + n(idx);
            else
                m(end+1) = 0;
            end
        end
        

        但是现在由于您正在处理行向量,您可以使用for 的强大功能来迭代n 的元素:

        n = [1,3,0,5,1,2,0,4,3];
        m = 0;
        for ni = n
            if ni > 0
                m(end) = m(end) + ni;
            else
                m(end+1) = 0;
            end
        end
        

        我们可能应该到此为止,但有一些有趣的(但绝对不那么可读)的方式来摆脱if 子句:

        m = 0;
        for ni = n
            I = ni > 0; 
            m(end+~I) = I*(m(end) + ni);
        end
        

        【讨论】:

          【解决方案5】:

          既然while 对你很重要,请使用这个:

          n=[1,3,0,5,1,2,0,4,3];
          m = 0;
          n(end + 1 ) = 0;    % add a zero for detection
          i = 1;
          k = 1;
          while i <= length(n)    
                while n(i) > 0
                      m(k) = m(k) + n(i);
                      i = i + 1;
                end
                m(end + 1) = 0;  % add a new column
                i = i + 1;
                k = k + 1;
          end
          m(end) = [];
          

          给,m = [4 8 7];

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-11-23
            • 1970-01-01
            • 1970-01-01
            • 2021-04-18
            • 1970-01-01
            • 1970-01-01
            • 2013-01-24
            相关资源
            最近更新 更多