//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。还有一些答案正在重复,这可能与我没有重复检查的事实有关。我试图将整数推入列表,然后使用一个哈希集只有不同的整数,但我卡住了,并试图暴力强迫它。所有要打印的数字都应该是不同的素数整数。我不明白如何打印所有不同的数字,并有一种优雅的方式来打印所有可能的。
感谢您的帮助!
答案 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循环。我相信对于一个新手来说很难理解它,但我发现递归是去这里的唯一方法。
亲眼看看:
使用调试器和一张纸来理解递归在我之前的答案或Dmitry Bychenko提供的答案中是如何工作的