Autor Beitrag
sepp_a_u
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51

Win Vista (Laptop), Win XP (PC)
C# (MS Visual Studio Express Edition)
BeitragVerfasst: Mo 01.10.07 21:45 
hi @ all

bin anfänger in c# und wollte mal meinen ersten algorithmus vorstellen:

das sieb des eratosthenes:
hier mal der code. vll kann man daran ja noch was verbessern?

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            long max;
            Console.Write("Bitte geben Sie eine Grenze ein: ");
            max = Int32.Parse(Console.ReadLine());

            Primzahlen(max);

            Console.WriteLine("\n\nPress ENTER to leave");
            Console.ReadLine();
        }
        static void Primzahlen(long grenze)
        {
            int i;
            bool[] sieb = new bool[grenze + 1];
            for (i = 2; i <= grenze; i++)
            {
                sieb[i] = false;
            }
            i = 2;
            while (i * i <= grenze)
            {
                if (!sieb[i])
                {
                    for (int j = i * i; j <= grenze; j = j + i)
                    {
                        sieb[j] = true;
                    }
                }
                i++;
            }
            for (i = 2; i <= grenze; i++)
            {
                if (!sieb[i])
                {
                    Console.Write(i + " ");
                }
            }
        }
    }
}


mfg
r2c2
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 324
Erhaltene Danke: 2

Linux

BeitragVerfasst: Di 02.10.07 08:51 
Hallo,

meine Kommentare zum Code:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            long max;
            Console.Write("Bitte geben Sie eine Grenze ein: ");
            max = Int32.Parse(Console.ReadLine()); // was machst du, wenn der User gar keine Zahl eingibt, sondern z.B. "Hallo"

            Primzahlen(max);

            Console.WriteLine("\n\nPress ENTER to leave"); // Wasw jetzt nun? Deutsch oder Englisch?
            Console.ReadLine();
        }
        static void Primzahlen(long grenze) // Funktionen benennt man normalerweise nach Verben. Also nicht Primzahlen, sondern: FindeFrimzahlen oder sowas...
        {
            int i;
            bool[] sieb = new bool[grenze + 1];
            for (i = 2; i <= grenze; i++)
            {
                sieb[i] = false;
            }
            i = 2;
            while (i * i <= grenze) // kann man so amchen, ja. 
// Geht aber besser: So wird pro Schleifendurchlauf einmal multipliziert. 
// Besser man zieht ganz zu Anfang einmal die Wurzel und prüft auf i <= wurzel. 
// Nun ich die Wurzelfunktion auch nicht sonderlich schnell, und bis auch die 20.
// Nachkommastelle brauchst dus auch nicht. Also wäre zu überlegen, ob man ne 
// eigene Wurzelfunktion schreibt, die nach einer Nachkommastelle abbricht... 
// ==> siehe z.B. Heron-Algorithmus
            {
                if (!sieb[i])
                {
                    for (int j = i * i; j <= grenze; j = j + i) // so, jetzt wirds ganz merkrürdig:
// was machst du hier? Das ist aber nicht der korrekte Algorithmus 
// und ich zweifle hochgradig, dass das so funktuioniert.
// Beispiel: i = 2, grenze = 10
// i*i = 4 ==> du setzt alles von 4 bis einschließlich 10 auf true. 
// 4,6,8,9 und 10 sind aber definitiv keine Primzahlen...
                    {
                        sieb[j] = true;
                    }
                }
                i++;
            }
            for (i = 2; i <= grenze; i++)
            {
                if (!sieb[i])
                {
                    Console.Write(i + " ");
                }
            }
        }
    }
}


mfg

Christian

_________________
Kaum macht man's richtig, schon klappts!
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Di 02.10.07 09:21 
Hallo,

der Algorithmus stimmt schon, denn die Ausgabe bezieht sich auf !sieb[i]
Es wäre einleuchtender das Feld auf true zu setzen und anschliessend alle nicht Primzahlen auf false.

ausblenden C#-Quelltext
1:
2:
3:
4:
 if (!sieb[i]) 
                { 
                    Console.Write(i + " "); 
                }


Gruß Horst
r2c2
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 324
Erhaltene Danke: 2

Linux

BeitragVerfasst: Di 02.10.07 09:36 
Hm... hab cih gar nicht bemerkt, da hast du Recht. Allerdings wären dann in meinem Beispiel oben 5 und 7 keine Primzahlen...

*grad vorsichtshalber doch mal ausprobiert*
Hm... funktioniert doch...
*durchsteppt*
Ah...

Hatte das j = j + i fälschlicherweise als j +1 gelesen. :oops: Ich sollte mir wohl nochmal die Brille putzen...

mfg

Christian

_________________
Kaum macht man's richtig, schon klappts!
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 02.10.07 10:52 
Für einen Anfänger ist die Umsetzung wirklich gut gelungen, hier noch ein paar Tipps:
Das Array ist schon mit false initialisiert, die erste Schleife kann also weggelassen werden. Die letzte lässt sich ebenfalls entfernen, indem sie in die mittlere integriert wird. Außerdem sollte der Algorithmus allgemein einsetzbar gemacht werden, indem er IEnumerable<int> zurückgibt.
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
using System;
using System.Collections.Generic;

static class SieveOfEratosthenes
{
  public static IEnumerable<int> FindPrimes(int limit) // was eigentlich nun, long oder int ;) ?
  {
    // zu überlegen wäre der Einsatz eines BitArrays,
    // ist wie immer eine Entscheidung zwischen Performance und Speicherverbrauch
    bool[] sieve = new bool[limit + 1];
    int limitSqrt = (int)Math.Sqrt(limit);

    for (int i = 2; i <= limit; i++)
      if (!sieve[i]) {
        yield return i;
        if (i <= limitSqrt)
          for (int j = i * i; j <= limit; j += i)
            sieve[j] = true;
      }
  }
}

Viel mehr zu optimieren würde ich gar nicht versuchen, dafür nimmt man einfach einen besseren Algo ;) .