Azzera filtri
Azzera filtri

中心を軸とした配列の入れ替え

3 visualizzazioni (ultimi 30 giorni)
wataru suzuki
wataru suzuki il 22 Dic 2020
Commentato: wataru suzuki il 24 Dic 2020
以下のような5×5の奇数列の配列Aを中心である3列目をそのままに
配列Bのように左右に入れ替えたいです。
しかしB=circshift(A,[0 5/2]); とすると
エラー: circshift
無効なシフト タイプ: 有限の実数の整数ベクトルでなければなりません。
と出てしまいます。fliperやfftshiftなどのコマンドをそのまま使ってもできなかったので
この場合どのように構文すべきか教えていただけないでしょうか?
A =
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
B=
8 15 1 17 24
14 16 7 23 5
20 22 13 4 6
21 3 19 10 12
2 9 25 11 18

Risposta accettata

源樹 上林
源樹 上林 il 22 Dic 2020
 マニュアルを見ると circshift の2つ目の引数は整数と書いてあります。エラーメッセージに書いてあるとおりです。ceilとかfloorで整数にしたところで希望する結果は得られません。
 関数1個で解決するに越したことはないのですが、最適なものを見つけられなかったり、存在しなくて簡単には解決しないこともよくあります。そういうときは泥臭い方法で解決するのも一つの手段です。
まず2回にシフトしてみました。
A = magic(5)
hw = ceil(size(A,2)/2);
B = circshift(A, [0 hw]);
B(:,[1:hw]) = circshift(B(:,[1:hw]), [0 -1]);
B
これだと偶数配列の場合はだめですね。
配列のインデックスを使って入れ替え。
A = magic(5)
% 最終的にこのようにしたい
% B = A;
% B(:,[4 5 1 2]) = A(:,[1 2 4 5]);
w = size(A,2);
hw = floor(w/2);
i = circshift( 1:w, hw );
ib = i(1:hw*2)
ia = circshift( ib, hw );
B = A;
B(:,ib) = A(:,ia);
B
良さそうだけど、長しい、何をやっているのかがわかりにくい。
あわせ技を思いつきました。
A = magic(5)
B = A;
i = [1 2 4 5];
B(:,i) = circshift(A(:,i), [0 2]);
B
これならスッキリしてて動作も理解しやすそうです。iさえ作れれば。
w = size(A,2);
i = 1:w;
if mod(w,2)
i(ceil(w/2)) = [];
end
こうなるのか。結局あまりきれいには書けませんでしたが、これでご希望の変換ができると思います。
  2 Commenti
Shunichi Kusano
Shunichi Kusano il 23 Dic 2020
上林さんの回答を見てすっきり書ける方法を思いついたので補足いたします。
A = magic(5)
i = [1 2 4 5]; % 5以外の場合、i = setdiff(1:size(A,2),ceil(size(A,2)/2));でOK
A(:,i) = A(:,circshift(i,2,2)); % 5以外の場合、シフト量は上と同様に変える
wataru suzuki
wataru suzuki il 24 Dic 2020
お二人ともありがとうございます。お蔭様でできそうです!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su ループと条件付きステートメント in Help Center e File Exchange

Community Treasure Hunt

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

Start Hunting!