モテようとして、C#でXOR使ってリバースしている奴がいたんですよ
いろいろなリバースのアルゴリズムを見てみましよう。
まずは表題のリバースのアルゴリズムについて、どうぞ。
なんとなくモテようとしている感のあるリバース
モテようとして、C#でXOR使ってリバースしている奴がいたんですよ・・(以下略)。こんな感じで
public static string Reverse(string s) { char[] charArray = s.ToCharArray(); int len = s.Length - 1; for (int i = 0; i < len; i++, len--) { charArray[i] ^= charArray[len]; charArray[len] ^= charArray[i]; charArray[i] ^= charArray[len]; } return new string(charArray); }
もちろん要件は満たしているし、それほど遅いアルゴリズムでもないので、
私的にはギリギリセーフなんですが、なんとなくやっちまってる感が・・ね。
どうも無理にXOR使ってスワップをして「モテ」を意識しているようです。
嫌いじゃないですがちょっとキモイです(笑)
新人くんにありがちなリバース
public static string Reverse(string s) { return new string(s.ToCharArray().Reverse().ToArray()); }
完全にやっちまってますね。イテリセンス利きまくりのIDEに飼いならされた新人が
「.」押して出てきたやつを次々につなげたらリバースできちゃったよー的な。
これは、超おそおそアルゴなので論外です。新人じゃない場合は・・・\(^o^)/
VB.NET厨寄りC#erにありがちなリバース
public static string Reverse(string s) { return Microsoft.VisualBasic.Strings.StrReverse(s); }
StrReverseキタコレ。まぁ、間違ってはいないんだけどね・・。
「車輪の再発明はしない的理論だよ」というのであれば、そのまま使え、と。
ちったあ、頭つかいましょうよ、と思っちゃいますね。
一般的によく書かれてそうなリバース
public static string Reverse(string s) { char[] charArray = new char[s.Length]; int len = s.Length - 1; for (int i = 0; i <= len; i++) charArray[i] = s[len - i]; return new string(charArray); }
ノーマルなC#erが最も書きそうな感じです。
教科書通り的な雰囲気があります。特に文句はありません。
書けといわれたら、自分もたぶんこれ書きます。
別によいんだけど、なんとなく残念なリバース
public static string Reverse(string s) { char[] arr = s.ToCharArray(); Array.Reverse(arr); return new string(arr); }
ノーマルなC#erが割と書きそうな感じです。
確かに、その発想もあるよね。悪くは無いです。あると思います。
そうも思うんだけど、なんとなく賛同できない俺ガイル。
StringBuilderに洗脳されている残念な人のリバース
public static string Reverse(string s) { char[] cArray = s.ToCharArray(); StringBuilder reverse = new StringBuilder(); for (int i = cArray.Length - 1; i > -1; i--) { reverse.Append(cArray[i]); } return reverse.ToString(); }
間違ってはいないんだけど、StringBuilder使えばいいっちゅーもんでもない。
とりあえず、洗脳を解いてあげたい。
人とは毛色が違いますね・・。正直やめて欲しい個性的なリバース
public static string Reverse(string s) { Stack<string> stack = new Stack<string>(); for (int i = 0; i < s.Length; i++) stack.Push(s.Substring(i, 1)); string ns = string.Empty; for (int i = 0; i < s.Length; i++) ns += stack.Pop(); return ns; }
これはひどい低速アルゴですね。
スタック使っちゃいますか。そうですか、わかりません。
基本的なところから再教育が必要かもしれません。
がんばったと決して褒めたくない再帰的なリバース
public static string Reverse(string s, int length) { if (length == 1) return s; return Reverse(s.Substring(1, s.Length - 1), --length) + s[0].ToString(); }
これもひどい低速アルゴです。ダサいです。
思考的ベクトルの方向が全くわかりません。本当にありがとうございました。
にわか仕込みラムダ厨による超低速リバース
public static string Reverse(string s) { Func<string, string> f = null; f = x => x.Length > 0 ? f(x.Substring(1)) + x[0] : string.Empty; return f(s); }
ラムダで書きゃーいいってもんじゃないです。
見なかったことにしてあげるので、今すぐ書き直してください。
できれば死なない程度に死んでください(^-^)
様々なリバースを見てきましたが、まだ飽き足らないあなたへ
unsafeでポインタつかって無駄に高速化をはかります。
ポインタ使うと速くなるのは、配列のバインド チェックが削除されるからです。
まずは普通に書く。(これが一番高速っぽいです)
unsafe static string Reverse(string s) { fixed (char* pc = s) { string newtext = new string(pc); fixed (char* pChar = newtext) { char swapChar; int length = s.Length - 1; for (int i = 0, j = length; i < j; i++, j--) { swapChar = pChar[i]; pChar[i] = pChar[j]; pChar[j] = swapChar; } } return newtext; } }
せっかくだから、俺はポインタでスワップするゼ
unsafe static string Reverse(string s) { fixed (char* pc = s) { string newtext = new string(pc); fixed (char* pChar = newtext) { char swapChar; int length = s.Length - 1; char* pStart = pChar; char* pEnd = pChar + length; while (pStart < pEnd) { swapChar = *pStart; *pStart = *pEnd; *pEnd = swapChar; pStart++; pEnd--; } } return newtext; } }
unsafeでもやっぱりXORでモテたい人のリバース
unsafe static string Reverse(string s) { fixed (char* pc = s) { string newtext = new string(pc); fixed (char* pChar = newtext) { int length = s.Length - 1; for (int i = 0, j = length; i < j; i++, j--) { pChar[i] ^= pChar[j]; pChar[j] ^= pChar[i]; pChar[i] ^= pChar[j]; } } return newtext; } }
「ワシのリバースは108式まであるぞ!」
という方がいらっしゃいましたら、ぜひ教えて頂ければ幸いです。
関係ないけど、ラムダ式の中でもunsafeって書けるんですね。今日初めて書きました。