System.Arrayクラスには、ソートだけでなくバイナリ・サーチ(二分検索)の機能もある。バイナリ・サーチとは、あらかじめソートされたデータを高速に検索する手法である。これを使用した例をList 15-11に示す。
1: using System;
2:
3: namespace Sample011
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: int [] ar = { 4,9,3,6,1,0 };
11: Array.Sort( ar );
12: foreach( int n in ar )
13: {
14: Console.WriteLine( n );
15: }
16: int index = Array.BinarySearch( ar, 3 );
17: Console.WriteLine( "index of 3 is {0}", index );
18: }
19: }
20: }
これを実行するとFig.15-11のようになる。
実際にバイナリ・サーチを行うのは、BinarySearchメソッドである。バイナリ・サーチを行うにはデータがソートされている必要があるので、11行目でソートを行っている。そして、16行目で、3という値を指定して、配列arに検索を掛ける。その結果、3という値は添え字が2の要素に格納されているので、16行目の変数indexには2が格納される。
配列型はれっきとしたデータ型なので、メソッドの引数に使ったり、メソッドの戻り値として使うこともできる。その際、配列型は要素数を限定しないため、大きさの決まっていない配列を受け渡すことができる。List 15-12はメソッドの引数と戻り値に配列型を使った例である。
1: using System;
2:
3: namespace Sample012
4: {
5: class Class1
6: {
7: static public int [] makeArray( bool select )
8: {
9: if( select )
10: {
11: int [] ar = { 0,1,2,3 };
12: return ar;
13: }
14: else
15: {
16: int [] ar = { 0,1 };
17: return ar;
18: }
19: }
20: static public void dumpArray( int [] ar )
21: {
22: foreach( int n in ar )
23: {
24: Console.WriteLine( n );
25: }
26: }
27: [STAThread]
28: static void Main(string[] args)
29: {
30: int [] ar = makeArray(false);
31: dumpArray( ar );
32: Console.WriteLine();
33: ar = makeArray(true);
34: dumpArray( ar );
35: }
36: }
37: }
これを実行するとFig.15-12のようになる。
まず注目していただきたいのが、7〜19行目のmakeArrayメソッドである。7行目で、戻り値として「int []」が指定されていることから分かるとおり、このメソッドは、整数の配列を返す。しかし、9行目の条件判断により、11行目の4つの内容を持つ配列を返したり、16行目の2つの内容を持つ配列を返したりする。つまり、要素の数がいくつであっても関係なく、戻り値として渡すことができるのである。
次に注目していただきたいのは、20〜26行目のdumpArrayメソッドである。このメソッドは引数に整数型の配列を受け取る。しかし、要素数に関する情報は何も指定されていない。つまり、要素が何個の配列でも受け取ることができる。そして、メソッドの内部では、foreach文で配列のすべての要素にアクセスしているが、foreach文は配列自身に何個の要素を持っているか問い合わせるので、ソース・コード上に要素の個数を調べるコードは出てこない。
最後に1つだけ、このソース・コードには注意すべきポイントがあることを付記しておく。30行目で作成された配列変数arは、33行目で再度代入をされている。このような使い方は許される。そして、33行目で再度代入されたことで、30行目で作成された配列は破棄されることになる。もちろん、別の場所から参照されていたら、破棄されないかもしれないし、破棄されるとしてもいつ破棄されるかは分からない。しかし、配列変数への代入は、配列の再利用にはならず、別個の配列インスタンスが生成されるということは、覚えておく方がよいだろう。
List 15-13は、C/C++プログラマー向けのオマケである。C#では、いかに容易に文字配列と文字列の間の相互変換ができるかを示す。
1: using System;
2:
3: namespace Sample013
4: {
5: class Class1
6: {
7: [STAThread]
8: static void Main(string[] args)
9: {
10: char [] ar1 = { 'A', 'B', 'C' };
11: foreach( char c in ar1 )
12: {
13: Console.WriteLine(c);
14: }
15: string s = new string(ar1);
16: Console.WriteLine(s);
17: char [] ar2 = s.ToCharArray();
18: foreach( char c in ar2 )
19: {
20: Console.WriteLine(c);
21: }
22: }
23: }
24: }
これを実行するとFig.15-13のようになる。
15行目のように、string(System.String)のコンストラクタに文字(char)の配列を指定すれば、その内容を文字列として生成する。また、17行目のように、文字列にToCharArrayメソッドを使うと、戻り値として、文字の配列が返ってくる。
C#では、C/C++と違って、文字の配列と文字列はまったく別個のものとして扱われるが、このように、必要とあれば、それぞれを相互に変換することは極めて容易にできる。
『新プログラミング環境 C#がわかる+使える』
本記事は、(株)技術評論社が発行する書籍『新プログラミング環境 C#がわかる+使える』から許可を得て一部分を転載したものです。
【本連載と書籍の関係について 】
この書籍は、本フォーラムで連載した「C#入門」を大幅に加筆修正し、発行されたものです。連載時はベータ版のVS.NETをベースとしていましたが、書籍ではVS.NET製品版を使ってプログラムの検証などが実施されています。技術評論社、および著者である川俣晶氏のご好意により、書籍の内容を本フォーラムの連載記事として掲載させていただけることになりました。
→技術評論社の解説ページ
ご注文はこちらから
Copyright© Digital Advantage Corp. All Rights Reserved.