matlab柱状斜线_Matlab小练习:按斜线方向依次赋值矩阵
來自知乎問題,覺得挺有意思,留給學(xué)生解答之余,我也做了一番思考,得到三種解法。
題目如下:
以n=80為例,
————————————————————
一、先要根據(jù)
確定矩陣的階數(shù)
如果先生成足夠大矩陣,再刪掉全為零的列,有點(diǎn)太low了。所以先思考一個(gè)算法:
觀察數(shù)據(jù)放置的特點(diǎn),不難發(fā)現(xiàn)這樣一個(gè)關(guān)系:
變形:
觀察,若
足夠大,
起決定作用,
取整一定是
較小的
(或
) 對(duì)嗎?試一試。
測(cè)試
至
:
n=1:56;
round(sqrt(2*n))
剛好是對(duì)的!
二、將
按斜線依次放置
無非是找到放置規(guī)律放數(shù)而已,放置就是用行標(biāo)列標(biāo)賦值,所以就是找行標(biāo)、列標(biāo)規(guī)律。
先寫個(gè)數(shù)的方便觀察規(guī)律,比如,
方法一. 行標(biāo)、列標(biāo)分別找規(guī)律
依次賦值的
行標(biāo):
共
組
個(gè)數(shù)
列標(biāo):
共
組
個(gè)數(shù)
(因?yàn)槭?/p>
條斜線)
既然如此,按上述規(guī)律生成(拼接)行標(biāo)、列標(biāo),再賦值即可。
編寫函數(shù):
functionA=DiagNum1(n)k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
%% 生成行標(biāo), 列標(biāo)
I=[];
J=[];
for i=1:k
I=[I,1:i];
J=[J,i:-1:1];
end
IND=sub2ind(size(A),I,J); %二維索引轉(zhuǎn)化為一維索引
A(IND(1:n))=1:n;
注意,生成行標(biāo)列標(biāo)索引后,[I, J]作為二維索引值,是不能直接用A([I,J])=1:n來賦值的,故做了二維索引到一維索引的轉(zhuǎn)化。
測(cè)試函數(shù):
DiagNum1(80)
方法二. 行標(biāo)列標(biāo)一起找規(guī)律
依次賦值的
行標(biāo)和列標(biāo):
先是“和為
”的,再“和為
”的,再“和為
”的,……; 每個(gè)子組里面又是行標(biāo)從小到大排列。
因此,先生成所有行標(biāo)列標(biāo)組合(
與
的笛卡爾積),第一關(guān)鍵字按"行標(biāo)列標(biāo)之和"排序,再第二關(guān)鍵字按行標(biāo)排序,排好序的取出前
個(gè),依次賦值
即可。
編寫函數(shù):
functionA=DiagNum2(n)k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
%% 生成所有下標(biāo)組合(笛卡爾積)
[X,Y]=meshgrid(1:n,1:n);
subn=[X(:),Y(:)];
%% 選取索引并賦值
ind=sortrows([subn,sum(subn,2)],3); %對(duì)下標(biāo)求和, 按該和排序, 已經(jīng)滿足要求
IND=sub2ind(size(A), ind(1:n,1),ind(1:n,2)); %選出前n個(gè)二維索引, 并轉(zhuǎn)化為一維
A(IND)=1:n;
測(cè)試函數(shù)(略)
方法三. 用循環(huán)語句實(shí)現(xiàn)
用循環(huán)語句控制行標(biāo)、列標(biāo)按該規(guī)律出現(xiàn),依次賦值:
編寫函數(shù):
functionA=DiagNum3(n)k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
val=1;
for m=1:k
for i=1:m
A(i,m+1-i)=val;
val=val+1;
if val>n
break;
end
end
end
注意,外層循環(huán)用
控制依次從第
列到第
列起始的斜線;對(duì)每條斜線,先循環(huán)
,從
到
;而始終有
.
測(cè)試函數(shù)(略)
三、稍微提升一下
只賦值
, 實(shí)用性不大,如果改進(jìn)一下,對(duì)給定的一個(gè)向量
, 將
中的值依次按斜線方向賦值成矩陣呢?
非常簡單,參數(shù)由
換成向量
, 則
的長度即為需要的
,再將最后賦值時(shí)用的
換成
即可。
改進(jìn)的第一個(gè)函數(shù):
functionA=DiagNum1(V)n=length(V);
k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
%% 生成行標(biāo), 列標(biāo)
I=[];
J=[];
for i=1:k
I=[I,1:i];
J=[J,i:-1:1];
end
IND=sub2ind(size(A),I,J); %二維索引轉(zhuǎn)化為一維索引
A(IND(1:n))=V;
改進(jìn)的第二個(gè)函數(shù):
functionA=DiagNum2(V)n=length(V);
k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
%% 生成所有下標(biāo)組合(笛卡爾積)
[X,Y]=meshgrid(1:n,1:n);
subn=[X(:),Y(:)];
%% 選取索引并賦值
ind=sortrows([subn,sum(subn,2)],3); %對(duì)下標(biāo)求和, 按該和排序
IND=sub2ind(size(A), ind(1:n,1),ind(1:n,2)); %選出前n個(gè)二維索引, 并轉(zhuǎn)化為一維
A(IND)=V;
改進(jìn)的第三個(gè)函數(shù)(稍有不同):
functionA=DiagNum3(V)n=length(V);
k=round(sqrt(2*n)); %確定矩陣階數(shù)k
A=zeros(k);
val=1;
for m=1:k
for i=1:m
A(i,m+1-i)=V(val);
val=val+1;
if val>n
break;
end
end
end
若還要得到原問題的結(jié)果,只需這樣調(diào)用函數(shù)即可:
DiagNum1(1:n)
DiagNum2(1:n)
DiagNum3(1:n)
原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明。
總結(jié)
以上是生活随笔為你收集整理的matlab柱状斜线_Matlab小练习:按斜线方向依次赋值矩阵的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从网络字节流中提出整数
- 下一篇: 数学建模——粒子群优化算法(PSO)【有