Python:2次元配列の縦横斜め
二次元配列のとりまわし
最近はpython3にハマってまして(;´Д`)
ここは私のお気に入りメモの場所なので好きな事を書くのです(`・ω・´)
検索してもなかなか斜め方向へのアクセスのいい方法は見つけられなかったのと
いつも検索して助けられている部分もあるのでもしかしたら最果てのこの場所で
探しているものが見つかったなら・・・と思ってメモを記すことにしました。
python3はpaizaラーニングというサイトで入門編をさらっとやってから問題集で
勉強した感じです。Cランクの問題集が終わったのでBランク問題へ。
同ランクでも難易度にだいぶ幅があるので( ノД`)スキルチェックする時は
難易度をよく見てから受けましょう(失敗したら失敗したコードが残っちゃうので)
Cランク受ける時もBランク受ける時も失敗続きでへこみます(´・ω・`)
問題集も答えを提出してからじゃないと模範解答とかみれないので
一度は自分で考えるけどあまりにもわからなければ時間ももったいないので
適当に提出して方針と模範解答から学ぶのも一つの手としております。
この2次配列の縦横斜めの操作もBランク問題ででてくるものです。
2次元配列とは文字道理2D・・配列が縦×横(平方)になっている配列のことです。
2D地図とかピクセルとか・・・そういったものの操作に用いられる様です。
# coding: utf-8
h=4
w=5
a=[[0]*w for _ in range(h)]
for i in range(h):
c=0
for j in range(w):
a[i][j]=str(i)+str(c)
c+=1
print(a)
for i in a:
print(" ".join(i))
[['00', '01', '02', '03', '04'], ['10', '11', '12', '13', '14'], ['20', '21', '22', '23', '24'], ['30', '31', '32', '33', '34']]
4行5列の2次配列だと普通は上のように表示されますが
00 01 02 03 04
10 11 12 13 14
20 21 22 23 24
30 31 32 33 34
縦横をそろえて表示するとこうなります。
配列は0番から始まるので00がa[0][0]、34がa[3][4]を示しています。
2次配列を操作する場合大抵は2重ループで取り回します。
for i で行を for jで列を回しています。
これが配列の横向き(1行ずつ)の操作となります。
for i で列をfor jで行をまわすと
配列の縦向き(1列ずつ)の操作となります。
では斜めはどうするのかというと
斜めは操作を2回に分けます。対角線上に線引きして
三角形を2つにしてひとつづつ取りまわすイメージです。
横
# coding: utf-8
h=4 #行
w=5 #列
a=[[0]*w for _ in range(h)] #2次配列の宣言と空の要素を入れる
c=1 #1からの連番にするため
for i in range(h): #行を回す
for j in range(w): #列を回す
a[i][j]=c #a[0][0]]なら1を再代入a[3][4]なら20を再代入
c+=1 #カウントを1つずつ増やす
#2次配列aを半角スペース区切りで出力
for i in range(h):
for j in range(w):
if j<w-1
print(a[i][j],end=" ")
else:
print(a[i][j])
縦
# coding: utf-8
h=4 #行
w=5 #列
a=[[0]*w for _ in range(h)] #2次配列の宣言と空の要素を入れる
c=1 #1からの連番にするため
for i in range(w): #列を回す
for j in range(h): #行を回す
a[j][i]=c #a[0][1]]なら22を再代入a[0][3]なら4を再代入
c+=1 #カウントを1つずつ増やす34
#2次配列aを半角スペース区切りで出力
for i in range(h):
for j in range(w):
if jj<w-1:
print(a[i][j],end=" ")
else:
print(a[i][j])
斜め(上方向)
行の数値が0,1,2,3と一つずつ増えているのと列の数値も1ずつ増えている。
外側のループを行の長さでまわす
内側のループは1回2回3回・・と1回ずつ増やした回数で列でまわす。
1回ずつ増やして列の長さを超えるとエラーになるので列の長さを超えないようにする。
外側のループ変数 i が0の時は iに1を足した 1に iが1の時は1を足して
2にと i +1 とする そして列の長さを超えないように 列の長さと比べて
i +1が小さいうちは i+1を i+1がれつより大きければ列の長さにする。
ループのレンジを min(i+1, w)とする。
今回の例だと行の長さの方が短いから列の長さを超えないが
行の長さが列よりも大きいと列の長さを超えるので色々なパターンを
考えて設定する。
a[行番=i][列番=j] a[2][0] a[1][1] a[0][2] を見たときに
行が iが i-j 列が jとなっていることがわかる。
iが2の時 行番が 2-0 2-1 2-2となっている 上方向に行が移動するので
行番を1ずつ小さくしている。
列はjが0~1ずつ増えていくので列番はjとする
# coding: utf-8
h=4 #行
w=5 #列
a=[[0]*w for _ in range(h)]
c=1
for i in range(h):
for j in range(min(i+1,w)):
a[i-j][j]=c
c+=1
#2次配列aを半角スペース区切りで出力
for i in range(h):
for j in range(w):
if j<w-1:
print(a[i][j],end=" ")
else:
print(a[i][j])
出力すると
# coding: utf-8
h=4 #行
w=5 #列
a=[[0]*w for _ in range(h)]
c=1
for i in range(h):
for j in range(min(i+1,w)):
a[i-j][j]=c
c+=1
for i in range(1,w):
for j in range(min(h,w-i)):
a[h-1-j][i+j]=c
c+=1
#2次配列aを半角スペース区切りで出力
for i in range(h):
for j in range(w):
if j<w-1:
print(a[i][j],end=" ")
else:
print(a[i][j])
1 3 6 10 14
2 5 9 13 17
4 8 12 16 19
7 11 15 18 20 と出力されます。
最後に逆方向の斜め
斜め(左下方向)
さっきののと反対なだけなので最初に斜めにする処理の仕方が
解っているなら簡単です。
上半分は
外側のループを列でまわす 内側のループを行の長さか i+1の小さい方でまわす
a[j][i-j]とする a[0][0-0] a[0][1-0]a[1][1-1].....となる。
下半分は
外側を行でまわす。内側を行の長さか h-i の小さい方で回す
a[i+j][w-1-j]とする a[0+0][5-1-0]a[0+1][5-1-1]...となる。
# coding: utf-8
h=4 #行
w=5 #列
a=[[0]*w for _ in range(h)]
c=1
for i in range(w):
for j in range(min(i+1,h)):
a[j][i-j]=c
c+=1
for i in range(1,h):
for j in range(min(h-i,w)):
a[i+j][w-1-j]=c
c+=1
#2次配列aを半角スペース区切りで出力
for i in range(h):
for j in range(w):
if j<w-1:
print(a[i][j],end=" ")
else:
print(a[i][j])
1 2 4 7 11
# coding: utf-8
h,w,d=map(int,input().split())
a=[[0]*w for _ in range(h)]
c=1
if d==1:
for i in range(h):
for j in range(min(i+1,w)):
a[i-j][j]=c
c+=1
for i in range(1,w):
for j in range(min(h,w-i)):
a[h-1-j][i+j]=c
c+=1
elif d==2:
for i in range(h):
for j in range(w):
a[i][j]=c
c+=1
elif d==3:
for i in range(w):
for j in range(h):
a[j][i]=c
c+=1
else:
for i in range(w):
for j in range(min(i+1,h)):
a[j][i-j]=c
c+=1
for i in range(1,h):
for j in range(min(h-i,w)):
a[i+j][w-1-j]=c
c+=1
for i in range(h):
for j in range(w):
if j<w-1:
print(a[i][j],end=" ")
else:
print(a[i][j])
1なら斜め右上2なら横・・・。
これで完成です(`・ω・´)
コメント
0 件のコメント :
コメントを投稿