次へ: 6 その他の部分 上へ: AWK による簡単なタイプ練習ソフト 前へ: 4.4 ユーザ定義関数化 (PDF ファイル: awk2.pdf)


5 入力チェック関数

次は、おおまかな設計図の (4) の課題と入力の違いの比較を行う関数を作成します。 引数として、$s_1$ = 文字列 1 (課題文字列)、$s_2$ = 文字列 2 (入力文字列) を与え、その違いの数を返す関数を作ることにします。

簡単に言えば、4.3 節でやったように 文字列を 1 文字ずつの配列に展開し、 それを先頭から比較していけばいいのですが、 その前に、関数の仕様について、もう少し細かく検討しておきます。

$s_1$ の長さ (= $N_1$ とします) と $s_2$ の長さ (= $N_2$ とします) が等しいときはそれでいいのですが、 違うときも考えておく必要があります。

例えば、単純に 1 番目から $N_1$ 番目までの比較しかしないのだとすると $N_1<N_2$ で、1 番目から $N_1$ 番目までは全く同じだけど、 その後に余計な文字列がついている、という場合もありえます。 それはタイプ練習ソフトとしては正解とはいい難いと思います。よって、

とするのが自然だと思います。

すなわち、文字列の短い方に合わせて比較し、そこまでの違い (= diff) と、 その余りの分、つまり $N_1$$N_2$ の差 ($=L$) とを足したものを 返せばいいことになります。

よって、おおまかには次のような関数を作ればいいことになります。

  function check(s1,s2,  h1,h2,N1,N2,N,L,j,diff)
  {
      # s1 を配列 h1 に展開 (N1 がその長さ)
      # s2 を配列 h2 に展開 (N2 がその長さ)
      # N = N1 と N2 の小さい方
      # L = N1 と N2 の差 (=|N1-N2|)
      for(j=1;j<=N;j++) if(h1[j]!=h2[j]) diff++
      return diff+L
  }
C 言語同様、!= は「等しくない」ことを表します。 diff は局所変数で、明示的に初期化しなければ 0 と初期化されますから、 この for 文で、短い方に合わせての比較が行えることになります。

最初の配列に展開する部分は、4.3 節で説明したように、

N1=split(s1,h1,"")
N2=split(s2,h2,"")
とすれば済みますし、$N$$L$ も、
if(N1<=N2) N=N1; L=N2-N1
else N=N2; L=N1-N2
で設定できます。


次へ: 6 その他の部分 上へ: AWK による簡単なタイプ練習ソフト 前へ: 4.4 ユーザ定義関数化
竹野茂治@新潟工科大学
2006年4月27日