モテようとして、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って書けるんですね。今日初めて書きました。