Суммирование частей вектора с использованием цикла while

Я не очень опытен с Matlab, и я изо всех сил борюсь с циклами. Я пытаюсь использовать цикл 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
5 ответов

Функция 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))

Если есть последовательные нули, мой ответ относится к тем, что они имеют подсписку нулевой длины, поэтому сумма этого подсписка (ноль) будет присутствовать в результате в соответствующем месте.


Вы можете использовать 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) положительно (я беру из фрагмента кода, что вас интересуют положительные значения, если вас интересуют ненулевые значения, просто измените его на 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


Прежде всего вам НЕОБХОДИМО рассматривать примеры в математике, в то время как документация цикла для лучшего понимания.

Ваша проблема в том, что утверждение (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).

Но, если вы еще этого не сделали, перейдите к документации по математике, пока циклы, циклы и все остальное, что вы считаете релевантным.

EDIT: лучшее решение

Я использовал find и length а также объединил некоторые значения вместе.

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

Если есть последовательные нули, они будут генерировать значение m, равное 0; Вы можете удалить это, используя

m(m==0) = '';


Так как в 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];


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

licensed under cc by-sa 3.0 with attribution.