2017-02-25 92 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)个项目。它只是生成随机组合,只有长期运行才具有良好的统计特性。也有可能实现这种保证,但它使代码显着复杂化,并且用户可能不会注意到。