2017-02-25 107 views
0

我正在學習編寫代碼。我正在使用Unity和C#,我發現嘗試通過for循環創建和填充多個數組存在一些困難。用for循環創建和填充多個數組

在其他語言中,你可以做這樣的事情:

for (int j = 0; j <= 3; j++) 
    { 
    scenes[j] = new float[2] {test[j], test2[j] }; 
    } 

但顯然我不能做在C#中類似的東西。是對的嗎?

那我該怎麼辦?

我需要像這樣創造一些東西:

scenes1 = {x1, y1} 
scenes2 = {x2, y2} 

等等...

+0

請使用'scenes','test'和'test2'的定義擴展您的代碼示例,以便我們可以知道它們的類型。另外,特定的編譯器錯誤可能會有幫助 – SergGr

+0

基本上這是我的問題。 在我的程序中,我有不同的場景,在這個場景裏面,我也需要改變一個變量。 我有8個場景和5個高點 我想隨機選擇1個高1場景,以我擁有所有可能的組合,隨機和不重複的方式。 我創建了兩個不同的數組,我洗牌場景數組,然後通過for循環,我採取了一個場景和1高。問題是,我有隨機的場景,但高位將始終是相同的順序,如果我洗牌高位,顯然我不再有一個平衡的變量組合。 – CornelioQuinto

+0

所以我試圖做的是使用一個函數來創建兩個數組的組合,然後創建40個新的數組長度= 2 dinamically,每個數組將會是我的組合之一..聽起來很愚蠢,但可能閱讀上面的消息,可能會有更巧妙的解決方案 – CornelioQuinto

回答

0

的多維數組可以給你一個解決問題的辦法,所有的你的數據可以進入一個單個數組,在你的情況下,你可能會使用類似場景的結構['index或position','test','test2'],我對C#不太熟悉(不幸),但是你可以看到更多here。希望這可以幫助。

+0

謝謝Kudzai,我在那個時候想到的問題是,我不知道如何從那裏採取隨機元素,以便擁有所有的組合沒有重複 – CornelioQuinto

+0

@CornelioQuinto要從一個數組中生成一個像test和test2的隨機索引,你可以實現類似[解決方案](http://stackoverflow.com/questions/2019417/access-random-item-in-list)到這個問題,檢查一下,看看它是否有幫助。 – 2017-02-25 06:26:15

0

根據你在評論中的回答,我仍然不明白你到底需要什麼。 AFAIU你有兩件數據:場景和高度;並且您想要生成複合(場景,高度)元素的排列。我認爲你要麼需要:

  1. 生成所有可能的permuations的恰好一次

  2. 隨機列表隨機生成不同permuations

長(可能是無限的)流所以在這裏是一些可能有用的代碼。

首先讓我們定義一些樣板:

public class Scene 
    { 
     public readonly string Something; 

     public Scene(string something) 
     { 
      Something = something; 
     } 

     // something else 
    } 

    public struct CompoundSceneData 
    { 
     public readonly Scene Scene; 
     public readonly float Height; 

     public CompoundSceneData(Scene scene, float height) 
     { 
      Scene = scene; 
      Height = height; 
     } 
    } 

當然你Scene類是最有可能更爲複雜。 CompoundSceneData是一個表示場景+高度的單個項目的結構。

#1生成所有可能的permuations隨機列出恰好一次:

// Fisher–Yates shuffle of indices 0..size 
    int[] GenerateRandomIndicesPermutation(int size) 
    { 
     int[] permutation = Enumerable.Range(0, size).ToArray(); 
     Random rnd = new Random(); 
     for (int cur = size; cur >= 2; cur--) 
     { 
      int swapPos = rnd.Next(cur); 
      int tmp = permutation[swapPos]; 
      permutation[swapPos] = permutation[cur - 1]; 
      permutation[cur - 1] = tmp; 
     } 

     return permutation; 
    } 

    List<CompoundSceneData> GenerateAllRandomPermutationsOnce(Scene[] scenes, float[] heights) 
    { 
     int scenesCount = scenes.Length; 
     int heightsCount = heights.Length; 
     int totalCount = scenesCount * heightsCount; 
     List<CompoundSceneData> permutations = new List<CompoundSceneData>(totalCount); 
     foreach (var compoundIndex in GenerateRandomIndicesPermutation(totalCount)) 
     { 
      int sceneIndex = compoundIndex % scenesCount; 
      int heightIndex = compoundIndex/scenesCount; 
      permutations.Add(new CompoundSceneData(scenes[sceneIndex], heights[heightIndex])); 
     } 
     return permutations; 
    } 


    void TestUsageAllOnce() 
    { 
     Scene[] scenes = new Scene[] { new Scene("Scene #1"), new Scene("Scene #2") }; 
     float[] heights = new float[] { 0.1f, 0.2f, 0.3f }; 

     // this is effectively endless loop 
     foreach (CompoundSceneData sceneData in GenerateAllRandomPermutationsOnce(scenes, heights)) 
     { 
      // will be called excactly 2*3 = 6 times 
      DrawScene(sceneData); 
     } 
    } 

有幾個關鍵概念有:

  • 如果我們有N個場景和M的高度有將是N M置換,並給定範圍[0,N M-1]中的數字,您可以選擇一對。例如,2 * N + 5表示第5個場景+第2個高度(在基於0的索引(!)中)。

  • 因此,如果我們想要生成N個場景和M個高度的不同對的序列,那麼足以生成數字[0,N * M-1]的隨機序列並將其用作指數序列

  • 有一個衆所周知的Fisher–Yates shuffle算法來創建一個隨機排列。

#2隨機生成不同permuations無限流:

IEnumerable<CompoundSceneData> GenerateInfiniteRandomStream(Scene[] scenes, float[] heights) 
    { 
     Random rnd = new Random(); 
     while (true) 
     { 
      int sceneIndex = rnd.Next(scenes.Length); 
      int heightIndex = rnd.Next(heights.Length); 
      yield return new CompoundSceneData(scenes[sceneIndex], heights[heightIndex]); 
     } 
    } 


    void TestUsageInfinite() 
    { 
     Scene[] scenes = new Scene[] { new Scene("Scene #1"), new Scene("Scene #2") }; 
     float[] heights = new float[] { 0.1f, 0.2f, 0.3f }; 

     // this is effectively endless loop 
     foreach (CompoundSceneData sceneData in GenerateInfiniteRandomStream(scenes, heights)) 
     { 
      DrawScene(sceneData); 

      // this is the only thing that will stop the loop 
      if (IsEndOfGame) 
       break; 
     } 
    } 

    void TestUsageInfinite2() 
    { 
     Scene[] scenes = new Scene[] { new Scene("Scene #1"), new Scene("Scene #2") }; 
     float[] heights = new float[] { 0.1f, 0.2f, 0.3f }; 

     List<CompoundSceneData> fixedSizeList = GenerateInfiniteRandomStream(scenes, heights).Take(100).ToList(); 
     foreach (CompoundSceneData sceneData in fixedSizeList) 
     { 
      // this will be called 100 times (as specified in Take) 
      DrawScene(sceneData); 
     } 
    } 

這裏唯一有趣的事情是一個C#的特徵yield return的使用。該功能允許從看起來順序的代碼創建數據流(IEnumerable)。

請注意,對於解決方案#2,不能保證每個組合(場景+數據)只會出現一次(N * M)個項目。它只是生成隨機組合,只有長期運行才具有良好的統計特性。也有可能實現這種保證,但它使代碼顯着複雜化,並且用戶可能不會注意到。