2017年5月4日木曜日

[UWSC]配列のサイズを変更する一【要素を削除】

UWSCで配列変数を用いる場合に必要になるリサイズ(削除)のやり方をまとめました。

初心者のプログラミング導入のため、簡単な自作関数を作って公開しているブログ。配列の要素を削除し、配列をリサイズしてしまう方法について書きました。(関数ではないです)

記事の内容

○配列の要素を削除

プログラムを作る際にはサラッと短いコードで見やすくするのが基本です。
なぜかというと、1ステップ1ステップ全てに意味があるので、これは何だっけ?と常に再考する必要があるからです。

そのためによく使うのはループ。
ループを使うにはやっぱり要素番号を指定して使える配列変数が便利です。

というわけで、配列変数をもうちょっと使いこなしましょう。


配列の要素を削除して綺麗な配列を再構築してしまう

配列の要素を削除

配列の要素を削除し、順番を詰めて綺麗な配列を再構築する手順を作りました。
使用する関数のソースは、
FUNCTION arry_remove(a[],rn)
   j=0
   DIM b[ubound(a)-1]
 if rn>ubound(a)
   RESULT=SLICE(a,0,LENGTH(a)-1)
   PRINT "ポクエラー(arry_remove関数):最大要素数より大きな要素が削除指定されました。"
 else
  for i=0 to ubound(a)
   if i=rn
   else
    b[j]=a[i]
    j=j+1
   endif
  next
   RESULT=SLICE(b,0,LENGTH(b)-1)
 endif
FEND

呼び出し側は(“ARRY[]”という配列を使っている場合)
   dmy=arry_remove(ARRY,2)
   DIM ARRY[ubound(dmy)]
  for i=0 to ubound(dmy)
   ARRY[i]=dmy[i]
  next
とします。
使用する場合には、3ヶ所の“ARRY”を目的の配列名に書き直します。


プログラムの説明

まず関数内のプログラムの説明を。
ubound(配列名)というのはポク太郎の自作関数で、“渡された配列の最大要素数”を返す関数。
この関数の中でb[]というa[]より一つ要素の少ない配列を宣言して、a[]の要素のうち必要なものだけをコピーするための箱として使用します。必要な部分かどうかは4~16行目のif文で判断します。

関数内のプログラム
1~2行目 以降使用する変数の初期値を代入。配列b[]は渡された配列a[]より一つサイズの小さいものを宣言します。(1要素を削除する関数なので)
4行目 if条件文は、rn(:削除しろと渡された要素番号)が、削除対象の配列a[]の最大要素数より大きい場合。
(成り立つ⇒5~6行目を実行、成り立たない⇒else以降。)
5~6行目 削除するべきものがないのでa[]をそのまま返す。また、使用法が間違っているのでエラーを表示。
7行目 else文。
8、14行目 iを変数として、0→a[]の最大要素までループさせる。
9行目 if条件文はi=rn。つまり、指定された番号(削除したい番号)の場合。
(成り立つ⇒何もしない、成り立たない⇒else以降。)
11~12行目 b[j]にa[i]を代入。その後jを+1する。
(いま8、14行目のループでiが増加。b[]にa[]を同じ順番で全て代入するのではなく、削除したい番号は抜いて詰めたいので、iを使用せずjという新しい変数を使用。jは12行目を通ったとき(=b[]に一つ代入された)ときしか+1されないので、b[j]にはa[]が順番に代入されていく。
15行目 全要素コピーし終わってループを抜けたら、出来上がったb[]を関数の戻り値として返す。

呼び出し側のプログラム
1行目 dmyという配列に関数の戻り値を代入。
2行目 綺麗にしたい目的の配列をdmyと同じ要素数に宣言し直し。
3~5行目 目的の配列へ関数の戻り値をコピー。


動作確認しながら仕様を理解

動作確認

★1、2、4を準備して動作確認します。
//★1 --
   DIM ARRY[9]
  for i=0 to 9
   ARRY[i]=i+1
  next
//-- ★1
//★2 --
   print "使用前"
  for i=0 to ubound(ARRY)
   print "ARRY["+i+"]="+ARRY[i]
  next
//-- ★2

//★3 --
   dmy=arry_remove(ARRY,2)
   DIM ARRY[ubound(dmy)]
  for i=0 to ubound(dmy)
   ARRY[i]=dmy[i]
  next
//-- ★3

//★4 --
   print "使用後"
  for i=0 to ubound(ARRY)
   ARRY[i]=dmy[i]
   print "ARRY["+i+"]="+ARRY[i]
  next
//-- ★4
確認用プログラム
★1 確認に使うためにARRYという配列変数に適当な値入れておくよ。
★2 目的のブロック(★3)に入る前にARRYの中身がどうなってるか表示しておくよ。
★3 今動作確認をしたい呼び出しコードだよ。
dmy=arry_remove(ARRY,2)とこのプログラムでは“要素数2”を削除してみようと思います。
★4 目的のブロック(★3)から出た後ARRYの中身がどうかわったか表示するよ。


確認結果
結果 使用前 使用後
結果 ARRY[0]=1
ARRY[1]=2
ARRY[2]=3
ARRY[3]=4
ARRY[4]=5
ARRY[5]=6
ARRY[6]=7
ARRY[7]=8
ARRY[8]=9
ARRY[9]=10
ARRY[0]=1
ARRY[1]=2
ARRY[2]=4
ARRY[3]=5
ARRY[4]=6
ARRY[5]=7
ARRY[6]=8
ARRY[7]=9
ARRY[8]=10

元々、3が入っていたARRY[2]がなくなって順番に詰めていかれましたね。

rnの値を変更して動きを確認してみてください。



綺麗な状態にしておきたい配列はクラスでも作ってグローバルで管理した方がよいのですが、ループの作り方の例題として配列の操作は向いてるかなと思い作ってみました。

ただ、呼び出し側が4行あり、再利用の際には3ヶ所書き換え要。と余りスッキリしないコードになってしまいました。
もっとスマートなやり方誰か教えてください。


記事の内容

記事の内容は伝わりましたでしょうか。
○配列の要素を削除


関数群のダウンロードはこちら
func_poku.uwsのコメント欄に呼び出し方が書いてあります。


【関連記事】  [UWSC]iniファイルを扱う関数
[UWSC]画像が表示された中心座標を返す関数
[UWSC]BMP画像の幅と高さを得る関数
[UWSC]指定画像が表示された座標を返す関数


スポンサーリンク



blogramのブログランキング

目次
コンピュータ(ハード/ソフト) 映画・ドラマ・芸能 変人のつぶやきとトラブル
ホームへ戻る ページ上部へ


0 件のコメント:

コメントを投稿