2017年5月5日金曜日

[UWSC]配列のサイズを変更する二【要素を挿入・追加】

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

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

記事の内容

○配列に要素を挿入・追加

前回の配列の削除に続き、追加です。


配列に要素を挿入・追加して綺麗な配列を再構築

配列の要素を追加

配列に要素を挿入・追加し、配列を綺麗に再構築しておく手順です。
使用する関数のソースは、
FUNCTION arry_append(a[],an,dt)
   j=0
   find=0
   DIM b[ubound(a)+1]
for i=0 to ubound(b)
 if an=-1 and i>ubound(a)
    b[j]=dt
 else
  if find=0
   if i=an
    b[j]=dt
    find=1
   else
    b[j]=a[i]
   endif
  else
    b[j]=a[i-1]
  endif
   j=j+1
 endif
next
   RESULT=SLICE(b,0,LENGTH(b)-1)
FEND

呼び出し側は(“ARRY[]”という配列を使っている場合)
   dmy=arry_append(ARRY,3,"poku")//←最後に追加する場合“3”の部分に-1指定
   DIM ARRY[ubound(dmy)]
  for i=0 to ubound(dmy)
   ARRY[i]=dmy[i]
  next
とします。
使用する場合には、3ヶ所の“ARRY”を目的の配列名に書き直します。


プログラムの説明

まず関数内のプログラムの説明を。
この関数の中でb[]というa[]より一つ要素の大きな配列を宣言して、a[]の要素をコピーするための箱として使用します。挿入するべき要素番号かどうかは10行目のif文で判断します。また0から順番に処理して行くので、既に挿入済かどうかを覚えるfindという変数を定義して制御していきます。

関数内のプログラム(○⇒:成り立つ場合、×⇒:成り立たない場合)
2~4行目
j=0
find=0
DIM b[ubound(a)+1]
以降使用する変数の初期値を代入。配列b[]は渡された配列a[]より一つサイズの大きいものを宣言します。(1要素を追加する関数なので)
変数findは既に要素を挿入済かどうかを覚えるフラグ。
(配列要素番号を0から順番に処理して行くので既に挿入したかどうかを判断するために使用します。)
※ubound(配列名)というのはポク太郎の自作関数で、“渡された配列の最大要素数”を返す関数。
5、21行目 for i=0 to ubound(b)
next
変数iを0から1づつ増やして配列の最大要素数までループさせます。
6、8、20
行目
 if an=-1 and i>ubound(a)
 else
 endif
if条件文は、an(:挿入・追加しろと渡された要素番号)が-1、かつ、配列の最大要素より大きい場合。
(○⇒7行目を実行)
  b[j]に渡されたデータdtを代入。
(×⇒else以降9~19行目を実行。)
  ↓参照
9~18行目
  if find=0
   if i=an
    b[j]=dt
    find=1
   else
    b[j]=a[i]
   endif
  else
    b[j]=a[i-1]
  endif
if条件文は、変数findが0かどうか。
○⇒10~15行目を実行)

  if条件文は、指定された挿入位置anと変数iが等しいかどうか、
  (○⇒)      新配列b[j]にデータdtを代入、findに挿入した由を記憶。
  (×⇒)    新配列b[j]にa[i]を代入。

×⇒else以降17行目を実行。)
  新配列b[j]に一つ要素の小さいa[i-1]を代入
19行目
   j=j+1
いま5、21行目のループで変数iが増加。b[]にa[]を同じ順番で全て代入するのではなく、挿入してしまった後は、新配列の要素番号と元配列の要素番号が異なるので、iを使用せずjという新しい変数を使用。jは20行目を通ったとき(=b[]に一つ代入された)ときしか+1されないので、b[j]にはa[]が順番に代入されていく。
※9~18行目はどの条件で通過してきてもb[]に一つ代入されています。
23行目    RESULT=SLICE(b,0,LENGTH(b)-1)
全要素コピーし終わってループを抜けたら、出来上がった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_append(ARRY,3,"poku")//←最後に追加する場合“3”の部分に-1指定
   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_append(ARRY,3,"poku")とこのプログラムでは“要素数3”に"poku"というデータを代入せよと書いてあります。
★4 目的のブロック(★3)から出た後ARRYの中身がどうかわったか表示するよ。


確認結果
結果 使用前 使用後
an=3指定 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]=3
ARRY[3]=poku
ARRY[4]=4
ARRY[5]=5
ARRY[6]=6
ARRY[7]=7
ARRY[8]=8
ARRY[9]=9
ARRY[10]=10
an=0指定 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]=poku
ARRY[1]=1
ARRY[2]=2
ARRY[3]=3
ARRY[4]=4
ARRY[5]=5
ARRY[6]=6
ARRY[7]=7
ARRY[8]=8
ARRY[9]=9
ARRY[10]=10
an=-1指定 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]=3
ARRY[3]=4
ARRY[4]=5
ARRY[5]=6
ARRY[6]=7
ARRY[7]=8
ARRY[8]=9
ARRY[9]=10
ARRY[10]=poku
an=15指定 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]=3
ARRY[3]=4
ARRY[4]=5
ARRY[5]=6
ARRY[6]=7
ARRY[7]=8
ARRY[8]=9
ARRY[9]=10
ARRY[10]=poku

anの指定によって、挿入される位置が変わっていますね。
-1を指定しても、配列の最大要素より大きな値を指定しても同じ結果になるようにしました。
(意図してない使い方だよと警告するために、後者の場合にエラーを出すよう改良してもよいかもしれません。)



前回の配列の要素を削除とともにこうしておくことでメインのソースには4行だけ書くことになるので多少スッキリします。


記事の内容

記事の内容は伝わりましたでしょうか。
○配列に要素を挿入・追加


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


【関連記事】  [UWSC]配列のサイズを変更する一【要素を削除】
[UWSC]iniファイルを扱う関数
[UWSC]画像が表示された中心座標を返す関数
[UWSC]BMP画像の幅と高さを得る関数


スポンサーリンク



blogramのブログランキング

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


0 件のコメント:

コメントを投稿