2013-10-30 103 views
2

我一定很累,因爲這是逃避我,覺得它應該很簡單,所以請對我輕鬆。如何在沒有迭代的情況下轉換對象數組?

如果A,B,和C是在存儲器中的所有類別和陣列是元件0-2:

[0] = A 
[1] = B 
[2] = C 

欲陣列移動,使得它變成這樣:

[0] = C 
[1] = A 
[2] = B 

我希望能夠走向任何一個方向,但我會假設,如果有人能指出我如何在一個方向上做到這一點,我可以找出另一個方向。

編輯:想到我應該提到,我需要這個沒有迭代,如果可能的話。

編輯2:這是一個僞無限地形的3D遊戲。數組中的每個對象都是大塊的地形數據。我想轉移他們,因爲他們包含每個大量數據的非常大的鋸齒狀數組。隨着玩家的移動,我有地形滑動(進/出)內存。我從來沒有考慮過只做一個array.copy來移動數組,然後完全重建下一系列塊的性能。所以爲了消除這個相對較小的性能問題,我想按照所述的方式將數組轉換爲包裝,而不是通過重新分配內存重新構建整個下一系列塊,我將重新使用巨大的鋸齒狀通過將默認值複製到它們中而不是完全重新初始化它們來提到數組。

踢所以你可以看到我在做什麼之前:

public void ShiftChunks(strVector2 ChunkOffset) { 
      while (ChunkOffset.X < 0) { 
       Array.Copy(Chunks, 0, Chunks, 1, Chunks.Length - 1); 

       for (int X = 1; X < maxChunkArraySize; X++) 
        for (int Z = 0; Z < maxChunkArraySize; Z++) 
         Chunks[X][Z].SetArrayPosition(X, Z); 

       Chunks[0] = new clsChunk[maxChunkArraySize]; 

       for (int Z = 0; Z < maxChunkArraySize; Z++) 
        Chunks[0][Z] = new clsChunk(0, Z); 

       ChunkOffset.X++; 
      } 

      while (ChunkOffset.X > 0) { 
       Array.Copy(Chunks, 1, Chunks, 0, Chunks.Length - 1); 

       for (int X = 0; X < maxChunkArraySize - 1; X++) 
        for (int Z = 0; Z < maxChunkArraySize; Z++) 
         Chunks[X][Z].SetArrayPosition(X, Z); 

       Chunks[maxChunkArraySize - 1] = new clsChunk[maxChunkArraySize]; 

       for (int Z = 0; Z < maxChunkArraySize; Z++) 
        Chunks[maxChunkArraySize - 1][Z] = new clsChunk(maxChunkArraySize - 1, Z); 

       ChunkOffset.X--; 
      } 

      while (ChunkOffset.Z < 0) { 
       for (int X = 0; X < maxChunkArraySize; X++) { 
        Array.Copy(Chunks[X], 0, Chunks[X], 1, Chunks[X].Length - 1); 
        for (int Z = 1; Z < maxChunkArraySize; Z++) 
         Chunks[X][Z].SetArrayPosition(X, Z); 

        Chunks[X][0] = new clsChunk(X, 0); 
       } 
       ChunkOffset.Z++; 
      } 

      while (ChunkOffset.Z > 0) { 
       for (int X = 0; X < maxChunkArraySize; X++) { 
        Array.Copy(Chunks[X], 1, Chunks[X], 0, Chunks[X].Length - 1); 

        for (int k = 0; k < maxChunkArraySize - 1; k++) 
         Chunks[X][k].SetArrayPosition(X, k); 

        Chunks[X][maxChunkArraySize - 1] = new clsChunk(X, maxChunkArraySize - 1); 
       } 
       ChunkOffset.Z--; 
      } 
     } 

如果有人想給我如何可能做到這一點甚至更好或如何進一步優化代碼,隨時讓意見我知道。

+0

爲什麼禁止迭代? –

+0

你將如何移動數組中的每個元素而不用迭代它?它可以一次完成,但它不像你可以簡單地告訴運行時「,嘿,這個數組是從_that_內存位置開始,然後讓它迴繞它。」數組不能像鏈接列表一樣簡單地重新排列;)。 –

+0

@ p.s.w.g性能是我反對迭代的理由。 – Mythics

回答

5
static void Rotate<T>(T[] source) 
{ 
    var temp = source[source.Length - 1]; 
    Array.Copy(source, 0, source, 1, source.Length - 1); 
    source[0] = temp; 
} 
+0

+1,非常優雅。 –

+0

如果你可以旋轉指定數量的元素,它會更加優雅;)。 –

+0

這是作業;) – Matthias

3

我碰巧這已經創造了確切的事情只是在幾天前:

private static T[] WrapAround<T>(T[] arr, int amount) { 
     var newArr = new T[arr.Length]; 

     while (amount > 1) { 
      for (var i = 0; i < arr.Length; i++) { 
       if (i != 0) { 
        newArr[i] = arr[i - 1]; 
       } 

       if (i == 0) { 
        newArr[i] = arr[arr.Length - 1]; 
       } 
      } 

      arr = (T[]) newArr.Clone(); 
      amount--; 
     } 

     return newArr; 
    } 

編輯:其實,@Matthias的解決方案是一個容易得多。你可能想使用代替。

+0

儘管如此,我很欣賞這種迴應。謝謝! :) – Mythics

0

這裏有一個函數,它將使用Array.Copy()任意方向上的任何偏移量(最大爲+/-的數組長度)旋轉數組。

這是Matthias上面答案的擴展。它分配一個具有偏移大小的臨時數組來處理包裝。

void Rotate<T>(T[] array, int offset) { 
    if (offset==0) return; 
    if (offset>0) { 
    var temp = new T[offset]; 
    System.Array.Copy(array, array.Length-offset, temp, 0, offset); 
    System.Array.Copy(array, 0, array, offset, array.Length-offset); 
    System.Array.Copy(temp, 0, array, 0, offset); 
    }else{ 
    var temp = new T[-offset]; 
    System.Array.Copy(array, 0, temp, 0, -offset); 
    System.Array.Copy(array, -offset, array, 0, array.Length+offset); 
    System.Array.Copy(temp, 0, array, array.Length+offset, -offset); 
    } 
} 

然而,對於您所描述的使用情況下,可能會更快而不是數組在所有移位,但檢索數據時,還是用一個週期性指數。

相關問題