【问题标题】:Multiplication Combinations (Simple C#)乘法组合(简单 C#)
【发布时间】:2014-05-13 15:22:49
【问题描述】:

所以我有一个长度可变的 ulong 素数列表。

例如:2,5,7,3

我想创建每个相乘组合,不包括所有相乘的数字。 (在这种情况下为 2*5*7*3)。

例如:2,3,5,6,7,10,14,15,21,30,35,42,70,105。

我尝试了几个使用“foreach”循环的解决方案,但我似乎无法理解。似乎太容易了。什么可能是解决此问题的有效方法?

我遇到的主要问题是,当我向列表中添加新值时,“foreach”循环会导致错误,因为我对其进行了更改。除了做一大堆新列表之外,我想不出办法解决这个问题。在我看来,应该有一个非常简单、干净的解决方案,但我只是过于复杂了。

我尝试了“构建”逼近,将基本因子相乘,以创建更大的因子等等,而“构建”逼近,从大数开始,然后将其分解(如我的例子)。这是我尝试过的:

List<ulong> c, f;
ulong i;
//Some code then sets c to the factors (2, 3, 5, and 7)
//i is then set to the c set multiplied together (2*3*5*7)

//if the c is a factor, divide and add it to the new list f (the final list)
foreach (ulong u in c) 
{
    if (i % u == 0)
    {
        f.Add(i/u);
        Console.WriteLine(i / u);
    }
}

// Keep on dividing the numbers down, until you get the original factors added to the list
for (int j = 0; j < f.Count -1; j++)
{
    foreach (ulong u in c)
    {
        foreach (ulong v in f)
        {
            if (v % u == 0)
            {
                if (v / u != 1 && !f.Contains(v / u))
                {
                    f.Add(v / u);
                }
            }
        }
    }
}

带输入的预期输出 (2 5 7 3):

  • 2
  • 5
  • 3
  • 7
  • 2 * 3 = 6
  • 2 * 5 = 10
  • 2 * 7 = 14
  • 5 * 7 = 35
  • 5 * 3 = 15
  • 7 * 3 = 21
  • 2 * 5 * 7 = 70
  • 2 * 5 * 3 = 30
  • 2 * 3 * 7 = 42
  • 5 * 7 * 3 = 105

【问题讨论】:

  • 这不是“解决我的家庭作业”问题的好地方。请先向我们展示您迄今为止所做的尝试。请记住,按几次 Enter 按钮可以让您的问题更具可读性。
  • 它的爱好编程......我会添加一些例子。
  • 听起来递归的解决方案是可行的......在寻求帮助之前自己尝试一下。
  • 我不明白您所说的“除了所有数字组合(在这种情况下为 2*5*7*3)”是什么意思。
  • 抱歉,这意味着 2*5*7*3 (210) 已从列表中排除,但所有其他组合都有效

标签: c#


【解决方案1】:

这可以得到你想要的数字:

Func<IEnumerable<ulong>, IEnumerable<ulong>> f = null;
f = xs =>
{
    if (xs.Any())
    {
        return f(xs.Skip(1))
            .SelectMany(x =>
                new [] { xs.First() * x, x });
    }
    else
    {
        return new ulong[] { 1 };
    }
};

你可以这样使用它:

var primes = new ulong[] { 2, 5, 7, 3 };

var results = f(primes)
    .OrderBy(x => x)
    .ToArray();

results = results
    .Skip(1)
    .Take(results.Length - 2)
    .ToArray();

我必须使用Skip/Take 来摆脱您想要避免的两种情况。

我得到的结果是:

如果您希望它作为(几乎)单线,它是:

Func<IEnumerable<ulong>, IEnumerable<ulong>> f = null;
f = xs => xs.Any() ? f(xs.Skip(1)).SelectMany(x => new [] { xs.First() * x, x }) : new ulong[] { 1 };

【讨论】:

    【解决方案2】:

    以下代码应为您提供列表中任意数量项目所需的确切信息

    class Program
    {
        static void Main(string[] args)
        {
            MultiplyFactors(new List<ulong>() { 2, 3, 5, 7 });
    
            Console.ReadLine();
        }
    
        public static void MultiplyFactors(List<ulong> numbers)
        {
            var factorCombinations = CreateSubsets(numbers.ToArray());
    
            foreach (var factors in factorCombinations)
            {
                // set initial result to identity value. (any number multiplied by itself is 1)
                ulong result = 1;
    
                // multiply all factors in combination together
                for (int i = 0; i < factors.Count(); i++)
                {
                    result *= factors[i];
                }
    
                // Output for Display
                Console.WriteLine(String.Format("{0}={1}", String.Join("x", factors), result));
    
            }
        }
    
        private static List<T[]> CreateSubsets<T>(T[] originalArray)
        {
            // From http://stackoverflow.com/questions/3319586/getting-all-possible-permutations-from-a-list-of-numbers
            var subsets = new List<T[]>();
    
            for (int i = 0; i < originalArray.Length; i++)
            {
                int subsetCount = subsets.Count;
                subsets.Add(new T[] {originalArray[i]});
    
                for (int j = 0; j < subsetCount; j++)
                {
                    T[] newSubset = new T[subsets[j].Length + 1];
                    subsets[j].CopyTo(newSubset, 0);
                    newSubset[newSubset.Length - 1] = originalArray[i];
                    subsets.Add(newSubset);
                }
            }
    
            return subsets;
        }
    }
    

    这将为您的2,3,5,7 输入提供以下结果。

    2=2
    3=3
    2x3=6
    5=5
    2x5=10
    3x5=15
    2x3x5=30
    7=7
    2x7=14
    3x7=21
    2x3x7=42
    5x7=35
    2x5x7=70
    3x5x7=105
    2x3x5x7=210
    

    这可能是通过递归实现的,但这种方法可能同样简单。诀窍是创建您的子集列表。一旦你有了它,你只需将每个子集的所有元素相乘。

    【讨论】:

      猜你喜欢
      • 2016-05-01
      • 1970-01-01
      • 2016-05-22
      • 2022-11-20
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 2013-03-10
      相关资源
      最近更新 更多