実際には、逆にしたい文字列が占有しているのと同じ量のメモリを割り当てずに、文字列を逆にする正しい方法はありません。(理論的には、メモリ内の文字列を逆にすることは可能ですが、これはお勧めできません。その領域に入るつもりはありません)。次に、文字列自体を逆にします。私は StringExtensions と呼ばれる小さなプロジェクトに取り組んでいます。このプロジェクトでは、文字列を操作するときに発生する可能性のある問題をすべて解決しようとしています。最大の問題の 1 つは、フレームワーク全体で広く使用されている UTF-16 エンコーディングを使用することです。文字列を逆にする私の実装は次のようになります。
static IEnumerable<Tuple<int, int>> GetTextElementSegments(string value)
{
int[] elementOffsets = StringInfo.ParseCombiningCharacters(value);
int lastOffset = -1;
foreach (int offset in elementOffsets)
{
if (lastOffset != -1)
{
int elementLength = offset - lastOffset;
Tuple<int, int> segment = new Tuple<int,int>(lastOffset, elementLength);
yield return segment;
}
lastOffset = offset;
}
if (lastOffset != -1)
{
int lastSegmentLength = value.Length - lastOffset;
Tuple<int, int> segment = new Tuple<int, int>(lastOffset, lastSegmentLength);
yield return segment;
}
}
static void Main(string[] args)
{
string input = "t\u0301e\u0302s\u0303t\u0304";
StringBuilder resultBuilder = new StringBuilder(input.Length);
var segments = GetTextElementSegments(input);
foreach (var segment in segments.Reverse())
{
resultBuilder.Append(input, segment.Item1, segment.Item2);
}
Debug.Assert(resultBuilder.ToString() == "t\u0304s\u0303e\u0302t\u0301s");
}
これは、サロゲート ペア、Unicode マーク コードポイントを処理し、入力文字列自体が占める量と同様のメモリのみを割り当てることに注意してください。