使用for循环创建并填充多个数组

时间:2017-02-25 03:55:46

标签: arrays loops dynamic-programming

我正在学习编码。我正在使用Unity和C#,我发现在尝试通过for循环创建和填充多个数组时遇到了一些困难。

在其他语言中,您可以执行以下操作:

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

但显然我不能在C#中做类似的事情。是吗?

那我该怎么办?

我需要创造这样的东西:

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

依旧......

2 个答案:

答案 0 :(得分:0)

多维数组可以为您提供问题的解决方案,您可以将所有数据放入单个数组中,在您的情况下,您可以使用类似场景的结构[&#39;索引或位置&#39;,&#39 ;测试&#39;,&#39; test2&#39;],我不熟悉C#(不幸的是),但你可以看到更多here。希望这会有所帮助。

答案 1 :(得分:0)

根据您在评论中的答案,我仍然不了解您的确切需求。 AFAIU你有两个数据:场景和高度;并且您想要生成复合(场景,高度)元素的排列。我假设你需要:

  1. 生成一次所有可能的permations的随机列表

  2. 生成随机不同渗透的长(可能无限)流

  3. 所以这里有一些可能有用的代码。

    首先让我们定义一些样板:

        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 只生成一次所有可能的permations的随机列表:

        // 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 生成随机不同permations的无限流:

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