Изменение для переменной индекса цикла внутри цикла - PullRequest
5 голосов
/ 14 мая 2010

Мне нужно изменить переменную цикла внутри итерации, поскольку я должен получить доступ к элементам массива в цикле, который изменяет размер w.r.t внутри цикла.

Вот мой фрагмент кода:

que=[];
que=[2,3,4];
global len;
len=size(que,2)
x=4;
for i=1:len 
    if x<=10
    que(x)= 5;
    len=size(que,2)
    x=x+1;

    end
end
que

Массив должен печататься как:

2 3 4 5 5 5 5 5 5 5 

Но это напечатано так:

2 3 4 5 5 5

В Visual C ++ массив вычисляется правильно, и печатается весь массив из 10 элементов, который увеличивается во время выполнения.

Как я могу сделать это в Matlab?

Ответы [ 4 ]

10 голосов
/ 14 мая 2010

Вы должны использовать while loop вместо for loop , чтобы сделать это:

que = [2 3 4];
x = 4;
while x <= 10
  que(x) = 5;
  x = x+1;
end

Или же вы можете вообще не использовать циклы, векторизовав свой код одним из следующих способов:

que = [2 3 4];             %# Your initial vector
%# Option #1:
que = [que 5.*ones(1,7)];  %# Append seven fives to the end of que
%# Option #2:
que(4:10) = 5;             %# Expand que using indexing
3 голосов
/ 14 мая 2010

Да, вы можете использовать цикл (while), но почему? Изучите способ работы с MATLAB. Избегайте этого цикла, который не нуждается в существовании.

Например, используйте эту единственную строку кода, которая просто добавляет столько элементов, сколько нужно добавить.

que = [que,repmat(5,1,10 - length(que))];

Если у вас есть какой-то другой способ определить, как долго ваша цель для этой переменной, все равно будет возможно создать массив в одну строку, используя аналогичную схему.

Я также могу спросить, почему вы определяете len как глобальную переменную в коде, который вы опубликовали?

0 голосов
/ 14 мая 2010

Программные циклы в Matlab имеют ужасную производительность. Как и все остальные, делайте это с помощью встроенных в Matlab функций и по мере возможности векторизуйте все. Если вам действительно нужны циклические конструкции, возможно, C будет лучшим выбором для вас:)

0 голосов
/ 14 мая 2010

Ваш вектор возврата - это именно то, что вы кодировали. Цикл for будет выполняться ровно 3 раза - длина вектора очереди, поэтому вы получаете три 5 с вместо семи. Изменение len внутри цикла не поможет, поскольку диапазон для переменной i определяется до запуска цикла for и не может быть изменен во время выполнения. Другими словами, после запуска цикла for он забывает, что такое len, он просто помнит, что i нужно изменить с 1 на 3.


Всегда ли начальная x равна length(que)+1?

Какой вектор вы ожидаете, скажем, x = 5? 2 3 4 0 5 5 5 5 5 5? или 2 3 4 5 5 5 5 5 5?

или 2 3 4 5 5 5 5 5 5 5? (на самом деле не зависит от x)

В первом случае лучшее решение для matlab-ish было бы от @gnovice:

que = [2 3 4];  
x = 5;
y = 10;
val = 5;
que(x:y)=val;

Во втором случае другое решение от @gnovice:

que = [2 3 4];
x = 5;
y = 10;
val = 5;
que = [que, val.*ones(1,y-x+1)];

или

que = [que, repmat(val, 1, y-x+1)];

В третьем случае это решение @woodchips:

que = [que, repmat(val, 1, y - length(que))];

В вашей ситуации использование цикла (для или во время) действительно плохо, потому что в каждом цикле вы увеличиваете размер вектора очереди с перераспределением памяти.

...