新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

学習記録:C#、プログラム作成:CodeIQ

[学習記録] C#

参考書籍

〔速攻入門〕 C#プログラミング すぐに現場で使える知識

〔速攻入門〕 C#プログラミング すぐに現場で使える知識

内容

Part1 C#の文法 速攻入門
  • dynamic(動的型付け)
    • コンパイル時に型チェックを行わず、実行時に解決する
    • IronPythonなどの他言語との連携で役立つ
static void DynamicAdd(dynamic x, dynamic y)
{
    // +演算子さえ持っていればOK
    Console.WriteLine(x + y);
}
  • 右シフト
    • 符号付き整数に対する右シフトは常に算術右シフトに、
    • 符号無し整数に対する右シフトは常に論理右シフトになる
    • 算術/論理右シフト用の演算子は存在しない
  • goto
    • ブロックの中から外へは飛べるが、逆は不可
    • finallyブロックから外へは飛べない
  • オーバーフローのチェック
    • 整数型に対する計算結果がオーバーフローした際に例外を発生させることができる
      • デフォルトではオフ
    • 1)C#コンパイラオプションに/checked+を指定
    • 2)checked/uncheckedステートメント演算子を用いる
// ブロック内でオーバーフローをチェック
checked
{
    byte x = 255;
    // 例外発生
    x++;
}

int y = 256;
// 例外発生
byte z = checked((byte) y);
  • 型情報
    • is演算子:型が一致しているかboolで返す
    • as演算子:型変換を行う、ただし変換できない場合にnullを返す
      • 参照型にしか使えない
try {
    var x = (string) obj;
}
catch (InvaludCastException)
{
    // キャストに失敗すると例外発生
}

// 事前に型を調べることで例外発生を回避
if (obj is string)
{
    var x = (string) obj;
}

// as演算子を使えば例外は発生しない
var y = obj as string;
  • default式
    • 規定値を取得
    • 数値は0、boolはfalse、参照型はnull...
var n = default(int); // 0 (int型)
var s = default(string); // null (string型)
  • 逐語的リテラル
    • @を付けることで以下のことができる
      • バックスラッシュによるエスケープを行わない
      • 改行を含めることができる
      • 二重引用符を使う場合は2つ続けて書く
string str = @"C:\Windows
2行目
3行目
";
  • クラス
    • 関数メンバ
メンバ 意味 Java
コンストラクタ クラスまたはインスタンスの初期化に必要なアクション
デストラクタ インスタンスが完全に破棄される前に実行されるアクション ○(ファイナライザ)
メソッド クラスで実行できる演算とアクション
プロパティ クラスの名前付きプロパティの読み書きに関連づけられるアクション ×
インデクサ インスタンスのインデックス付けに関連するアクション ×
イベント クラスによって生成される通知機構 ×
演算子 クラスでサポートされる変換・式演算子 ×
修飾子 アクセス可能範囲 Java
public どこからでも public
protected 自分と派生クラスから protected(ただしパッケージ内もOK)
internal 同一アセンブリから ×(指定なし時がパッケージスコープになり、少し近い)
protected internal 自分と派生クラス、同一アセンブリから ×(protectedが近い)
private 自分のみ private
    • 名前空間直下の型にはpublicかinternalのいずれかを指定(省略時はinternal)
    • メンバの修飾子を省略した場合はprivate扱い
class Program
{
    static void Main()
    {
        Console.WriteLine(4.Square());
    }
}

static class Extension
{
    public static int Square(this int i)
    {
        return i * i;
    }
}
  • 演算子オーバロード
    • public static 戻り値の型 operator 演算子名 (パラメータのリスト) { ... }
演算子 引数の型 戻り値の型
+, -, !, ~ 自クラスの型 任意
++, -- 自クラスの型 自クラスの型
true, false 自クラスの型 bool型
キャスト 自クラスの型 明示しない
+, -, *, /, |, ^ 少なくとも一方は自クラスの型 任意
<<, >> 自クラスの型, int 任意
==, !=, >, <, >=, <= 少なくとも一方は自クラスの型 任意

[プログラム作成] CodeIQ:最長の移動経路を求める

URL


挑戦者求む!【アルゴリズム】今週のお題:最長の移動経路を考えて! by 増井技術士事務所 今週のアルゴリズムの@masuipeo│CodeIQ

プログラム

  • 受付締め切りを過ぎたので公開
    • プロコン系の本を読んだおかげで割とあっさり解けて嬉しい。
    • とはいえ効率は悪そうですが、同じ直線上は2回しか通れないという制約のおかげか実行は割と早い
    • 最短距離ではないので再帰を使った深さ優先探索にしたが、幅優先探索でもできるのかな?
public class MigratonLength {

	static final int HEIGHT = 5;
	static final int WIDTH = 6;
	static final int[] VX = {1, -1, 0, 0};
	static final int[] VY = {0, 0, 1, -1};
	
	static int[] tateCount = new int[WIDTH + 1];
	static int[] yokoCount = new int[HEIGHT + 1];
	static int max = 0;
	
	static void getMaxMigrationLength(int curLength, int curX, int curY) {
		if (curX < 0 || curX > WIDTH || curY < 0 || curY > HEIGHT) {
			return;
		}
		
		if (yokoCount[curY] >= 3 || tateCount[curX] >= 3) {
			return;
		}
		
		if (curX == WIDTH && curY == HEIGHT) {
			max = Math.max(max, curLength);
			return;
		}
		
		for (int i = 0; i < 4; i++) {
			yokoCount[curY] += Math.abs(VX[i]);
			tateCount[curX] += Math.abs(VY[i]);
			getMaxMigrationLength(curLength + 1,  curX + VX[i], curY + VY[i]);
			yokoCount[curY] -= Math.abs(VX[i]);
			tateCount[curX] -= Math.abs(VY[i]);
		}
	}
	
	public static void main(String[] args) {
		getMaxMigrationLength(0, 0, 0);
		System.out.println(max);
	}
}