C#列表的乘法

时间:2013-08-08 16:03:27

标签: c# multiplication

我正在大脑冻结,无法找到解决这个问题的方法。

我创建了一个名为CustomSet的类,其中包含一个字符串列表。包含对CustomSet的引用的类将其存储为列表。

public class CustomSet : IEnumerable<string>
{
    public string Name { get; set; }
    internal IList<string> elements;

    public CustomSet(string name)
    {
        this.Name = name;
        this.elements = new List<string>();
    }

    public IEnumerable<string> Elements
    {
        get
        {
            return elements;
        }
    }
    public IEnumerator<string> GetEnumerator()
    {
        return elements.GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

所以我想要做的是迭代这个自定义集列表以输出一个2d字符串数组,其中列是customSet的数量,行是customSet元素的乘法。

例如,如果列表中有3个自定义集:1st有3个元素,2nd有2个元素,3rd有3个元素。我想输出3列和18行(3 * 2 * 3)。以下代码是尝试解决方案:

CustomSet motion = new CustomSet("Motion");
motion.Elements.Add("low");
motion.Elements.Add("medium");
motion.Elements.Add("high");

CustomSet speed = new CustomSet("Speed");
speed.Elements.Add("slow");
speed.Elements.Add("Fast");

CustomSet mass = new CustomSet("Mass");
mass.Elements.Add("light");
mass.Elements.Add("medium");
mass.Elements.Add("heavy");

List<CustomSet> aSet = new List<CustomSet>();
aSet.Add(motion);
aSet.Add(speed);
aSet.Add(mass);

//problem code
int rows = 1;
for(int i = 0; i < aSet.Count; i++)
{
    rows *= aSet[i].Elements.Count;
}

string[,] array = new String[aSet.Count, rows];
int modulus;

for (int i = 0; i < aSet.Count; i++)
{
    for (int j = 0; j < rows; j++)
    {
        modulus = j % aSet[i].Elements.Count;
        array[i, j] = aSet[i].Elements[modulus];
    }
}

for (int j = 0; j < rows; j++)
{
    for (int i = 0; i < aSet.Count; i++)
    {
        Console.Write(array[i, j] + " / ");
    }
    Console.WriteLine();
}
//end

Console.ReadLine();

但是,代码不会输出正确的字符串数组(尽管它已关闭)。我想要的是以下内容:

低/慢/亮/

低/慢/中/ /

低/慢/重/

低/快/轻/

低/快/中/

低/快/重/

中/慢/轻/

中/慢/中/ /

中/慢/重/

中/快/轻/

中/快/中/

中/快/重/

高/慢/轻/

高/慢/中/ /

高/慢/重/

高/快/轻/

高/快/中/

高/快/重/

现在,此问题中的变量是列表中的customSets数和每个CustomSet中的元素数。

2 个答案:

答案 0 :(得分:6)

您可以一次性获得该产品:

var crossJoin = from m in motion
                from s in speed
                from ms in mass
                select new { Motion = m, Speed = s, Mass = ms };

foreach (var val in crossJoin)
{
   Console.Write("{0} / {1} / {2}", val.Motion, val.Speed, val.Mass);
}

现在,由于你不知道列表的数量,你需要做更多的事情。 Eric Lippert在this article中介绍了这一点,您可以在其中使用以下方式定义的CertesianProduct函数:

var cProduct = SomeContainerClass.CartesianProduct(aSet.Select(m => m.Elements));
var stringsToOutput = cProduct.Select(l => string.Join(" / ", l));

答案 1 :(得分:1)

这种递归方法根据需要显示结果,包含n个CustomSet对象的列表:

void OutputSets(List<CustomSet> aSet, int setIndex, string hirarchyString)
{
    string ouputString = hirarchyString;
    int nextIndex = setIndex + 1;

    foreach (string element in aSet[setIndex].Elements)
    {
        if (nextIndex < aSet.Count)
        {
            OutputSets(aSet, nextIndex, hirarchyString + element + " / ");
        }
        else
        {
            Console.WriteLine(ouputString + element + " / ");
        }
    }
}

用以下方式调用:

OutputSets(aSet, 0, "");