Atcoderなんかのような競技プログラミングをやっていると、必ず出てくるのが文字列の操作。文字列の中からある文字列を削除したり、くっつけたりと、そういった類の問題が出てくる印象がある。
で、ここらへんはすでにメソッドが用意されているので、知っていると知っていないでは、問題の解くスピードが変わってくる。けどね、全部を覚えるのは不可能です。じゃあ、どうしたらいいか考えた結果、メソッド自体を覚えるのではなく、「文字列の比較で、大文字と小文字の区別なく比較できるメソッドあったな」みたいに、こんなことができるメソッドがあったなということを覚えておけばいい感じだと思う。
で、これらを覚えておくには、ソースを書いて、そのメソッドを使ってみないとダメだ。ということで、以下つらつらと書いていきます。
文字列どうしの比較
var str1 = "ABC"; var str2 = "ABC"; if(str1 == str2) Console.WriteLine("OK");
一番シンプルなやつ。演算子が==なので、直感的でわかりやすい。
大文字 / 小文字の区別なく比較する
var str1 = "windows"; var str2 = "WINDOWS"; if(String.Compare(str1, str2, ignoreCase:true) == 0) { Console.WriteLine("等しい"); } else { Console.WriteLine("等しくない"); }
String.Compareを使えば、文字列比較の幅が一気に広がる。
これより以下、String.Compareを使った文字列比較の例。
ひらがな / カタカナの区別なく比較する
var str1 = "カステラ"; var str2 = "かすてら"; // CultureInfoクラスは、言語、国、地域、暦などを表すクラス var cultureInfo = new CultureInfo("ja-JP"); if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreKanaType) == 0) { Console.WriteLine("等しい"); } else { Console.WriteLine("等しくない"); }
全角 / 半角の区別なく比較する
var str1 = "HTML5"; var str2 = "HTML5; // CultureInfoクラスは、言語、国、地域、暦などを表すクラス var cultureInfo = new CultureInfo("ja-JP"); if(String.Compare(str1, str2, cultureInfo, CompareOptions.IgnoreWidth) == 0) { Console.WriteLine("等しい"); } else { Console.WriteLine("等しくない"); }
ここまでString.Compareメソッドを使った、文字列比較をまとめてきた。次は、文字列の判定についてまとめてみる。ここで出てくる、「指定した部分文字列で始まっているか」などは、競プロでほんとよく出てくる。
nullあるいは空文字列かを調べる
var str = ""; if (String.IsNullOrEmpty(str)) Console.WriteLine("NG");
文字列のNULLと空文字チェックだが、自分が何も考えずに書くと以下のようになってしまう。
var str = ""; if (str == null || str == "") Console.WriteLine("NG");
こっちでも動くけど、IsNullOrEmptyメソッド使った方が分かりやすいし、確実だな。if文の条件は、バグポイントなので。
ちなみに、空白文字列まで調べられるメソッドもある。
if (String.IsNullOrWhiteSpace(str))
指定した部分文字列で始まっているか調べる
var str = "Visual Studio"; if (str.StartsWith("Visual")) Console.WriteLine("OK");
指定した部分文字列で終わっているか調べる
始まりがあれば終わりもあるということで、終わりを調べるメソッドもある。
if (str.EndsWith("Visual"))
指定した部分文字列が含まれているか調べる
始まりと終わりときて次は、そもそも場所関係なく部分文字列が含まれているかどうかを調べるときには、Containsメソッドを使う。
if (str.Contains("Program"))
条件を満たしている文字が含まれているか調べる
Anyメソッドの引数の条件に合う文字があれば、trueを返す。
var target = "C# Programming";
var isExists = target.Any(c => Char.IsLower(c));
すべての文字がある条件を満たしているか調べる
さきほどは、一つでも条件を満たした文字があるか調べるものだったが、今度はすべての文字が条件を満たしているか調べる。以下のコードだと、target変数の文字が、すべて数字だったら、trueを返す。
var target = "141421356";
var isAllDigits = target.All(c => Char.IsDigit(c));
部分文字列を検索し、その位置を求める
これも、競プロでよく使うイメージがある。先頭を0から数えた、インデックスを返す。
var target = "C# Programming"; var index = target.IndexOf("Programming");
文字列の一部を取り出す
SubStringメソッドを使えば、開始位置と長さを指定することで、任意の文字列を取り出せる。
var target = "C# Programming"; // 文字列"Pr"を取り出す var value = target.Substring(3, 2);
ちなみに、Substringの第二引数に何も指定しなければ、文字列の最後まで取り出す。
var target = "C# Programming"; // 文字列"Programming"を取り出す var value = target.Substring(3);
残り、ちょっと一気に書く。
文字列の前後の空白を取り除く
var target = " C# Programming ";
var replaced = target.Trim();
指定した位置から任意の数の文字を削除
var target = "01234ABC567"; // 開始位置と長さを指定 var result = target.Remove(5, 3);
文字列に別の文字列を挿入する
var target = "01234"; // 01abc234を返す var result = target.Insert(2, "abc");
文字列の一部を別の文字列で置き換える
var target = "I hope you"; var replaced = target.Replace("hope", "wish");
小文字⇆大文字の変換
var replaced = target.ToUpper(); var replaced = target.ToLower();
指定した区切り文字で文字列配列を連結
var languages = new [] {"C#", "Java", "VB", "Ruby", }; var separator = ","; // 文字列"C", Java, VB, Ruby"を返す var result = String.Join(separator, languages);
文字列から文字を1つずつ取り出す
var str = "C"プログラミング"; foreach (var c in str) Console.Write("{0}", c);
文字配列から文字列を生成
var chars = new char[] {'P', 'r', 'o', 'g', 'r', 'a', 'm' }; var str = new string(chars);