MATLAB Language
Для петель
Поиск…
замечания
Итерация над вектором столбца
Общий источник ошибок пытается перебрать элементы вектора столбца. Вектор столбца обрабатывается как матрица с одним столбцом. (В Matlab фактически нет различий.) Цикл for
выполняется один раз, когда переменная цикла устанавливается в столбец.
% Prints once: [3, 1]
my_vector = [1; 2; 3];
for i = my_vector
display(size(i))
end
Изменение переменной итерации
Изменение переменной итерации изменяет ее значение для текущей итерации, но не влияет на ее значение в последующих итерациях.
% Prints 1, 2, 3, 4, 5
for i = 1:5
display(i)
i = 5; % Fail at trying to terminate the loop
end
Специальные характеристики a:b
в правой части
В базовом примере рассматривается 1:n
как обычный экземпляр создания вектора строки, а затем итерации по нему. По соображениям производительности Matlab фактически обрабатывает любые a:b
или a:c:b
специально, не создавая вектор строки полностью, а вместо этого создавая каждый элемент по одному за раз.
Это можно обнаружить, слегка изменив синтаксис.
% Loops forever
for i = 1:1e50
end
% Crashes immediately
for i = [1:1e50]
end
Петля от 1 до n
Самый простой случай - это просто выполнить задачу для фиксированного известного количества раз. Скажем, мы хотим отображать числа от 1 до n, мы можем написать:
n = 5;
for k = 1:n
display(k)
end
Цикл будет выполнять внутренний оператор (ы), все между символами for
и end
, в течение n
раз (5 в этом примере):
1
2
3
4
5
Вот еще один пример:
n = 5;
for k = 1:n
disp(n-k+1:-1:1) % DISP uses more "clean" way to print on the screen
end
на этот раз мы используем как n
и k
в цикле, чтобы создать «вложенный» дисплей:
5 4 3 2 1
4 3 2 1
3 2 1
2 1
1
Итерации над элементами вектора
Правая часть задания в цикле for
может быть любым вектором строки. Левая часть задания может быть любым допустимым именем переменной. Цикл for
присваивает другому элементу этого вектора переменной каждый пробег.
other_row_vector = [4, 3, 5, 1, 2];
for any_name = other_row_vector
display(any_name)
end
Вывод будет отображаться
4
3
5
1
2
(Версия 1:n
является нормальным случаем этого, потому что в Matlab 1:n
- просто синтаксис для построения вектор-строки из [1, 2, ..., n]
.)
Следовательно, два следующих блока кода идентичны:
A = [1 2 3 4 5];
for x = A
disp(x);
end
а также
for x = 1:5
disp(x);
end
И следующие идентичны:
A = [1 3 5 7 9];
for x = A
disp(x);
end
а также
for x = 1:2:9
disp(x);
end
Любой вектор строки будет делать. Они не должны быть цифрами.
my_characters = 'abcde';
for my_char = my_characters
disp(my_char)
end
выйдет
a
b
c
d
e
Итерация по столбцам матрицы
Если правая часть присваивания является матрицей, то в каждой итерации переменной присваиваются последующие столбцы этой матрицы.
some_matrix = [1, 2, 3; 4, 5, 6]; % 2 by 3 matrix
for some_column = some_matrix
display(some_column)
end
(Версия вектора строки является нормальным случаем этого, потому что в Matlab вектор строки является просто матрицей, столбцы которой имеют размер 1.)
Вывод будет отображаться
1
4
2
5
3
6
т.е. каждый столбец отображенной итерационной матрицы отображается, каждый столбец печатается при каждом вызове display
.
Перечислять индексы
my_vector = [0, 2, 1, 3, 9];
for i = 1:numel(my_vector)
my_vector(i) = my_vector(i) + 1;
end
Наиболее простые вещи, выполняемые for
циклов, могут выполняться быстрее и проще с помощью векторизованных операций. Например, приведенный выше цикл можно заменить на my_vector = my_vector + 1
.
Вложенные петли
Петли могут быть вложенными, чтобы преформировать итерированную задачу в другую итерационную задачу. Рассмотрим следующие петли:
ch = 'abc';
m = 3;
for c = ch
for k = 1:m
disp([c num2str(k)]) % NUM2STR converts the number stored in k to a charachter,
% so it can be concataneted with the letter in c
end
end
мы используем 2 итератора для отображения всех комбинаций элементов из abc
и 1:m
, что дает:
a1
a2
a3
b1
b2
b3
c1
c2
c3
Мы также можем использовать вложенные циклы для объединения между задачами, которые должны выполняться каждый раз, и задачи, которые необходимо выполнить один раз в нескольких итерациях:
N = 10;
n = 3;
a1 = 0; % the first element in Fibonacci series
a2 = 1; % the secound element in Fibonacci series
for j = 1:N
for k = 1:n
an = a1 + a2; % compute the next element in Fibonacci series
a1 = a2; % save the previous element for the next iteration
a2 = an; % save ht new element for the next iteration
end
disp(an) % display every n'th element
end
Здесь мы хотим вычислить все ряды Фибоначчи , но каждый раз отображать только n
й элемент, поэтому мы получаем
3
13
55
233
987
4181
17711
75025
317811
1346269
Другое дело, что мы можем использовать первый (внешний) итератор во внутреннем цикле. Вот еще один пример:
N = 12;
gap = [1 2 3 4 6];
for j = gap
for k = 1:j:N
fprintf('%d ',k) % FPRINTF prints the number k proceeding to the next the line
end
fprintf('\n') % go to the next line
end
На этот раз мы используем вложенный цикл для форматирования вывода и торможем линию только тогда, когда был введен новый пробел ( j
) между элементами. Мы пробиваем ширину зазора во внешнем контуре и используем его внутри внутреннего цикла для итерации по вектору:
1 2 3 4 5 6 7 8 9 10 11 12
1 3 5 7 9 11
1 4 7 10
1 5 9
1 7
Примечание. Странные те же самые вложенные контуры.
Это не то, что вы увидите в других средах программирования. Я наткнулся на это несколько лет назад, и я не мог понять, почему это происходит, но после некоторого времени работы с MATLAB я смог понять это. Посмотрите на фрагмент кода ниже:
for x = 1:10
for x = 1:10
fprintf('%d,', x);
end
fprintf('\n');
end
вы не ожидаете, что это будет работать должным образом, но это произойдет, производя следующий вывод:
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
1,2,3,4,5,6,7,8,9,10,
Причина в том, что, как и все остальное в MATLAB, счетчик x
также является матрицей - вектором, который будет точным. Таким образом, x
является только ссылкой на «массив» (когерентная, последовательная структура памяти), которая соответствующим образом ссылается на каждый последующий цикл (вложенный или нет). Тот факт, что вложенный цикл использует один и тот же идентификатор, не имеет никакого отношения к тому, как ссылаются значения из этого массива. Единственная проблема заключается в том, что внутри вложенного цикла внешний x
скрывается вложенным (локальным) x
и поэтому не может быть ссылкой. Однако функциональность структуры вложенных циклов остается неповрежденной.