필터 지우기
필터 지우기

Evaluation of a for loop

조회 수: 2 (최근 30일)
Jürgen
Jürgen 2012년 8월 13일
hello
is this pseudo code:
for Counter=1:size(M,2)
if someting
delete row from M
end
end
If would expect that if the size of M changing the range of Counter would change do but that does not happen, instead Counter will rang from 1 to the begin size of M
so size(M,2) is not evaluated each time that the loop runs?
I notices with while ...end you do not have the problem or am I completely mistaken?
thanks for any insights
regards,Jürgen

채택된 답변

Walter Roberson
Walter Roberson 2012년 8월 13일
The bounds and increments of "for" loops are recorded at the time the "for" statement is executed, and changes to any of the bounds or increment in the body of the loop do not have any effect on the execution of the loop. If you need to have the bounds vary, use a "while" loop.
In the particular case of deleting elements of the array, a "forward" for loop is not appropriate. Suppose Counter is 3 and you delete element 3, then what was in element 4 "falls down" to occupy element 3, so in order to test that element to see if it should be deleted, you would have to re-test at location 3 rather than proceeding on to location 4.
One of the tricks for avoiding this problem is to run the "for" loop backwards:
for Counter = size(M,1) : -1 : 1
if someting
delete row from M
end
end
Note here I adjusted to size(M,1) which is the row count (as per your "delete row"); your pseudo-code was using the count of columns to decide whether to delete rows.
  댓글 수: 1
Jürgen
Jürgen 2012년 8월 13일
ok ( yes pseudo code was wrong sorry for that ) nice idea a backwards loop

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Wayne King
Wayne King 2012년 8월 13일
편집: Wayne King 2012년 8월 13일
Yes, the for loop termination condition is set the first time you enter the loop
m = 3;
for jj = 1:m
disp('Hi');
m = m-1;
end
but the value of m is zero upon exiting the loop
If you wanted to use the value of size(M,2) to know when to execute the loop, you can use a break()
m = 3;
for jj = 1:m
disp('Hi');
m = m-1;
if (m<2)
break;
end
end
Or a while loop instead of a for
m = 3;
while m>1
disp('Hi');
m= m-1;
end
  댓글 수: 1
Jürgen
Jürgen 2012년 8월 13일
yes , I choose the while loop to solve the problem, I don't like to use break, long ago , I learned that breaking out a loop with 'break' is not an ideal solutions

댓글을 달려면 로그인하십시오.


Azzi Abdelmalek
Azzi Abdelmalek 2012년 8월 13일
편집: Azzi Abdelmalek 2012년 8월 13일
the idea is to:
  1. replace the rows by "nan"
  2. at the end remove the rows containing "nan"
A=magic(10) % example
for k=1:size(A,2)
if rand(1)>0.5 % it's just an example
A(:,k)=nan % replace the row by "nan"
end
end
A(:,any(isnan(A)))=[] %remove the rows containing nan
% this code suppose that your initial matrix don't contain nan. if your matrix contain "nan" use instead this code
A=magic(10) % example
A=num2cell(A) % convert to cell
for k=1:size(A,2)
if rand(1)>0.5 % it's just an example
A(:,k)={'remove'} % replace the row by "remove"
end
end
ind=cellfun(@(x) ~isnumeric(x),A)
A(:,find(mean(ind)==1))=[]
A=cell2mat(A)

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by