我正在尝试以下作为一种业余爱好,而不是家庭作业。我对MATLAB还是陌生的,但对编码的了解却很少。我有一个坚持的问题。它来自使用MATLAB进行计算机编程:J。Michael Fitzpatrick和Akos Ledeckzi
问题10。编写一个名为cancel_middle
的函数,该函数需要 A , n - m
矩阵作为输入,其中 n 和 m 均为奇数, k 为正
小于 m 和 n 的奇数整数(该函数不必
检查输入)。该函数返回其中心 k 由 k 矩阵清零的输入矩阵。检查以下运行,
>> cancel_middle(ones(5),3)
ans =
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
我有一个嵌套的if函数,它将正确执行输入参数,但无法获得所需的输出。我认为这远没有效率,即使书中未涉及if语句,我也正在使用它。那是根据我以前的知识。因此,我认为要编写一个更简单,更有效的函数。
function M = cancel_middle(A,k);
[m,n] = size(A);
if rem([m,n],2) == [1,1]
if rem(k,2)==1
if [k,k]<[m,n]
M = zeros(k);
else
fprintf('Error 1: k must be odd and smaller than A\n');
end
else
fprintf('Error 2: k must be odd and smaller than A\n');
end
else
fprintf('Error 3: k must be odd and smaller than A\n');
end
我卡住的区域是应该在第8行上的输出参数。我正在正确输出k-by-k矩阵,但是出于明显的原因,它不在较大的矩阵上。我相信我想使用矩阵zeros(k)
并将其索引到较大的矩阵A中。我相信我缺少一些关键函数,这些函数也使我不必使用3个if语句,但是我非常不了解
这是我运行函数时的输出:
>> cancel_middle(ones(5),3)
ans =
0 0 0
0 0 0
0 0 0
很明显,这只是zeros(k)
的输出。
答案 0 :(得分:3)
我不知道您是否已经涵盖了MATLAB的 indexing 部分,但如果不是这样,我强烈建议您仔细阅读它们,因为这是MATLAB实力的支柱之一:>
一旦理解了这一点,练习就是计算矩阵的哪些索引将被清零。有了索引列表后,将值辅助到位于这些位置的矩阵元素就可以实现单行琐碎分配。
请考虑下面的以下功能(对冗长的变量名表示抱歉,但我试图使其具有说服力)。每行末尾的注释中给出的结果值对于一组示例输入A=ones(5,7)
和k=3
有效:
function M = cancel_middle(A,k)
% find [m,n] (the size of A)
[m,n] = size(A) ; % => m=5, n=7
% calculate the coordinates of the "center" of the matrix
center_row_idx = (m+1)/2 ; % => center_row_idx = 3
center_col_idx = (n+1)/2 ; % => center_col_idx = 4
% how much indices to take on each side of the center
half_width = (k-1)/2 ; % => center_row_idx = 3
% generate the indices which will be zeroed
row_indices = center_row_idx-half_width:center_row_idx+half_width ; % => row_indices = [2,3,4]
col_indices = center_col_idx-half_width:center_col_idx+half_width ; % => col_indices = [3,4,5]
% generate the output matrix M (as a copy of A)
M = A ;
% now you can zero the elements of matrix M directly by their indices
M(row_indices,col_indices) = 0 ;
end
您可以验证:
>> M = cancel_middle(ones(5,7),3)
M =
1 1 1 1 1 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 0 0 0 1 1
1 1 1 1 1 1 1
答案 1 :(得分:2)
您可以对end
使用索引分配,如下所示:
A = randi(9,5,7); % example A
k = 3; % example k
t = -(k-1)/2:(k-1)/2;
A((end+1)/2 + t, (end+1)/2 + t) = 0;
示例结果:
A =
2 5 2 9 3 6 9
6 3 0 0 0 4 8
7 7 0 0 0 8 5
6 2 0 0 0 5 6
5 7 1 5 8 4 6