Array.Reverse()
メソッドを使用せずに配列を(C#で)逆にする方法は?
例えば、
int[] arr = {1,3,4,9,8};
// some code here
Console.WriteLine(string.Join(",", arr));
結果になるはずです
8,9,4,3,1
これは面接のタスクとして取得しました。
質問の// some code here
の代わりに置き換えられるコードは次のとおりです:
for (int i = 0; i < arr.Length / 2; i++)
{
int tmp = arr[i];
arr[i] = arr[arr.Length - i - 1];
arr[arr.Length - i - 1] = tmp;
}
配列の前半のみを反復処理する必要があります(arr.Length / 2
)。配列全体(arr.Length
)を反復処理すると、配列が2回反転し、開始前と同じ要素の順序になります。
基本的に、再実装するように求められます Array.Reverse(Array)
。 フレームワークに実装されている 自体を見て、周りの多くの技術的な詳細を無視すると、3つのパラメーターのバージョン(配列の指定された部分を逆にする)を呼び出すだけであることがわかります。アレイ全体。
Array.Reverse(Array,Int32,Int32)
は、要素を交換して2つのインデックスを維持するwhileループです。
i
は、反転したパーツの最初の要素を指し、j
は、反転されたパーツの最後の要素を指します。質問の// some code here
の代わりに置き換えるように書き直されました:
int i = 0;
int j = arr.Length - 1;
while (i < j)
{
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
これは for-loopを使用した実装 よりも把握しやすく、計算が少なく、エレガントに二重の逆変換で問題を回避します。
for (int i = 0; i < array.Length - i; i++)
{
var value = array[array.Length - i - 1];
array[array.Length - i - 1] = array[i];
array[i] = value;
}
それは配列の長さからのとても単純な開始ループであり、コードを見て、あなたは理解するでしょう:)))
int[] arr = new int[5] { 1, 2, 3, 4, 5 };
for (int i = arr.Length-1; i >= 0; i--)
{
Console.WriteLine(arr[i]);
}
int[] arr1 = {1,3,4,9,8};
int[] arr2 = new int[5];
int j = 0;
for(int i = arr1.Length - 1; i >= 0; i--)
{
arr2[j] = arr1[i];
j++;
}
もちろん、逆の順序で新しい配列にコピーすることもできます。
「定位置」の操作を行うには、両端から中央に向かって作業します。最初と最後の要素をロードしてから、それらを元の場所から最後の場所に、最後の要素を最初の場所に格納します。次に、2番目と最後から2番目などを実行します。要素数が偶数の場合は、N/2回の繰り返しを実行します。奇数の場合は(N-1)/ 2回の繰り返しを行い、中央の要素をそのままにします。
キャッシュラインのサイズやその他のメモリ特性を考慮すると、わずかに高速になるアルゴリズムが他にもあると思われますが、本当にパフォーマンスが重要な状況でない限り、その価値はありません。
// Reverseメソッドを使用せず、追加の配列を使用せず//最後の要素から開始してyield演算子を試す
public IEnumerable<int> Reverse (int[] array)
{
for (int i = array.Length - 1; i >= 0; i--) {
yield return array [i];
}
}
char[] strx = { '1','2','3','4','5','6','7','8','9' };
int i = strx.Length;
string ktr ="";
while (i>0)
{
i--;
ktr += strx[i];
if (i==0)
{
i = strx.Length;
while (i > 0)
{
i--;
strx[i] = ktr[i];
}
}
}
int j;
Console.WriteLine("Array strx in reverse order: ");
for (j = 0; j < strx.Length; j++ )
{
Console.Write("{0}", strx[j]);
}
これは、次のように、最も高速なものから最も愚かなものまで、さまざまな方法で実行できます。
int[] arr = new int[] { 1,2,3 };
arr = (from a in arr orderby a descending select a).ToArray();
しかし、なぜあなたがそのような無駄な探求を追求しているのか理解できません。それが誰かに印象づけるために、forループの代わりにこれを使用するのであれば:)
//Create temp array with the same size.
int[] arrTemp = new int[arr.Length];
int i = 0;
//Assign last value of arr to first value of arrTemp
for (int j = arr.Length - 1; j >= 0; j--)
{
arrTemp[i] = arr[j];
i++;
}
arr = arrTemp;
次のようなものを試してください:
var counter = 1;
var newArr = new int[arr.length];
for(int i = 0; i < arr.length; i++)
{
newArr[i] = arr[arr.length - counter];
counter++;
}
私はそれをテストしませんでしたが、それは正しい軌道に乗っているはずです。 Array.Reverseを使用したくない理由はありますか?そのアルゴリズムはおそらく最適化されています。
私はループがまったく得意ではありません。しかし、これは私には簡単に思えます-
int[] array1 = { 1, 2, 3, 4, 5 };
int[] reverseArray = new int[array1.Length];
for (int i = 0; i <= array1.Length - 1; i++)
{
reverseArray[i] = array1[array1.Length - i - 1];
}
これは、任意のデータ型の配列を逆にする動的なソリューションです。このアルゴリズムのいくつかの重要な点は、最初に配列の長さの半分を計算し、配列インデックスが同じ値の場合に反復を停止するチェックを追加します。同じインデックスを持つステージは、逆の操作を再度開始します。この段階で、「goto Statement」を使用して外側のループを解除します。
string[] unreversed = {"A","B","C","D","E","F","G","H","I","J","K"};
int q=unreversed.Length;
int t = q / 2;
var temp1 = "A";
for(int i = 0;i<unreversed.Length;i++)
{
q = q - 1;
for(int k=q;k<=q;k++)
{
if (unreversed[k] != unreversed[i] && i!=t)
{
temp1 = unreversed[i];
unreversed[i] = unreversed[k];
unreversed[k] = temp1;
}
else
{
goto printarray;
}
}
}
printarray:
foreach (var k in unreversed)
{
Console.WriteLine(k);
}