はてなキーワード:StreamReaderとは
プログラムはclassに記述します。たとえばSampleという名前のclassを作る場合、Sample.csファイル内に次のように書きます。(C#の場合、ファイル名とクラス名は同一でなくても良い。複数のクラスを書いても良い)
public class Sample {}
プログラムはclass内のMainメソッドの先頭から実行されます。Mainメソッドは次のように書きます。
public class Sample { public staticvoid Main(String[] args ) { // 処理を書く }}
Console.WriteLine( "Hello world" );
コメントです。
// 一行コメント/* 複数行コメント */
//変数int num;
データ型です。C#のデータ型には値型と参照型とがあります。以下は値型のデータ型です。
// int(整数)型int num;//char(文字)型char c;// float(単精度浮動小数点)型float val;//double(倍精度浮動小数点)型double val;// bool(論理)型boolflag;//DateTime(日付)型DateTimedate;
以下は参照型のデータ型です。
//String型String s;//配列型String[] array;
プログラムをコンパイルするには、コマンドラインで以下のようにします。
csc Sample.cs
プログラムを実行するには、コマンドラインで以下のようにします。
Sample.exe
mono ./Sample.exe
int、float、double型の変数に数値を代入できます。int型には整数だけ代入できます。float、double型には整数でも小数でも代入できます。
int i = 2;int i = 100000000;float num = 1.234f;double num = 1.234;
四則演算です。
num = 1 + 1;num = 1 - 1;num = 1 * 2;num = 1 / 2;
商の求め方です。割る数と割られる数が両方とも整数の場合、計算結果の小数点以下が切り捨てられます。
num = 1 / 2; // 0
割る数と割られる数のどちらかが小数の場合、計算結果の小数点以下が切り捨てられません。
num = 1.0 / 2; // 0.5num = 1 /2.0; // 0.5num = 1.0 /2.0; // 0.5
余りの求め方です。
// 余りmod = 4 % 2
インクリメントとデクリメントです。
// インクリメント ++i;// デクリメント --i;
Stringstr = "abc";
// 結合String join = "aaa" + "bbb";// 分割String[] record = "aaa,bbb,ccc".Split( "," );// 長さint length = "abcdef".Length();// 切り出し"abcd".Substring( 0, 2 ) //abc//検索int result = "abcd".IndexOf( "cd" ) // 見つかった場合はその位置、見つからなかった場合は-1が返る
配列です。
//配列の宣言int[] array;
配列の生成です。配列の生成時には要素数を指定するか、初期データを指定します。
int[] array;// 要素数を指定して配列を生成array = new int[5];// 初期データを指定して配列を生成array = new int[] { 1, 2, 3 };// 宣言と同時に配列を生成int[] array2 = new int[5];
配列の要素の参照と代入です。
// 要素の参照array[0]array[1]// 要素の代入array[0] = 1;array[1] = 2;
array_num = array.Length;
int[] from = new int[] { 1, 2, 3 };int[] to = new int[5];from.CopyTo(to, 0);
if文です。
if ( 条件 ){}
if ~ else文です。
if ( 条件 ){}else{}
if ~ else if文です。
if ( 条件 ){}else if ( 条件 ){}
while文です。
int i = 0;while ( i < 5 ){ // 処理 ++i;}
for文です。
for ( int i = 0; i < 5; ++i ){ // 処理}
int[]fields = new int[] { 1, 2, 3 };foreach (intfield infields){ // 処理}
C#では関数をメソッドと言います。メソッドを作るには次のようにします。戻り値を返却するにはreturn文を使います。
static int sum( int num1, int num2 ){ inttotal;total = num1 + num2; returntotal;}
ファイル入出力です。ファイル入出力を行うには、プログラムの先頭に以下を記述します。
using System.IO;
以下がファイル入力の雛形になります。ファイルのオープンや読み込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt";StreamReaderreader = null;try{reader = newStreamReader(filename);Stringline; while ((line =reader.ReadLine()) != null) { }}catch (IOException e){ //エラー処理:}finally{ if (reader != null) {try {reader.Close(); }catch (IOException e) { } }}
またはC#ではusingステートメントと言うものがあり、この様にも書ける
String filename = "text.txt";using (StreamReaderreader = newStreamReader(filename)){try {Stringline; while ((line =reader.ReadLine()) != null) { // 読み込んだ行を処理 } }catch (IOException e) { //エラー処理: }}
usingをつかうとCloseがなくなったことからわかるようにusing(){}を抜けるときに自動的にDisposeメソッドを呼び出し、オブジェクトを廃棄する。その分コードがスッキリするが、使いにくい場面もあるので考えて使うこと。
以下がファイル出力の雛形になります。ファイルのオープンや書き込みに失敗した場合、catch節に処理が移ります。
String filename = "text.txt";StreamWriterwriter = null;try{writer = newStreamWriter(filename));writer.WriteLine("abc");writer.WriteLine("def");writer.WriteLine("fgh");}catch (IOException e){ //エラー処理:}finally{ if (writer != null) {writer.Close(); }}
こちらもusingを使って書ける。が、割愛する。
C#でよく出てくる知っておいたほうがよい文法の一覧です。
繰り返し文の途中で抜けるにはbreak文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) { break; // 条件を満たす場合、for文を抜ける。 }}
残りの部分処理をスキップし、次の繰り返しに進むにはcontinue文を使用します。
for ( i = 0; i < 5; ++i ) { if ( 条件 ) {continue; // 条件を満たす場合、残りの部分処理をスキップし、次の繰り返しに進む。 }}
例外を投げるにはthrow文を使用します。
throw new Exception( "Error messsage" );
try { // 例外が発生する可能性のある処理}catch ( Exception e ) { // 例外発生時の処理}
これで40分。
タイムアタックってことでアルゴリズムは全幅探索で書き上げました。
エラーチェック皆無。
A*ならもう5分ほど延びるかな?
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;namespace Maze{ class Program { // 探索用地図 static int[,] maze; // 始点終点 staticPosition Start = newPosition(0, 0), Goal = newPosition(0, 0); staticvoid Main(string[] args) { //////////////////////////// まずは各行のリストとして読み込みstring[] inMaze; using (varfp = newFileStream(args[0], FileMode.Open, FileAccess.Read)) using (var iStream = newStreamReader(fp)) inMaze = iStream.ReadToEnd().Split('\n'); //迷路幅 int height = inMaze.Length; //迷路高さ int width = inMaze[0].Length; /////////////////////////// 読み込んだ迷路を作業用地図に展開 maze = new int[width, height]; for (int y = 0; y < height; ++y) {string line = inMaze[y]; for (int x = 0; x < line.Length; ++x) { maze[x, y] = line[x] == '*' ? -1 : 0; if (line[x] == 'S') Start = newPosition(x, y); if (line[x] == 'G') Goal = newPosition(x, y); } } // 探索実行 int dist = Search(maze, Start); // 探索結果から最短経路を再現Position backTracer = Goal; while (dist>1){ --dist; backTracer = backTracer.Nearbys.First(pos => maze[pos.X,pos.Y] == dist); maze[backTracer.X, backTracer.Y] = -2; } //////////////////// 最短経路こみのアスキー地図に変換char[,] outMaze = newchar[width, height]; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { outMaze[x, y] = maze[x, y] == -2 ? '$' : maze[x, y] == -1 ? '*' : ' '; } } outMaze[Start.X, Start.Y] = 'S'; outMaze[Goal.X, Goal.Y] = 'G'; ////////////////////// 結果は標準出力に。 for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x)Console.Write(outMaze[x, y]);Console.WriteLine(); }Console.ReadLine(); } /// <summary> /// 探索する。SG間の道のりを返す(道のり=SGが隣接しているなら1) /// </summary> private static int Search(int[,] maze,Position Start) { List<Position> FrontLine = new List<Position>(); FrontLine.Add(Start); int dist = 1; for (; ; ) { List<Position> NextFrontLine = new List<Position>(); foreach (varpos in FrontLine) { foreach (var nextPos inpos.Nearbys) { if (nextPos == Goal) return dist; if (maze[nextPos.X, nextPos.Y] == 0) { maze[nextPos.X, nextPos.Y] = dist; NextFrontLine.Add(nextPos); } } } FrontLine = NextFrontLine; ++dist; } } } structPosition { public readonly int X, Y; publicPosition(int x, int y) { X = x; Y = y; } public IEnumerable<Position> Nearbys { get { return new[]{ newPosition(X-1,Y), newPosition(X,Y-1), newPosition(X+1,Y), newPosition(X,Y+1), }; } } public static bool operator==(Position p1,Positionp2){ return p1.X ==p2.X && p1.Y ==p2.Y; } public static bool operator!=(Position p1,Positionp2){ return p1.X !=p2.X || p1.Y !=p2.Y; } }}