文字列からC#のint[][]とchar[][]を作成する/int[][]から文字列を生成するクラス
C#のジャグ配列、、生成するのが面倒なのでちょっとしたヘルパー代わり。 でくくった文字列からint[]のジャグ配列を作成する。
class GridCreator { /* 入力サンプル [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]] ↓ [3,0,8,4] [2,4,5,7] [9,2,6,3] [0,3,1,0] */ public static int[][] CreateGridJag(string a) { string[] wk = a.Replace(" ", "").Replace("[[", "").Replace("]]", "").Split("],["); int[][] grid = new int[wk.Length][]; for (int i = 0; i < wk.Length; i++) { string[] tmp = wk[i].Split(","); if (tmp.Length > 0 && tmp[0].Length > 0) grid[i] = tmp.Select(x => int.Parse(x)).ToArray(); } return grid; } public static int[,] CreateGrid(string a) { string[] wk = a.Replace(" ", "").Replace("[[", "").Replace("]]", "").Split("],["); int[][] tmp = wk.Select(c => c.Split(",").Select(x => int.Parse(x)).ToArray()).ToArray(); int[,] grid = new int[tmp.Length, tmp[0].Length]; for (int i = 0; i < wk.Length; i++) { for (int j = 0; j < tmp[i].Length; j++) grid[i, j] = tmp[i][j]; } return grid; } public static char[][] CreateCharGrid(string a) { string[] wk = a.Replace(" ", "").Replace("[[", "").Replace("]]", "").Split("],["); char[][] grid = new char[wk.Length][]; for (int i = 0; i < wk.Length; i++) { string[] tmp = wk[i].Split(","); grid[i] = tmp.Select(x => x[0]).ToArray(); } return grid; } public static string GetResultStr(int[][] grid) { StringBuilder builder = new StringBuilder(); builder.Append("["); foreach (var item in grid) { builder.Append("["); for (int i = 0; i < item.Length; i++) { if (i == item.Length - 1) builder.Append(item[i]); else builder.Append(item[i]).Append(","); } builder.Append("]"); } builder.Append("]"); return builder.ToString(); } }
使い方
int[][] grid = GridCreator.CreateGrid("[[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]");
int[]または文字列からListNodeを作成するクラス
文字列でもint[]でも構築可能
public class ListNode { public int val; public ListNode next; public ListNode(int x) { val = x; } }
class ListNodeHelper { public static ListNode CreateListNode(string nums) { if (nums == null) return null; string[] tmp = nums.Split("->"); List<int> res = new List<int>(); foreach (var item in tmp) { int number; if (int.TryParse(item, out number)) res.Add(number); } return CreateTree(res.ToArray()); } public static ListNode CreateList(int[] nums) { if (nums == null) return null; ListNode res = new ListNode(-1); ListNode wk = res; for (int i = 0; i < nums.Length; i++) { wk.next = new ListNode(nums[i]); wk = wk.next; } return res.next; } public static string ResultStr(ListNode node) { StringBuilder builder = new StringBuilder(); while (node != null) { builder.Append(node.val).Append("-"); node = node.next; } return builder.ToString(); } }
使い方(文字列で値を渡して区切り文字を指定Version。数値の配列でも可)
ListNode res = ListNodeHelper.CreateListNode("1->2->3->4->5->NULL", "->"); ListNode node = ListNodeHelper.CreateList(new int[] { 1, 2, 3, 4, 5 }); Console.WriteLine(ListNodeHelper.ResultStr(res));
int[]またはstring[]からTreeNodeを作成するクラス
nullが必要ならstring null不要ならint
public class TreeNode { public int val; public TreeNode left; public TreeNode right; public TreeNode(int x) { val = x; } } class TreeNodeHelper { public static TreeNode CreateTree(int[] nums) { return CreateTree(nums.Select(x => x.ToString()).ToArray()); } public static TreeNode CreateTree(string[] nums) { if (nums == null) return null; TreeNode res = new TreeNode(int.Parse(nums[0])); Queue<TreeNode> nodes = new Queue<TreeNode>(); nodes.Enqueue(res); int index = 1; while (nodes.Count > 0) { int cnt = nodes.Count; for (int i = 0; i < cnt; i++) { TreeNode root = nodes.Dequeue(); if (root == null) continue; root.left = GetNode(nums, index++); root.right = GetNode(nums, index++); nodes.Enqueue(root.left); nodes.Enqueue(root.right); } } return res; } private static TreeNode GetNode(string[] nums, int n) { if (n >= nums.Length) return null; if (nums[n] == null) return null; return new TreeNode(int.Parse(nums[n])); } public static string ResultStr(TreeNode node) { StringBuilder builder = new StringBuilder(); Queue<TreeNode> nodes = new Queue<TreeNode>(); while (nodes.Count > 0) { int cnt = nodes.Count; for (int i = 0; i < cnt; i++) { TreeNode wk = nodes.Dequeue(); if (wk == null) { builder.Append("null").Append(" "); } else { builder.Append(wk.val).Append(" "); nodes.Enqueue(wk.left); nodes.Enqueue(wk.right); } } } return builder.ToString(); } }
使い方
Program program = new Program(); var res = program.RightSideView(TreeNodeHelper.CreateTree(new string[] { "1", "2", "3", null, "5", null, "4" })); TreeNode node = TreeNodeHelper.CreateTree(new int[] { 4, 2, 7, 1, 3 }); Console.WriteLine("Hello World!");
'a'と'A'の相互変換
aのAsciiコードは10進で65 AのAsciiコードは10進で97
char | 10進 | 2進 | |
---|---|---|---|
a | 65 | 1000001 | |
A | 97 | 1100001| | |
z | 90 | 1011010 | |
Z | 122 | 1111010 |
'a' xor 'A'~'z' xor 'Z'`をやってみればよい。
char[] wk1 = new char[] { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; char[] wk2 = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; for (int i = 0; i < wk1.Length; i++) { if (i < wk1.Length) Console.WriteLine(wk1[i] + "-" + (char)(wk1[i] ^ 32)); if (i < wk2.Length) Console.WriteLine(wk2[i] + "-" + (char)(wk2[i] ^ 32)); }
Scalaを趣味で触るついでに関数型プログラミングに慣れる(予定)-1
scalaを勉強してみることにした。
調べてみるとこれが良いって色んな人が書いているので、流される性格の人としては 読んでみるしかない。
Scala関数型デザイン&プログラミング―Scalazコントリビューターによる関数型徹底ガイド
- 作者: Paul Chiusano,Rúnar Bjarnason,株式会社クイープ
- 出版社/メーカー: インプレス
- 発売日: 2015/04/30
- メディア: Kindle版
- この商品を含むブログ (3件) を見る
第2章
/**
* シングルトンオブジェクト
*/
object MyModule {
/*
整数を受け取り整数を返す純粋関数
*/
def abs(n: Int): Int =
if (n < 0) -n
else n
/*
プライベートメソッドMyModule内からしか呼び出せない
*/
private def formatAbs(x: Int) = {
val msg = "The absolute value of %d is %d"
msg.format(x, abs(x))
}
/*
Unitはjavaのvoidに相当する
*/
def main(args: Array[String]): Unit = {
println(formatAbs(-42))
}
}
javaと大分違うな
object MyModule
これでシングルトンオブジェクトの宣言となる。とな。
あとは、型アノテーションがこんな感じ。
(n: Int)
変数宣言はこう。
val num1: Int = 0
val num2 = 0
num2 = 1 //この行はコンパイルエラー
var num3: Int = 0
var num4 = 0
num4 = 1
valでもvarでも宣言可能だが、valで宣言するとImmutableになる。
変なところで書き換えられないためにも、valを使うほうが安全で安心だなぁ。
2.4章
高階関数:関数に関数を渡す
factorialのサンプル実装を書いてみる。
goという関数をローカル定義
Scalaのヘルパー関数ではgoまたはloopという名前を使用するのが慣例らしい。
で、StackOverFlowしないように末尾再帰を使ってねと。
@annotation.tailrec というアノテーションで末尾再帰かどうかをチェックしてくれる。
def factorial(n: Int): Int = {
@annotation.tailrec
def go(n: Int, acc: Int): Int = {
if (n <= 0)
acc
else go(n - 1, n * acc)
}
go(n, 1)
}
Excersizeとしてn番目のフィボナッチを求めるのを書けとの事
Signatureはこれ。
def fib(n: Int): Int = ???
scalaは未実装部分を???にしておいて他の実装を進められる。
これ、すごい便利だと思う。実装忘れがなくなるし、並行作業しやすい。
まずは単純に再帰で書いてみる・
とりあえずササっと書い、、けないので、文法を調べる。
scalaでのcase文はmatchってのを使うらしい。
def fib(n: Int): Int = {
n match {
case 0 => 0
case 1 => 1
case 2 => 1
case _ => fib(n - 2) + fib(n - 1)
}
}
case _
で0,1,2以外の残りを処理する。
caseについてはこんな書き方ができるらしい。今回のロジックだとこっちの方が綺麗だと感じた。
ただ、末尾再帰ではないのでもう少し。
def fib(n: Int): Int = n match {
case 0 => 0
case 1 => 1
case 2 => 1
case _ => fib(n - 2) + fib(n - 1)
}
factorialと同じ手法で末尾再帰してみる。
def fib(n: Int): Int = {
@annotation.tailrec
def go(n: Int, pre: Int, cur: Int): Int = {
if (n == 0) pre
else go(n - 1, cur, pre + cur)
}
go(n, 0, 1)
}
答え見てみたけど、一緒。
fpinscala/GettingStarted.scala at master · fpinscala/fpinscala · GitHub
三日坊主にならないようにしよう