Delphi Sunday Programming 2

相性占いで学ぶ
文字列処理

相沢 絹恵 AIZAWA KINUE


 この連載では,Delphiサンデープログラマ(特にビギナー)を対象に,手軽に楽しめる(なおかつ実用的な)プログラミングの数々を各回読み切りで紹介しています.

● はじめに
 今回は,ちょっと軽めに,相性占いのプログラムを通して文字列処理について考えてみたいと思います.相性占いといってもいろいろ種類がありますが,ここでは名前を数値化して2人の数値から相性を計算するという占いです.

占いの方法

 まず,占いについて解説します.最初に,2人の運命数を求めます.運命数とは占う相手の名前を数字に置き換えたものです.置き換え方ですが,あ段が1,い段が2,う段が3,え段が4,お段が5,んが6です.ですから,多田健さんと須田真理さんの場合は,

   多田 健(TADA KEN)さんの運命数   1146
    須田真理(SUDA MARI)さんの運命数  3112

になります.これを男性,女性の順に並べるとスタートする数字になります.
 つまり,11463112が処理を開始する数字となります.
 次に,この並んだ数字ですが,隣り合った2つの数字を足した数字を並べたものを次の数字とします.この際,4と6のように足すと2桁になるものは一の位を次の数字とします.この場合は,0となるわけです.これを2桁になるまで繰り返します.

11463112
2509423
759365
24291
6610
271
98

 この2桁の数字が相性です.つまり,多田健さんと須田真理さんの相性は98%ということになります.この占いでは2人の相性は0%(00)〜99%(99)までの範囲になります.プログラムではこの過程をすべて見せてくれます(図2-1).

<図2-1>実行結果
Delphig1.jpg (26624 バイト)

プログラム(リスト2-1)の解説

 プログラムのポイントは2つです.1つは運命数の生成であり,もう1つは相性の計算です.これらを順を追って考えてみましょう.

● 運命数の生成
 まず,運命数の生成ですが,名前の入力を何で行うかということから考えなくてはなりません.漢字の場合は,読み方が一通りではないので都合が悪いです.というと,ひらがな,カタカナ,ローマ字ということになります.
 今回は,あ段い段う段え段お段がAIUEOとして入力した文字の中に出てくるローマ字を採用することにします.ローマ字入力の場合,基本的にはAIUEO以外の文字が無視できます.
 例えば,藤田さんの場合,FUJITAはUIAと考えて321とすることができます.これをプログラムにすると次のようになります.

  ss := ' ';
  for i := 1 to Length(s) do begin
    if Pos(s[i], 'AIUEO') > 0 then ss := ss
             + IntToStr(Pos(s[i], 'AIUEO'));
  end;

 sに変換前のローマ字が入っていて,変換後の数字がssに入ります.sに文字列が入っているときs[1]は1文字目の文字,s[2]は2文字目の文字になるので,それをうまく利用して1文字目から文字列の長さに当たる文字まで1文字ずつ調べています.
 Pos関数は文字列の位置を調べる関数です.これを利用してs[i]が 'AIUEO'のどの位置にあるか調べているのですが,うまいことにAが1,Iが2,Uが3,Eが4,Oが5になります.
 しかし,これだけでは不十分です.というのはYの処理とNの処理が必要だからです.
 Yは,や行のローマ字に使われます.この場合は無視してかまいません.しかし,「にゃ」や「じょ」のように「い段+小さいや行」の場合にも使用されます.この場合,Yは2として処理しなくてはなりません.では,どういう場合がや行か考えてみると,AIUEOの次に来るYはや行のYであることがわかります.そこでAIUEO以外の文字の次にYがきた場合は「い段+小さいや行」のYと考えて,Yを2として扱います.

  if Pos(s[i], 'AIUEO') = 0 then
    if s[i + 1]='Y' then ss := ss + '2';

 Nの場合も,な行のNと「ん」のNの区別が必要です.な行のNは,Nの次にAIUEOYが来るので,それ以外の場合を「ん」として処理し6に置き換えています.

  if s[i]='N' then
  if Pos(s[i + 1], 'AIUEOY')=0 then ss := ss + '6';

 これで置き換えは終わりました.

● 相性の計算
 次に,相性の計算です.例えば,1文字目と2文字目の文字の処理を考えてみます.1文字目はs[1],2文字目はs[2]に入っています.これはあくまで文字ですので,StrToIntで数字にします.その後,2つの数字を足して一の位を取り出します.一の位の取り出し方ですが,10で割った余りを計算しています.これを文字に変換すれば,次の段の文字の先頭になります.これを,2文字目と3文字目,3文字目と4文字目…と最後の文字まで繰り返せばよいわけです.

  ss := ' ';
  for i := 1 to Length(s) - 1 do
   ss := ss + IntToStr((StrToInt(s[i])
              + StrToInt(s[i + 1])) mod 10);
  result := ss;

 繰り返しが,(文字列の長さ−1)までですが,これは(文字列の長さ−1)文字目の文字と最後の文字を処理するのが一番最後の処理だからです.
 フォームのデザイン画面を図2-2に示します.重要なのは,名前を入力する2つのエディットコントロール(Edit1,Edit2)と結果を表示するメモコントロール(Memo1),相性を計算するボタンコントロールです(Button1).ボタンが押されると,2人の運命数を計算し,結合,あとは2桁になるまで次の段を計算しつづけるプログラムを書けば完成です.

<図2-2>デザイン画面
Delphig2.jpg (27837 バイト)

● さいごに
 いかがでしたか,文字列を文字の配列と考えて先頭から1文字ずつ処理していく方法がよく理解できたと思います.命令の解析や数式処理などにはこの技術が不可欠です.
 ところで,今回はアルファベットと数字だけだったので1バイトずつ処理したのですが,日本語の処理の場合は1バイト文字と2バイト文字が存在するので,1文字ずつ処理するということが1バイトずつ処理するということと違ってきますので注意してください.


copyright 1999 相沢 絹恵 AIZAWA KINUE