数字之和作为不同的素数

时间:2016-09-13 05:41:24

标签: c# algorithm primes

//List Style


using System;
using System.Collections.Generic;
using System.Linq;


public class pr{

    static public void Main (){

            int n, i, j, k, l, sum,flag = 0;
            //int sum = i+j;
            //int k = (n-i);
            //int l = (n-j);

            //System.Console.WriteLine ("Enter a number");
            //n = Convert.ToInt32 (Console.ReadLine());

            //List <int> primes = new List <int>(); //list to handle the numbers
            //HashSet <int> myPrimes = new HashSet <int> (primes);


                 System.Console.WriteLine ("Enter a number");
                 n = Convert.ToInt32 (Console.ReadLine());
                 //myPrimes.Add(n);
                 //myPrimes.Add(i);
                 //myPrimes.Add(j);

                // var count = string.Join(", ", primes);
                  //System.Console.WriteLine("The value of n is {0}",myPrimes);

                    for(i=3; i<n/2; i++){

                        for(j=3; j<n/2; j++){

                            if(checkPrime(i) == 1){

                                if(checkPrime(j) == 1){

                                    if (checkPrime(n-i) == 1){

                                        if (checkPrime(n-j) == 1){

                                                //if(i == j){
                                                //sum = i+j;


                                            System.Console.WriteLine("{0}={1}+{2}\n",n,i,n-i);
                                        //}

                                    }
                                }
                            }
                        }

                            if (flag == 0 && (n-i) <= 0 && (n-j) <= 0){ //check to avoid dupes

                                    if (n <= 0 && i <= 0 && j <= 0){

                                        Console.Write("{0}\n",n);
                                    }


                            }


                        }
                    }

    }

            public static int checkPrime(int n){

                int i, j, flag = 1;

                for (i = 2; i<=(Math.Sqrt(n)); i++){ 

                    for (j = 2; j<=(Math.Sqrt(n)); j++){


                        if (n%i == 0 && n%j == 0 ){ //even number check

                                i++;
                                j++;
                                flag = 0;
                    } 

                }

            }

                return flag;
            }






}

所以我现在已经尝试了一段时间了。我似乎无法打印所有可能的解决方案。例如24我可以打印7 + 17而不是2 + 5 + 17。还有一些答案正在重复,这可能与我没有重复检查的事实有关。我试图将整数推入列表,然后使用一个哈希集只有不同的整数,但我卡住了,并试图暴力强迫它。所有要打印的数字都应该是不同的素数整数。我不明白如何打印所有不同的数字,并有一种优雅的方式来打印所有可能的。

感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

不知道它对你来说是否足够优雅,但我只是捣乱了一种方法让它发挥作用:

static void Main()
    {
        Console.WriteLine("Enter a number");
        var numberToSum = Convert.ToInt32(Console.ReadLine());

        var primesInRange = GetPrimesUpTo(numberToSum);
        var foundSolutions = primesInRange.SubSetsOf().Where(prime => prime.Sum() == numberToSum);

        foreach (var solution in foundSolutions.ToList())
        {
            var formatOperation = solution
                .Select(x => x.ToString())
                .Aggregate((a, n) => a + " + " + n) + " = " + numberToSum;

            Console.WriteLine(formatOperation);
        }

        Console.ReadLine();
    }

    public static IEnumerable<int> GetPrimesUpTo(int end)
    {
        var primes = new HashSet<int>();

        for (var i = 2; i <= end; i++)
        {
            var ok = true;

            foreach (var prime in primes)
            {
                if (prime * prime > i)
                    break;

                if (i % prime == 0)
                {
                    ok = false;
                    break;
                }
            }

            if (ok)
                primes.Add(i);
        }

        return primes;
    }

    public static IEnumerable<IEnumerable<T>> SubSetsOf<T>(this IEnumerable<T> source)
    {
        if (!source.Any())
            return Enumerable.Repeat(Enumerable.Empty<T>(), 1);

        var element = source.Take(1);

        var haveNots = SubSetsOf(source.Skip(1));
        var haves = haveNots.Select(set => element.Concat(set));

        return haves.Concat(haveNots);
    }

我发现你的解决方案非常脏,所以我把问题分开来更容易理解。 GetPrimesUpTo将所有素数从2返回到您在输入中提供的数字,SubSetsOf返回总计的数字组合等于您提供的输入数字,最后Main中的foreach生成格式化的输出,这很容易在眼睛上。希望它有所帮助!

答案 1 :(得分:0)

假设您拥有素数和IsPrime方法

的集合
private static int[] primes = new[] { 
  2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37 };

private static bool IsPrime(int value) {
  return primes.Contains(value);
}

您可以实施递归解决方案

private List<List<int>> ToListOfPrimes(int value, List<int> parts = null) {
  if (null == parts)
    parts = new List<int>();

  List<List<int>> result = new List<List<int>>();

  if (value == 0) {
    result.Add(parts.ToList());

    return result;
  }

  int minPrime = parts.Count <= 0 ? 0 : parts[parts.Count - 1];

  if (value <= minPrime)
    return result;

  // not that efficient: binary search will be a better choice here 
  for (int i = 0; i < primes.Length; ++i) {
    int p = primes[i];

    if (p <= minPrime)
      continue;
    else if (p > value)
      break;

    var list = parts.ToList();
    list.Add(p);

    var outcome = ToListOfPrimes(value - p, list);

    foreach (var solution in outcome)
      result.Add(solution);
  }

  return result;
}

测试

var result = ToListOfPrimes(28);

string report = String.Join(Environment.NewLine, result
  .Select(line => String.Join(", ", line)));

Console.Write(report); 

结果(28

2, 3, 5, 7, 11
2, 3, 23
2, 7, 19
3, 5, 7, 13
5, 23
11, 17

24

2, 3, 19
2, 5, 17
5, 19
7, 17
11, 13

答案 2 :(得分:0)

如果你真的想用其他语言实现它,只需将你的解决方案扔到垃圾箱。您应该更明确地了解执行过程中发生的情况。具有多个if语句的嵌套for循环根本不是显式的。在样本中更糟糕的是 - 每次你想要总和中的更多数字时,你需要添加新的for循环。我相信对于一个新手来说很难理解它,但我发现递归是去这里的唯一方法。

亲眼看看:

  1. 由于逻辑
  2. ,很难说为什么你的程序输出是错误的
  3. 变量应该被有意义地命名,这样你才能知道他们存储什么而不是盲目猜测。
  4. 你的checkPrime方法返回int,即使你返回0或1所以它应该真的返回bool类型
  5. 使用调试器和一张纸来理解递归在我之前的答案或Dmitry Bychenko提供的答案中是如何工作的