| 翔太 | :わ! なんだかたくさん同じようなのが並んでるな。 |
| 美咲 | :えーと、どれも変数の宣言ってことでいいのかしら。最初の 2 つの変数には何かのプロパティの値が代入されてるわ。 |
| 翔太 | :あとの 2 つの変数には、「""」が代入されてる。「""」は文字列の何もないということを表わすはずだから、この場合もこの Angou1 と Angou2 という変数には何も文字列が入らないという初期化が行われたって事だね。 |
| 健一 | :ずいぶん、見方がしっかりしてきたね。この調子なら、しばらく黙ってみてることにしようか。 |
| 翔太 | :え、そんなぁ。 |
| 健一 | :冗談、冗談。それじゃ上 2 つでやってることをもう少し詳しく説明してもらおうかな。 |
| 美咲 | :えーっと。1 行目は、Genbun という変数を String 型で宣言して、txtGenbun というテキスト ボックスの Text プロパティを代入してます。これは文字列の変数で、Angou1 や Angou2 と同じね。 |
| 翔太 | :2 行目は、Nagasa という文字列を Integer 型で宣言してる。Integer は整数を扱う型だから、これは数値の変数だね。それで、Genbun 変数の・・・、Length っていうプロパティを代入してる。Length って何のプロパティだろう? |
| 健一 | :Length は長さを表わすプロパティなんだ。この場合は文字の長さ、つまり文字数を表わしている。プロパティやメソッド、クラス、コントロール、コンポーネントなどは、プログラマが自分でつける名前を除けば、基本的に英語で書かれていることがほとんどだ。わからない名前が出てきたら、英和辞典で調べてみるといい。既に知っている単語でも、意外な意味があったりするから面白いよ。 |
| 健一 | :まず、1 行目では、Index1 という変数を新しく Integer 型で宣言して、初期値を 0 に指定している。そして、「For」から「Next」の間にある処理を、「For」の後ろで指定した変数が、「To」の後ろで指定した終了値に達するまで繰り返すという命令なんだ。 |
| 翔太 | :終了値は、「Nagasa – 1 Step 2」? |
| 健一 | :惜しい! この場合の終了値の設定は「Nagasa - 1」まで。Nagasa というのは文字列の長さ、つまり文字数について入れておく変数だったよね。つまり、ここでは文字数よりも 1 つ少ない数になるまで、っていう意味なんだ。 |
| 美咲 | :それじゃ「Step 2」は何を表わしてるの? |
| 健一 | :繰り返す回数に関係しているんだ。For から始まるこの書き方は、ループ文と呼ばれている。 |
| 翔太 | :ループ? ループって・・・、ジェットコースターとかに出てくる奴? |
| 健一 | :そういえばそういうのもあるね。ループというのは元々「輪」という意味があるんだ。ジェットコースターもぐるっと一回転する奴にループってついてるはずだし、今回のループ文の場合も、輪のように同じ範囲を回転して行ったり来たりするプログラムのことをいうんだよ。 |
| 翔太 | :つまり、指定した条件に達するまで同じことを繰り返すからループ、っていうことなのか。 |
| 健一 | :そういうこと。「回転」する回数だけど、もし「Step 2」というのがなければ、このサンプルの場合は、Index1 という変数が 0 から 1 ずつ増えていって、文字数より 1 つ少ない数に達するまで、という作業になる。ところが、「Step 2」という記述があると・・・ |
| 美咲 | :・・・もしかして、Index1 変数が 2 ずつ増えるの? |
| 健一 | :そのとおり! 1 回ループする度に、Index1 に 1 を加える作業を 2 度行う、つまり 2 を足す、という指示になってるんだ。 |
| 翔太 | :なるほど! それで 2 行目の処理をして、3 行目の「Next」は? |
| 健一 | :「Next」は「For」で始まる行で指定した変数の値の変化が、指定した終了値に達するまで、「For」と「Next」の間にある行の処理をしなさい、という意味になるんだよ。 |
| 美咲 | :へえー、条件分岐の「End If」と同じ役目を持ってるのね。 |
| 健一 | :さっき似ているって言ったのもそういうところだよ。 |
| 翔太 | :なるほどね。それで、問題の処理する命令の中身は・・・、Angou1 に何かを代入してるね。自分自身である Angou1 に「Genbun.Substring(Index1, 1)」を加えてる・・・ |
| 美咲 | :Genbun は原文が入った変数よね。Substring はメソッドかしら、プロパティかしら。 |
| 健一 | :この場合はメソッドだよ。Substiring メソッドは、() で指定した内容を基に、文字列を取出す機能があるんだ。 |
| 翔太 | :文字列を取出す・・・? |
| 健一 | :例えば、一番最初にプログラムを動かした場合を考えてみよう。初めてこのループ文を動かすときには、Index1 の値は? |
| 翔太 | :0 ? |
| 健一 | :そう。だから、Substiring メソッドは「(0, 1)」の範囲の文字列を取出すことになる。この場合、最初の 0 は Genbun 変数内の文字列の何文字目から取出すのか、開始位置を表わす数字になる。0 というのは実は 1 文字目のことを表わしているんだ。そして、0 の隣にある 1 は、開始位置から何文字目までを取出すのかを表わしている。だからこの場合は、Genbun 変数内の 1 文字目から 1 文字まで、つまり 1 文字目だけを取出す、という命令になっている。 |
| 美咲 | :えーっと。文字列から文字を取出して、どうするの? |
| 健一 | :まあまあ、あわてないで。さて、この作業が原文の文字列の文字数と同じ数か、もしくはそれを超えるまで続けられることになる。それも、取出す文字の位置は 1 つ飛ばしで変わっていくんだ。 |
| 翔太 | :どうして 1 つ飛ばしなの? |
| 美咲 | :「Step 2」で Index1 が 2 つずつ増えるから? これだと、Index1 の値が 0、2、4、6 ・・・となるから 1 つ飛ばしになってるわ。 |
| 翔太 | :なるほど。あれ? でもそうすると、「Nagasa -1」と一致しない場合が出てくるよね。長さが偶数で、例えば 6 だったら、6 - 1 = 5 で、5 になるはずなのに、Index1 は 4 の次、2 を足して 6 になっちゃうよ? |
| 健一 | :その場合は、条件を超えたものとみなして、やはりループは終了するんだよ。だからその例では、Index1 の値が 6 になったら、Next の次の行が処理されるんだ。 |
| 翔太 | :そうなんだ。うまくできてるんだなぁ。 |
| 美咲 | :それで、肝心の文字列の取出しの方はどうなるの? |
| 健一 | :それじゃ翔太君の例を使わせてもらうとしよう。原文が 6 文字の文字列の場合、Index1 の値は 0、2、4 の 3 パターン存在することがわかる。だから、この場合、Substirng メソッドが取出す文字列の開始位置も、1 文字目、3 文字目、5 文字目、ということになるんだ。何文字取出すかは 1 のままだから、つまり原文の 1 文字目、3 文字目、5 文字目がそれぞれ Genbun.Substring メソッドの値ということになる。それが、Angou1 に加えられて代入されるんだ。 |
| 翔太 | :だんだん混乱してきちゃった。えーっと、じゃあ、文字列が ABCDEF だったとして考えてみようか。これの 1 文字目は A、3 文字目は C、5 文字目は E だよね。 |
| 美咲 | :うん。それで、1 回目のループでは、Angou1 には何も入っていないから、A がそのまま代入される形になるわね。 |
| 翔太 | :だから 2 回目のループのときは、Angou1 には A が入っていて、そこに今度は 3 文字目の C が結合されるのか。ということは、Angou1 は AC になるんだ。 |
| 健一 | :そう、そして同じことをまた繰り返して、今度は 5 文字目の E が結合されて、ACE になる。これはこのループ文が終了したときの Angou1 の値だね。 |
| 翔太 | :なるほど・・・。うん、なんとなく文字を取出すという流れはわかった気がする。 |
| 美咲 | :そうね。でも、これだと元の文字列の半分になっちゃったわ。 |
| 健一 | :あわてないでって言っただろう? 残りの半分はこれから作るんだよ。 |
| 美咲 | :残りを作る? |
| 健一 | :それじゃ、リスト 7-1-3 の次にリスト 7-1-4 のコードを続けて書いてごらん。 |
| 翔太 | :あ、今度は Index2 を使ってループ文が・・・ |
| 健一 | :さあ、ここでやってるのはどういうことか説明できるかな? |
| 美咲 | :え? でも、変数名が 1 から 2 に変わっただけで、あとは全部一緒なんじゃ・・・ あ! Index2 の初期値が違ってる! |
| 翔太 | :Index2 の初期値? ・・・たしかにこのループ文では 1 になってるね。さっきのループ文の Index1 は 0 だったのに、どうして違ってるの? |
| 健一 | :それはこのループ文を使って取得する文字列を、さっきのループ文とは 1 つずらすためさ。 |
| 美咲 | :1 つずらす? |
| 健一 | :そう、ループ文の Index の値が一度に 2 つ増えるのはどちらも同じだ。ただ、さっきのループ文が 0 から始まって、0、2、4、6 と増えていくのに対して、今度のループ文は 1、3、5、7 と増えていく。ということは・・・? |
| 翔太 | :Index の値が違ったら・・・、Substring メソッドの範囲指定が変わるってこと? |
| 健一 | :正解。つまり、さっきのループ文では、文字を取出す開始位置が原文の文字列の 1 文字目から始まっていた。指定の上では 0 からだけどね。それで、それに対して今度のループ文では、指定の上では 1 から、そして実際には、開始位置が原文の文字列の 2 文字目から文字の取出しが始まることになる。さっきの例でそのまま考えてごらん? |
| 翔太 | :えーっと。ABCDEF の 6 文字が原文の場合、Index2 の値は 1、3、5 の 3 パターン存在することがわかる。 |
| 美咲 | :7 がないのは、「Nagasa」を超えてしまうからね。 |
| 翔太 | :そう。だから、この場合、Substirng メソッドが取出す文字列の開始位置は、2 文字目、4 文字目、6 文字目、ということになる。何文字取出すかは最初のループ文と同じ 1 だから、つまり原文の 2 文字目、4 文字目、6 文字目がそれぞれ Genbun.Substring メソッドの値ということになる。それが、Angou2 に加えられて代入される、と。 |
| 美咲 | :となると、ABCDEF が原文の場合、これの 2 文字目は B 、4 文字目は D、6 文字目は F になって、1 回目のループでは、Angou2 には何も入っていないから、B がそのまま代入されることになるわ。 |
| 翔太 | :それで 2 回目のループのときは、Angou2 には B が入っていて、そこに今度は 4 文字目の D が結合される。だから、この時点で Angou2 は BD になるんだ。 |
| 健一 | :そして 3 回目のループで、今度は 6 文字目の F が結合されて、BDF になる。これが、このループ文が終了したときの Angou2 の値というわけだ。 |
| 翔太 | :すごい! なんかよくわかんないけど、すごいことをやってる気がしてきた! |
| 健一 | :翔太君は、この手のプログラムが好きなタイプみたいだね。それじゃ、続きをいってみようか。それで、やっと全体が見えてくるから。美咲ちゃんも大丈夫かい? |
| 美咲 | :なんとか、ついていってます。でも、よくこんなややこしいこと考えるわね、プログラマの人って。 |
| 健一 | :プログラミングって、何でもできるように見えて実はかなり制限があるんだ。 |
| 美咲 | :制限? |
| 健一 | :そう、例えばパソコンの中で絵を動かしたい、って思っても、今でこそある程度までは簡単にできるようになったけど、それでもまだ考えなきゃいけないことはたくさんある。その制限の中で、どうやればやりたいことがやれるのか、知恵を絞るのがプログラマなんだよ。僕の先輩の一人は、毎日パズルを解いてるようなものだって言ってたくらいだから。 |
| 翔太 | :パズルか・・・。そんな仕事なら楽しそうだな。 |
| 健一 | :プログラマの仕事については、また別の機会に話すとして、とりあえず続きを見てみよう。リスト 7-1-5 を、さっきのリスト 7-1-4 のあとに続けて書き加えてほしい。 |
Public Class Form1
' [暗号化>] ボタンを押したときの処理
Private Sub btnAngou_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAngou.Click
' 原文を格納する変数を用意して
' txtGenbun の Text プロパティ値で初期化する
Dim Genbun As String = txtGenbun.Text
' 原文の長さを格納する変数を用意して
' Genbun の Length プロパティ値で初期化する
Dim Nagasa As Integer = Genbun.Length
' 暗号1 を格納する変数を用意して NULL 文字列で初期化する
Dim Angou1 As String = ""
' 暗号2 を格納する変数を用意して NULL 文字列で初期化する
Dim Angou2 As String = ""
' [暗号1 の文字位置] を表す変数を用意して 0 で初期化し
' [暗号1 の文字位置] が [原文の長さ] - 1 になるまで
' 2 足して行き、繰返し処理を行う
For Index1 As Integer = 0 To Nagasa - 1 Step 2
' 原文から [暗号1 の文字位置] にある 1 文字を取出し
' 暗号1 に結合させる
Angou1 = Angou1 + Genbun.Substring(Index1, 1)
Next
' [暗号2 の文字位置] を表す変数を用意して 1 で初期化し
' [暗号2 の文字位置] が [原文の長さ] - 1 になるまで
' 2 足して行き、繰返し処理を行う
For Index2 As Integer = 1 To Nagasa - 1 Step 2
' 原文から [暗号2 の文字位置] にある 1 文字を取出し
' 暗号2 に結合させる
Angou2 = Angou2 + Genbun.Substring(Index2, 1)
Next
' 暗号1 と暗号2 を結合したものを txtAngou の Text プロパティに設定する
txtAngou.Text = Angou1 + Angou2
End Sub
End Class
|
' 暗号文を格納する変数を用意して
' txtAngou の Text プロパティ値で初期化する
Dim Angou As String = txtAngou.Text
' [暗号文の長さ] を格納する変数を用意して
' Genbun の Length プロパティ値で初期化する
Dim Nagasa As Integer = Angou.Length
' 原文を格納する変数を用意して NULL 文字列で初期化する
Dim Genbun As String = ""
' [暗号1 の長さ] を格納する変数を用意して
' [暗号文の長さ] を半分にした長さを代入する
Dim Nagasa1 As Integer = Nagasa - Int(Nagasa / 2)
' [暗号2 の長さ] を格納する変数を用意して
' [暗号文の長さ] から [暗号1 の長さ] を引いた長さを代入する
Dim Nagasa2 As Integer = Nagasa - Nagasa1
' 暗号1 を格納する変数を用意して
' 暗号文の 1 文字目から Nagasa1 文字目までの文字列を代入する
Dim Angou1 As String = Angou.Substring(0, Nagasa1)
' 暗号2 を格納する変数を用意して
' 暗号文の Nagasa1 文字目から Nagasa2 文字目までの文字列を代入する
Dim Angou2 As String = Angou.Substring(Nagasa1, Nagasa2)
|
| 翔太 | :あれ? さっきの暗号化の処理とはまた微妙に違う気がするな。 |
| 美咲 | :違ってる部分もそうだけど、同じ変数名が出てきてるわ。これは問題ないのかしら。 |
| 健一 | :うん、さっきの暗号化処理の部分とは、変数を使う範囲が異なっているからね。この場合は問題ないんだ。そもそも、このプログラム自体が、暗号化と解読を同時にやるようにはできてないからね。 |
| 翔太 | :ふーん。 |
| 健一 | :とりあえず順に見て行こうか。まず 1 行目。これはさっきも出てきた中央のテキスト ボックスの Text プロパティの値を、新しく String 型で宣言した Angou という変数に代入している。 |
| 翔太 | :Angou に数字をつけなくてもいいの? |
| 健一 | :変数名同士で区別がつけばいいから、数字がつくものとつかないものがあってもいいんだよ。それにこの場合、txtAngou.Text の中身は、Angou1 と Angou2 を結合したものだろう? だったら、暗号全体を表わす変数ということで、あえて番号をつけない Angou という変数名を使うことで区別する、という意味もあるんだよ。 |
| 美咲 | :なるほど。 |
| 翔太 | :2 行目と 3 行目はさっきとほとんど同じだね。Nagasa っていう変数に Angou の文字数を設定してるのと、原文にあたる Genbun 変数の初期値を何もない状態にしているんだ。 |
| 健一 | :この場合の Genbun 変数は少し注意が必要だね。原文ということで、解読する対象、つまり暗号文だと思いがちだけど、ここは元通りの意味で、暗号化される前の本来の文、として用意された変数なんだ。 |
| 翔太 | :じゃあ、解読結果をここに入れるってこと? |
| 健一 | :そうなるね。さて、ここまでが前半だ。後半の 4 行はちょっとややこしいぞ。まず、Nagasa1 は、暗号文全体の長さを半分にした長さを代入している。これは、暗号化の際に、最初のループ文で設定した暗号の文字列の長さと同じだ。なぜなら、原文から 1 つ飛ばしで 1 文字ずつ取出した文字列だから。計算式では、暗号文全体の長さを 2 で割った整数の値を代入しているんだけど、この Int() というのは割り算の整数の値を出す命令になる。 |
| 翔太 | :それじゃ、Nagasa2 はもう 1 つのループ文の暗号の長さってこと? |
| 健一 | :そう。2 つの暗号文の長さを足したものが、全体の長さになるはずだから、ここでは全体から Nagasa1 の長さを引いた値を代入している。 |
| 美咲 | :ちょっと待って。そうすると、残りの Angou1 は、Substring メソッドで、開始位置 0 つまり 1 文字目から Nagasa1 の値分までを代入してるから、そのままさっきのループ文で作った Angou1 ってことになるんじゃない? そうして、Angou2 は・・・ |
| 翔太 | :Nagasa1 の文字数の値を開始位置、ってことはその 1 つ上の数字から始まって、Nagasa2 の値分までを代入してるから、これもさっきの後半のループ文で設定した Angou2 と同じだ。 |
| 健一 | :そう、ここでやっているのは、さっき苦労して大元の文字列からバラバラに取出して 1 つにまとめた文字列から、処理の途中の変数の値まで引き戻す作業なんだ。さっきの ACEBDF の例で考えてみよう。文字数、つまり Nagasa は 6 文字あるから、Nagasa1 と Nagasa2 はそれぞれ 3 だ。つまり、前半 3 文字と後半 3 文字ということになる。 |
| 翔太 | :ということは、ここまで処理した時点で、Angou1 には前半の文字列である ACE、Angou2 には後半の文字列である BDF がそれぞれ代入されていることになるんだね。 |
| 健一 | :その通り。ここまでの流れは大丈夫かな? ここからさらに複雑になるから、よくおさらいした上で、次のコードを入力してみよう。 |
' [暗号2 の文字位置] を表す変数を用意して 0 で初期化する
Dim Index2 As Integer = 0
' [暗号1 の文字位置] を表す変数を用意して 0 で初期化し
' [暗号1 の文字位置] が [暗号1 の長さ] - 1 になるまで繰返し処理を行う
For Index1 As Integer = 0 To Nagasa1 - 1
' 暗号1 から [暗号1 の文字位置] にある 1 文字を取出し
' 原文に結合させる
Genbun = Genbun + Angou1.Substring(Index1, 1)
' [暗号2 の文字位置] が [暗号2 の長さ] を超えていないか判断する
If Nagasa2 > Index2 Then
' [暗号2 の長さ] より [暗号2 の文字位置] が小さいときの処理
' 暗号2 から [暗号2 の文字位置] にある 1 文字を取出し
' 原文に結合させる
Genbun = Genbun + Angou2.Substring(Index2, 1)
' [暗号2 の文字位置] を 1 つ進める
Index2 = Index2 + 1
End If
Next
|
| 翔太 | :・・・こ、これって、もしかしてループ文と条件分岐が一緒になってるんじゃ・・・ |
| 健一 | :そうなんだ。ちょっとややこしいから、よく考える必要がある。 |
| 翔太 | :うわ・・・。大変だな、これは。 |
| 美咲 | :・・・よし、やってみるわね。えーっと、最初に Index2 という変数を整数で宣言して、0 を代入してるわ。Index2 はさっきのループ文で使ってた変数とは別物ってことなのよね? |
| 健一 | :美咲ちゃん、気合入ってるね。そう、この場合は、Substring メソッドの範囲指定の目印に過ぎない。ちなみに、Index2 は、後半の Angou2 の方の文字列の解読を始める位置に使われている。ループ文と関係してくるのは、2 行目に出てくる Index1 の方。こちらは、前半の Angou1 の方の文字列の解読を始める位置に使われている。 |
| 翔太 | :それじゃ、ループ文の頭から見て行こうか。最初に、Index1 変数が Integer 型で宣言され、初期値として 0 が代入されている。そして、Angou1 変数の長さでもある Nagasa1 変数の値から 1 を引いた数まで、ループが繰り返される、となってるみたいだ。しかも、今回は「Step 2」がないから、1 回のループで 1 つずつ Index1 が増えていくことになるようだね。 |
| 美咲 | :そして、2 行目では、早くもその Index1 の値を使って、文字列の取出しが行われてるわ。最初のループでは、開始位置 0 からだから、Angou1 の 1 文字目から 1 文字取出して、Genbun 変数に代入してることになるのね。 |
| 健一 | :そう、さっきの「ABCDEF」の例で考えてみよう。暗号化によって、「ACE」と「BDF」に分かれたあとで 2 つの文字列は結合して「ACEBDF」になったんだったね。今回は、それをまた 2 つに分けたところから始まってる。このループの最初の段階では、Angou1 には「ACE」が入っていて、その 1 文字目から 1 文字分だから、「A」が取出されて、Genbun に代入されている。続けて、条件分岐の中身を見ていこう。 |
| 翔太 | :条件分岐の 1 行目の条件式では、暗号文の後半の長さである Nagasa2 の値が、Index2 よりも大きければ、条件を満たすことになり、その次の行が処理されるように記述されている。つまり、一番最初のループでは、Index2 は 0 のままだから、当然この条件式は満たされるよね。そして、Angou1 と同じように、Angou2 も Substing メソッドで文字列を取出されて、Genbun に結合されてるのか。でも、これだと Index2 は 0 で Index1 と同じだから、開始位置も同じになっちゃうんじゃない? 暗号化のときは Index2 は 1 から始まってたよね。 |
| 美咲 | :それは、暗号化のときは元々の原文から文字列を取出してたからよ。今回は、あらかじめそこから半分取出した文字列が相手だから、開始位置が 0 からでもいい、ってことよね、健一さん? |
| 健一 | :そのとおり! ここは同じ名前を使っているから勘違いしやすいんだけど、暗号化のときと、解読のときでは違うものだということをよく頭に入れておく必要があるんだ。 |
| 翔太 | :えーっと、ということはさっきの例で言うと、「BDF」の 1 文字目から 1 文字ずつ取っていくっていうことになるのかな。 |
| 健一 | :そうそう、その調子! |
| 翔太 | :だから、1 回目のループでは、「BDF」の 1 文字目である「B」が取出されて、Genbun に結合され・・・、あれ? 待てよ。さっきの時点で、Genbun には「A」が代入されてたんだよな。そこに「B」が結合されると・・・ |
| 美咲 | :「AB」だわ。すごい! ちゃんと元の文字列に近づいてる! |
| 健一 | :だんだんわかってきたようだね。ところで、Genbun に文字列を代入した次の行を忘れちゃだめだよ。 |
| 翔太 | :「Index2 = Index2 + 1」? これは、Index2 の値を 1 つ増やしてるんだね。 |
| 健一 | :そう、今回、Index2 は For で始まるループ文本体で使っているわけではないから、自動的に値が増えたりしないんだ。だから、こうやって命令の中で明確に値を増やしてあげないといけないんだよ。 |
| 翔太 | :こうやって変数の数を増やしていくのは、ラーメンタイマーや数当てゲームでもやってきたけど、あれがここでも使われてるんだね。 |
| 健一 | :そう、この書き方はとても重要な書き方だって、言ったとおりだろう? さて、このループ文と条件式は、Angou1 と Angou2 の文字数分だけそれぞれ処理し終わったら、終了するようになっている。そして、終了したところで、最後にこの行を処理するんだ。 |
Public Class Form1
' [暗号化>] ボタンを押したときの処理
Private Sub btnAngou_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAngou.Click
' 原文を格納する変数を用意して
' txtGenbun の Text プロパティ値で初期化する
Dim Genbun As String = txtGenbun.Text
' 原文の長さを格納する変数を用意して
' Genbun の Length プロパティ値で初期化する
Dim Nagasa As Integer = Genbun.Length
' 暗号1 を格納する変数を用意して NULL 文字列で初期化する
Dim Angou1 As String = ""
' 暗号2 を格納する変数を用意して NULL 文字列で初期化する
Dim Angou2 As String = ""
' [暗号1 の文字位置] を表す変数を用意して 0 で初期化し
' [暗号1 の文字位置] が [原文の長さ] - 1 になるまで
' 2 足して行き、繰返し処理を行う
For Index1 As Integer = 0 To Nagasa - 1 Step 2
' 原文から [暗号1 の文字位置] にある 1 文字を取出し
' 暗号1 に結合させる
Angou1 = Angou1 + Genbun.Substring(Index1, 1)
Next
' [暗号2 の文字位置] を表す変数を用意して 1 で初期化し
' [暗号2 の文字位置] が [原文の長さ] - 1 になるまで
' 2 足して行き、繰返し処理を行う
For Index2 As Integer = 1 To Nagasa - 1 Step 2
' 原文から [暗号2 の文字位置] にある 1 文字を取出し
' 暗号2 に結合させる
Angou2 = Angou2 + Genbun.Substring(Index2, 1)
Next
' 暗号1 と暗号2 を結合したものを txtAngou の Text プロパティに設定する
txtAngou.Text = Angou1 + Angou2
End Sub
' [解読>] ボタンを押したときの処理
Private Sub btnKaidoku_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles btnKaidoku.Click
' 暗号文を格納する変数を用意して
' txtAngou の Text プロパティ値で初期化する
Dim Angou As String = txtAngou.Text
' [暗号文の長さ] を格納する変数を用意して
' Genbun の Length プロパティ値で初期化する
Dim Nagasa As Integer = Angou.Length
' 原文を格納する変数を用意して NULL 文字列で初期化する
Dim Genbun As String = ""
' [暗号1 の長さ] を格納する変数を用意して
' [暗号文の長さ] を半分にした長さを代入する
Dim Nagasa1 As Integer = Nagasa - Int(Nagasa / 2)
' [暗号2 の長さ] を格納する変数を用意して
' [暗号文の長さ] から [暗号1 の長さ] を引いた長さを代入する
Dim Nagasa2 As Integer = Nagasa - Nagasa1
' 暗号1 を格納する変数を用意して
' 暗号文の 1 文字目から Nagasa1 文字目までの文字列を代入する
Dim Angou1 As String = Angou.Substring(0, Nagasa1)
' 暗号2 を格納する変数を用意して
' 暗号文の Nagasa1 文字目から Nagasa2 文字目までの文字列を代入する
Dim Angou2 As String = Angou.Substring(Nagasa1, Nagasa2)
' [暗号2 の文字位置] を表す変数を用意して 0 で初期化する
Dim Index2 As Integer = 0
' [暗号1 の文字位置] を表す変数を用意して 0 で初期化し
' [暗号1 の文字位置] が [暗号1 の長さ] - 1 になるまで繰返し処理を行う
For Index1 As Integer = 0 To Nagasa1 - 1
' 暗号1 から [暗号1 の文字位置] にある 1 文字を取出し
' 原文に結合させる
Genbun = Genbun + Angou1.Substring(Index1, 1)
' [暗号2 の文字位置] が [暗号2 の長さ] を超えていないか判断する
If Nagasa2 > Index2 Then
' [暗号2 の長さ] より [暗号2 の文字位置] が小さいときの処理
' 暗号2 から [暗号2 の文字位置] にある 1 文字を取出し
' 原文に結合させる
Genbun = Genbun + Angou2.Substring(Index2, 1)
' [暗号2 の文字位置] を 1 つ進める
Index2 = Index2 + 1
End If
Next
' 解読した原文を txtKaidoku の Text プロパティに設定する
txtKaidoku.Text = Genbun
End Sub
End Class
|
| 健一 | :いやあ、どうやら無事に最後までたどりつけたね。 |
| 翔太 | :うん、やっぱり健一さんにそばにいてもらってよかったよ。でないと、大変なことになってたかもしれない。 |
| 健一 | :おいおい、僕もまだまだ勉強中の身だってことを忘れないでくれよ。この本はあくまで初心者向けの入門書にすぎないんだ。だから、僕でもこうして君たちにいろいろ教えることができたんだよ。実際、君たちと一緒に勉強を進めたことで、自分自身の復習にもなったしね。 |
| 美咲 | :でも、健一さんがいなかったら、わけもわからずにただコードを書いて終わってたと思うわ。 |
| 健一 | :それでも、サンプルがちゃんと動いてくれれば、それはそれでいいんだよ。この本の目的は、書いてある内容について知識を深めてもらうことじゃなくて、プロラグミングを体験してもらうことなんだから。その意味では、十分すぎるほど効果があったみたいだね。 |
| 翔太 | :うん、とても楽しかったよ。あとは第 8 章が残ってるけど、終わるのが名残惜しいなぁ。 |
| 健一 | :第 8 章は、今までの応用編になってる。だから、体験を基本にしてるのは変わりはないんだけど、今までよりコードを書く量が多いし、出てくる技術も広範囲にわたってる。その代わり、今までの中では一番しっかりしたプログラムができあがるのは間違いない。どうする? 続けてやるかい? |
| 翔太 | :うーん、やりたい気持ちはあるんだけど、さすがにちょっと頭が一杯一杯になってきちゃったな。 |
| 美咲 | :それじゃ、一休みしてからにしましょうか。 |
| 健一 | :だったら、出張のお土産にお菓子を買ってきたから、それでお茶にしよう。 |
| 翔太 | :うん! それじゃまずは休憩ってことで。そのあとで、最後の第 8 章に挑戦することにしようよ。 |