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