2016-09-13 4 views
1
//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; 
      } 






} 

Also experimentiere ich schon eine Weile damit. Ich kann nicht alle möglichen Lösungen drucken. Zum Beispiel für 24 bin ich in der Lage, 7 + 17, aber nicht 2 + 5 + 17 zu drucken. Es gibt auch einige Antworten, die wiederholt werden, und das mag damit zu tun haben, dass ich keine doppelten Schecks habe. Ich habe versucht, die Ganzzahlen in eine Liste zu pushen und dann ein Hashset zu verwenden, um nur ganzzahlige Ganzzahlen zu haben, aber ich blieb stecken und versuchte, es brutal zu erzwingen. Alle Zahlen, die gedruckt werden sollen, sollen verschiedene Primzahlzahlen sein. Ich verstehe nicht, wie man alle eindeutigen Zahlen druckt, und gibt es eine elegante Weise, alles Mögliche auszudrucken.Summe der Zahlen als eindeutige Primzahlen

Danke für die Hilfe!

+0

Könnten Sie Ihren Code überprüfen? scheint die Klammer nicht richtig geschlossen zu sein – Prisoner

+0

Auch eine bessere Einrückung hilft sehr! –

Antwort

0

Sie wissen nicht, ob es für Sie elegant genug ist, aber ich habe püriert nur eine schmutzige Art und Weise, damit es funktioniert:

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); 
    } 

ich Ihre Lösung ziemlich schmutzig gefunden habe, so teilte ich das Problem zu verständlicher sein. GetPrimesUpTo gibt alle Primzahlen von 2 auf die Nummer, die Sie in der Eingabe zur Verfügung gestellt haben, SubSetsOf Kombination von Zahlen zurückgibt, die die Eingangsnummer aufsummiert gleich Sie zur Verfügung gestellt haben und schließlich die foreach in Main erzeugt formatierte Ausgabe, die auf dem Auge einfach ist. Ich hoffe es hilft!

+0

Ok Ich verstehe, wo ich in meiner Implementierung jetzt falsch gelaufen bin.Ich habe versucht, "n" hinzuzufügen. Ich war nur brutal Zwang für 2 verschiedene Lösungen, anstatt für den Rest der Lösungen zu berechnen. Können Sie mir bitte die letzte Vergangenheit Ihrer Lösung erklären? Ausgehend von "public static IEnumerable > SubSetsOf (diese IEnumerable Quelle)" Ich möchte dies mit meiner Version replizieren. –

+0

Es nimmt Liste von Elementen und verwenden Rekursion, um jede mögliche Teilmenge davon zurückzugeben, dh: wenn Sie eine Anordnung der Primzahlen [2, 3, 5] zur Verfügung stellen, produziert es [2, 3, 5], [2, 3], [2, 5], [2], [3, 5], [3]. Mit dieser Information können wir jeden einzelnen von ihnen zusammenfassen und mit dem Wert vergleichen, den wir bekommen wollen. Dies werden mögliche Lösungen sein. Es ist alles andere als optimal, aber so selbsterklärend wie möglich. Verstehst du es jetzt? –

+0

Ja, es macht jetzt einen Sinn. Sorry, ich habe vor einer Woche oder so im Grunde mit der Programmierung in C# begonnen. Aber beim Betrachten meines Codes gab es irgendwelche eklatanten Fehler oder Probleme, abgesehen von dem ganzen Teil der Primzahl. Ich werde versuchen, so viel wie möglich in meinen Code zu implementieren, basierend auf den hier gegebenen Informationen, da ich diese Aufgabe in anderen Sprachen wiederholen muss. –

0

Vorausgesetzt, dass Sie haben Sammlung von Primzahlen und IsPrime Methode

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); 
} 

Sie recoursive Lösung implementieren können

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; 
} 

-Test

var result = ToListOfPrimes(28); 

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

Console.Write(report); 

Ergebnis (28)

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

Für 24

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

Wenn Sie wirklich wollen es in anderen Sprachen implementieren nur Ihre Lösung ist Müll werfen. Sie sollten genauer angeben, was während der Ausführung passiert. Geschachtelte for-Schleifen mit mehreren if-Anweisungen sind überhaupt nicht explizit. Was im Beispiel noch schlimmer ist - Sie müssen jedes Mal neue for-Schleifen hinzufügen, wenn Sie mehr Zahlen in der Summe haben wollen. Ich glaube, es ist schwer für einen Neuling zu verstehen, aber ich finde Rekursion der einzige Weg, um hier zu gehen.

überzeugen Sie sich selbst:

  1. es ist schwer zu sagen, warum Ausgabe Ihres Programms falsch ist, weil die Logik
  2. Variablen Bedeutung benannt werden sollte, so dass Sie wissen, was sie speichern, anstatt blindes Erraten.
  3. Ihre checkPrime Methode gibt int zurück, auch wenn Sie zurückkommen 0 oder 1, so sollte es wirklich Bool Typ

Verwenden Debugger und ein Stück Papier zurückkehren zu verstehen, wie Rekursion entweder in meiner vorherigen Antwort oder das mitgelieferte funktioniert durch Dmitry Bychenko

Verwandte Themen