随机测试i枚举,按顺序j次

时间:2012-10-30 22:37:18

标签: c# loops .net-4.0

我有一个IEnumerable与i项我需要迭代并测试另一个带有j项的IEnumerable。但是,我应该随机迭代,并且在j的每次迭代中,可能会测试与i不同的项目:

list_of_is = [ a, b, c, d, e, f, g ]
list_of_js = [ x, y, z ]

让我们假设随机化i是微不足道的,所以我们可以很容易地生成这样的东西:

random_is[x] = [ e, b, f, g, d, a, c ]
random_is[y] = [ f, b, g, c, a, d, e ]
random_is[z] = [ d, g, f, c, b, e, a ]

现在我们需要的基本上是:

for (int i = 0; i < list_of_is.Count(); i++)
{
   foreach (var j in list_of_js)
   {
      yield return j.DoSomething(random_is[j][i]);
   }
}

,输出为:

e x ,f y ,d z ,b x ,b y ,g z ,...

现在,有没有办法在不存储random_is变量的情况下执行此操作?两个列表都非常大,这将占用大量内存。

修改 只是为了澄清,订购很重要。 j的每次传递应该只“处理”它的random_i中的下一个项目。总的来说,处理应按以下顺序完成:

enter image description here

2 个答案:

答案 0 :(得分:1)

解决问题的一种方法是交换你的循环。那就是:

foreach (var j in list_of_js)
{
    random_i = generateRandom(j);
    for (int i = 0; i < list_of_is.Count(); ++i)
    {
        return j.DoSomething(random_i[i]);
    }
}

虽然查看代码,但return将会破坏循环。也许你的意思是yield return

在任何情况下,这使得必须仅生成每个随机列表一次,并且一次只需要在内存中收集一个random_is。但是,它确实改变了生成事物的顺序。如果您可以保存中间值并在生成所有值后重新排列,那么这不是问题。

答案 1 :(得分:1)

除非您首先将其转换为数组,否则您无法真正随机化Enumerable,因为根据定义,枚举器一次获得1个值,令牌为令牌。

所以,如果我理解正确,我会做这样的事情......

  1. 将list_of_is转换为数组
  2. 对于list_of_js中的每个j
  3. 循环执行list_of_is执行Fisher-Yates shuffle
  4. 循环通过list_of_is并执行f(j,i),其中i是shuffle中的当前索引
  5. 这是一个简单的例子,我希望这有帮助(抱歉修复了一些错误)

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
    
            static IEnumerable<char> list_of_is = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g'};
            static IEnumerable<char> list_of_js = new char[] { 'x', 'y', 'z' };
    
            static void Main(string[] args)
            {
                foreach (string result in Randomize())
                    Debug.Write(result);
            }
    
            public static IEnumerable<String> Randomize()
            {
                char[] random_is = list_of_is.ToArray();
                int jCount = list_of_js.Count();
    
                Random r = new Random();
    
                // foreach j
                foreach(char j in list_of_js)
                {
                    // create a random ordering of is
                    for (int i = random_is.Length - 1; i >= 0; i--)
                    {
                        int x = r.Next(0, i);
    
                        // swap
                        char temp = random_is[x];
                        random_is[x] = random_is[i];
                        random_is[i] = temp;
                    }
    
                    // now evaluate the random pairs
                    foreach(Char i in random_is)
                        yield return String.Format("{0}{1} ", Char.ToUpper(i), j);
                }
            }
        }
    }
    

    输出

    Gx Cx Ex Bx Fx Ax Dx Dy By Fy Ay Cy Gy Ey Bz Az Gz Cz Fz Ez Dz
    

    修改 实际上,它只是打击我,你的伪代码看起来不太正确。您正在生成3个随机数组的7个值..然后想要为每个随机数组输出X,Y,Z对。看来你需要3 * 7 * 3 = 63输出..

    因此,这可能更准确:

    public static IEnumerable<String> Randomize()
    {
        char[] random_is = list_of_is.ToArray();
        int jCount = list_of_js.Count();
    
        Random r = new Random();
    
        // foreach j
        for (int random = 0; random < jCount; random++)
        {
            // create a random ordering of is
            for (int i = random_is.Length - 1; i >= 0; i--)
            {
                int x = r.Next(0, i);
    
                // swap
                char temp = random_is[x];
                random_is[x] = random_is[i];
                random_is[i] = temp;
            }
    
            // now evaluate the random pairs
            foreach (Char i in random_is)
                foreach(Char j in list_of_js)
                    yield return String.Format("{0}{1} ", Char.ToUpper(i), j);
        }
    }
    

    它输出:

    Cx Cy Cz Gx Gy Gz Dx Dy Dz Bx By Bz Fx Fy Fz Ax Ay Az Ex Ey Ez Bx By Bz Cx Cy Cz Fx Fy Fz Ax Ay Az Ex Ey Ez Dx Dy Dz Gx Gy Gz Cx Cy Cz Ax Ay Az Bx By Bz Gx Gy Gz Fx Fy Fz Ex Ey Ez Dx Dy Dz