Microsoft Visual C# 2005

Diskutiere Microsoft Visual C# 2005 im Developer Network Forum im Bereich Hardware & Software Forum; Stimmt die is kompliziert :) Wie könnte ich denn mit dem Ansatz meiner Lösung weiterkommen? Wo/Wie bau ich den Check nach Größe ein?
  • Microsoft Visual C# 2005 Beitrag #41
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Stimmt die is kompliziert :) Wie könnte ich denn mit dem Ansatz meiner Lösung weiterkommen? Wo/Wie bau ich den Check nach Größe ein?
 
  • Microsoft Visual C# 2005 Beitrag #42
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
using System;
using System.IO;

class App
{
public static void hilfsfunktion()
{
int i = 0;

FileStream fshf = new FileStream("C:\\GEMDAT54A.txt", FileMode.Open);
StreamReader readerhf = new StreamReader(fshf);
string hf;

while ((hf = readerhf.ReadLine()) != null)
{
Console.Write(hf + " * ");
++i;

if (i % 4 == 0)
{
Console.WriteLine(" \n");
}
}
}


public static void Main()
{

//Einlesen der 1. Datei
FileStream fs1 = new FileStream("C:\\DAT54A1.txt", FileMode.Open);
StreamReader reader1 = new StreamReader(fs1);
string zeile1;

//Einlesen der 2. Datei
FileStream fs2 = new FileStream("C:\\DAT54A2.txt", FileMode.Open);
StreamReader reader2 = new StreamReader(fs2);
string zeile2;

//Erstellen der Datei
FileStream fs3 = new FileStream("C:\\GEMDAT54A.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs3);

int zähler = 0;

while ((zeile1 = reader1.ReadLine()) != null && (zeile2 = reader2.ReadLine())!=null)
{

double zahl1 = Convert.ToDouble(zeile1);
double zahl2 = Convert.ToDouble(zeile2);

if (zahl1 < zahl2)
{
sw.WriteLine(zahl1);
sw.WriteLine(zahl2);
}

else
{
sw.WriteLine(zahl2);
sw.WriteLine(zahl1);
}

zähler+=2;
}

sw.Close();
//FELD

FileStream fs4 = new FileStream("C:\\GEMDAT54A.txt", FileMode.Open);
StreamReader readersort = new StreamReader(fs4);
string zeilesort;

double [] feld = new double[zähler];
double xyz = Convert.ToDouble(zeilesort = readersort.ReadLine());

for (int no = 0; no < zähler; no++)
{
feld[no] = xyz;
if (feld[no - 1] < feld[no])
{
sw.WriteLine(feld[no - 1]);
}
}

sw.Close();
hilfsfunktion();
Console.WriteLine(zähler);

}
}

Ich wusste mir jetzt net anders zu helfen ausser so mitm Feld. Kann mir jemand sagen, warum ich bei der IF-Anweisung im Feld die Fehlermeldung: "Index was outside the bounds of the array." Und wie ichs umschreiben kann, das es auch funktioniert, wenn die Dateien eine unterschiedliche Anzahl an Zeilen haben.
 
Zuletzt bearbeitet:
  • Microsoft Visual C# 2005 Beitrag #43
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Die zweite Schleife, in der Du alles nochmal sortierst, funktioniert nicht und ist auch überflüssig, da die Zahlen ja schon im ersten Schritt sortiert werden sollen. Ich hab da nochmal schnell was zusammengeschrieben:

Code:
        static void Main(string[] args)
        {
            string val1Str = null;
            string val2Str = null;
            double val1 = 0;
            double val2 = 0;

            StreamReader reader1 = new StreamReader(new FileStream("DAT54A1.txt", FileMode.Open));
            StreamReader reader2 = new StreamReader(new FileStream("DAT54A2.txt", FileMode.Open));
            StreamWriter writer = new StreamWriter(new FileStream("GEMDAT54A.txt", FileMode.Create));

            do
            {
                // Einlesen
                if (val1Str == null)
                {
                    val1Str = reader1.ReadLine();
                    val1 = Convert.ToDouble(val1Str);
                }

                if (val2Str == null)
                {
                    val2Str = reader2.ReadLine();
                    val2 = Convert.ToDouble(val2Str);
                }

                // Vergleichen
                if (val1Str == null)
                {
                    writer.WriteLine(val2);
                    val2Str = null;
                }
                else if (val2Str == null)
                {
                    writer.WriteLine(val1);
                    val1Str = null;
                }
                else if (val1 <= val2)
                {
                    writer.WriteLine(val1);
                    val1Str = null;
                }
                else if (val1 > val2)
                {
                    writer.WriteLine(val2);
                    val2Str = null;
                }
            } while (val1Str != null || val2Str != null);

            reader1.Close();
            reader2.Close();
            writer.Close();

            hilfsfunktion();
        }

Ist natürlich um einiges schwieriger zu lesen als meine erste Lösung, aber für große Dateien sehr viel performanter, weil die Dateien nicht erst komplett eingelesen werden müssen.
 
  • Microsoft Visual C# 2005 Beitrag #44
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Vielen Dank das du dich nochmal drum gekümmert hast :) Habs mal laufen lassen und es funktionert fast. Kann man irgendwie einbauen, dass es auch negative Zahlen korrekt behandelt? Ausserdem wenn die eine Datei länger ist als die andere ignoriert er einfach die zahlen die in der zweiten datei noch kommen würden.
 
  • Microsoft Visual C# 2005 Beitrag #45
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Hexer1985 schrieb:
Vielen Dank das du dich nochmal drum gekümmert hast :) Habs mal laufen lassen und es funktionert fast. Kann man irgendwie einbauen, dass es auch negative Zahlen korrekt behandelt? Ausserdem wenn die eine Datei länger ist als die andere ignoriert er einfach die zahlen die in der zweiten datei noch kommen würden.
Negative Zahlen werden korrekt behandelt. Bei Fließkommazahlen mußt Du nur aufpassen, daß Du keinen "." sondern ein "," schreibst, da das Programm automatisch das hierzulande übliche Format benutzt.

Bei letzterem hast Du Recht. Da ist noch ein kleiner Bug drin. Einfach die while-Bedingung durch folgende austauschen:
Code:
while (!reader1.EndOfStream || !reader2.EndOfStream);
 
  • Microsoft Visual C# 2005 Beitrag #46
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
1000 Dank! Das hat mir nen fetten Schub gegeben! Jetzt werd ich das letztemal für die nächsten paar Monate nochmal ne Frage zu ner Aufgabe haben! Ist das "gut" zu realisieren?

Schreiben Sie eine Funktion, die angibt, auf wie viele Arten man eine ganze Zahl (einen Geldbetrag) aus ganzen Zahlen zusammensetzen kann. Dabei dürfen die Teilbeträge (die Geldscheine) eine obere Grenze nicht überschreiten. Wir nehmen aber der Einfachheit halber an, dass es zu jeder kleineren Zahl einen passenden Schein gibt.
 
  • Microsoft Visual C# 2005 Beitrag #47
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Voraussetzung ist:

static int anz_summen // Anzahl der Moeglichkeiten
(int summe, // Summe, die gebildet werden soll
int grenze); // groesster erlaubter Betrag

Die Werte werden ja erst in der Mainfunktion übergeben, woher soll die aber schon die Summe der Möglichkeiten kennen? Bzw. die Grenze, weil die Grenze ist ja meine Eingabe - 1? Ich komm net auf den mathematischen Zweig und wie ich das darstellen soll!

Beispiel:

6 = 1+1+1+1+1+1
6 = 1+1+1+1+2
6 = 1+1+2+2
6 = 2+2+2
6 = 1+1+1+3
6 = 1+2+3
6 = 3+3
6 = 1+1+4
6 = 2+4
6 = 1+5

Im Beispiel wäre 11 die Antwort (wenn ich richtig gezählt habe).

Schreiben Sie ein Testprogramm, das Ihre Funktion prüft.
 
  • Microsoft Visual C# 2005 Beitrag #48
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Die Lösung ist ein rekursiver Algorithmus.

Du fängst mit der größten Grenze an und schaust, ob sie in die Summe paßt. Wenn ja, dann hast Du schon einen Summanden gefunden. Jetzt mußt Du die aktuelle Grenze und alle kleineren Grenzen nochmal testen. Dazu ruft sich die Funktion einfach selbst auf. Als Parameter bekommt die Funktion die aktuelle Summe, die aktuelle Grenze und einen Ausgabestring.

Die Summe erniedrigst Du bei jedem Aufruf um die Grenze. Wenn die Funktion dann als Summe 0 übergeben bekommt, weißt Du, daß Du mit einer Möglichkeit durch bist und kannst den String ausgeben und den Zähler erhöhen. Den Rest erledigt die Rekursion.

Beispiel: summe = 6, grenze = 3
3 3
3 2 1
3 1 1 1
2 2 2
2 2 1 1
2 1 1 1 1
1 1 1 1 1 1
=> 7
 
  • Microsoft Visual C# 2005 Beitrag #49
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Also die Grenze ist laut Aufgabenstellung immer

Ich hab jetzt in der Main-Funktion:

static void Main()
{
Console.Write("Geben Sie einen Wert ein: ");
int eingabe = Convert.ToInt32(Console.ReadLine());
int grenze = (eingabe - 1);
anz_summen(grenze, eingabe);
}

Hab ich es falsch verstanden, dass der Wert Summe, das letztendliche Ergebniss ist? Wenn ja was für einen Wert soll ich dann an anz_summen übergeben? Und ich weiss net wie ich das machen könnte , dass sich die Funktion selbst aufrufen kann. Ich hab an ne do-while-schleife gedacht, ich wüsste aber net was ich ins do reinschreiben soll! Danke für deine Hilfe
 
  • Microsoft Visual C# 2005 Beitrag #50
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Die main() sieht bei mir so aus:
Code:
        static void Main(string[] args)
        {
            int summe = 6;
            int grenze = summe - 1;

            int anz_summen = count("", summe, grenze);

            Console.WriteLine("Anzahl: " + anz_summen);
        }

Die eigentliche Arbeit erledigt die Funktion count()

Code:
        static int count(string ausgabe, int summe, int grenze)
        {
                if ...
                else if ...
                else
                {
                   return count(ausgabe, summe, grenze - 1);
                }
        }
count() ruft sich selbst auf und nähert sich so stückweise dem Ergebnis. Das nennt sich dann Rekursion und vereinfacht die Geschichte enorm.
Wahrscheinlich geht's auch irgendwie mit diversen Schleifen. Allerdings habe ich bei dem Wetter keine Lust, meine Gehirnwindungen zu verknoten ;-)
 
  • Microsoft Visual C# 2005 Beitrag #51
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Das g8bt vielleicht wieder nen Extrapunkt ;) Also ich hab mal versucht an Hand deines Ansatzes die If-Schleife zu füllen, meiner Ansicht nach schreibt er immer wenn Modulo 0 ist die Grenze auf solang bis grenze 0 ist

if(summe%grenze==0)
{
Console.Write(grenze + " ");
if (summe % grenze == 0)
{
Console.Write(grenze + " ");
}

else
{
while(grenze >= 0)
{
--grenze;
if(summe % grenze == 0)
{
Console.Write(grenze + " ");
}
}

}

Ich hab bloss no net verstandne für was du den String übergibst
 
Zuletzt bearbeitet:
  • Microsoft Visual C# 2005 Beitrag #52
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Hexer1985 schrieb:
Das g8bt vielleicht wieder nen Extrapunkt ;) Also ich hab mal versucht an Hand deines Ansatzes die If-Schleife zu füllen, meiner Ansicht nach schreibt er immer wenn Modulo 0 ist die Grenze auf solang bis grenze 0 ist
Nene, das war nix. Überleg Dir einfach mal anhand meines (oder Deines) Beispiels, wie die Sache abläuft. Dann wird Dir auch klar, wie man die Anzahl der Summen suchen lassen kann. Der Algorithmus tut nichts anderes als stur durchzuzählen. Dabei zählt er die Summe jedesmal auf 0 runter.

count() sieht in etwa so aus:

if summe == 0 => string ausgeben, 1 zurückgeben
else if summe >= grenze => aktuelle grenze notieren, von summe abziehen und count nochmal für den rest und alle niedrigeren grenzen aufrufen. ergenisse zusammenzählen und zurückgeben
else => grenze ist größer als summe, also count nochmal mit der nächstkleineren grenze aufrufen.

Ich hab bloss no net verstandne für was du den String übergibst
Durch die Rekursion werden die einzelnen Möglichkeiten nicht der Reihe nach zusammengesetzt. Deshalb funktioniert die direkte Ausgabe nicht bzw. liefert ein Durcheinander.
 
  • Microsoft Visual C# 2005 Beitrag #53
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
Ok, ich versuch mich nochmal, aber warum 1 zurückgeben? beim if
 
  • Microsoft Visual C# 2005 Beitrag #54
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Hexer1985 schrieb:
Ok, ich versuch mich nochmal, aber warum 1 zurückgeben? beim if
count() ruft sich ja immer selbst auf. Irgendwann muß sie auch ein Ergebnis zurückliefern ;-)
Das Prinzip ist ja, daß sich die Funktion immer wieder selbst aufruft, solange noch eine Restsumme bzw. noch eine Möglichkeit da ist. Erst wenn die 0 ist, habe ich eine gefunden. Deshalb gebe ich dann eine 1 zurück. Die einsen der einzelnen Möglichkeiten werden zusammengezählt und ergeben dann das Endergebnis.
 
  • Microsoft Visual C# 2005 Beitrag #55
mezzo mix

mezzo mix

Bekanntes Mitglied
Dabei seit
24.12.2000
Beiträge
1.793
Reaktionspunkte
1
Ort
Entenhausen
Hallo,
hab mir jetzt nicht das ganze Thema durchgelesen, jedoch programmierst Du am Anfang des Themas ziemlich an der Aufgabe vorbei. Du sollst ja nicht die Teiler von 2 Zahlen suchen.
Hexer1985 schrieb:
Für jede ganze Zahl untersuchen wir jetzt alle kleineren ganzen Zahlen bis zur 1 einschließlich und machen jedes Mal einen Strich, wenn eine Zahl mit n keinen Teiler gemeinsam hat außer der 1.
Dazu suchst Du den größten gemeinsamen Teiler (ggT) aller Zahlen von n und n-1, n-2,...,1, und machst immer einen Strich wenn 1 als ggT rauskommt. Das machst Du am besten mit dem Algorithmus von Euklid. Ist in ~ 4 Zeilen zu programmieren.

Sollte sich das auf den 3 Seiten schon geklärt haben, bitte meinen Beitrag ignorieren...

Grüße mm
 
  • Microsoft Visual C# 2005 Beitrag #56
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
if (summe == 0)
{
Console.Write(ausgabe);
return 1;
}

else if (summe >= grenze)
{
note = grenze;
erg = summe - note;
return anz_summen(ausgabe, summe, grenze -1);
summe += erg;
return anz_summe(summe);
}

else
{
return anz_summen(ausgabe, summe, grenze - 1);
}
 
  • Microsoft Visual C# 2005 Beitrag #57
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
using System;

class App
{
static int anz_summen(string ausgabe, int summe, int grenze)
{
if (summe == 0)
{
Console.Write(ausgabe);
return 1;
}

else if (summe >= grenze)
{
int note = grenze;
int erg = summe - note;
summe += erg;
return anz_summen(ausgabe, summe, grenze -1);

}

else
{
return anz_summen(ausgabe, summe, grenze - 1);
}
}


static void Main()
{
int summe = Convert.ToInt32(Console.Read());
int grenze = summe - 1;

int erg = anz_summen("", summe, grenze);

Console.WriteLine("Anzahl: " + erg);
}
}

Ich bekomm den Fehler:
An unhandled exception of type 'System.StackOverflowException' occurred in Project1.exe

Und grau unterlegt ist der Teil in der else-Schleife! Wie kann ich das korrigieren? Stimmts sonst so weit? Danke schon mal im Vorraus, kann leider grad net so oft posten, weil Prüfungszeit ist!
 
  • Microsoft Visual C# 2005 Beitrag #58
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
Deine Summe wird auch immer größer, kann also nie 0 werden. Damit schlägt die Abbruchbedingung fehl und die Funktion ruft sich immer wieder auf. Das geht solange, bis der Speicher alle ist (der Stack => StackOverlow).
Außerdem wirst Du nie eine Ausgabe bekommen, da Du die Variable ausgabe nie veränderst.

Du solltest nochmal versuchen, den Algorithmus auf Papier aufzuschreiben und ihn zu verstehen. Also einfach anhand eines einfachen Beispieles versuchen, das Problem zu lösen.
 
  • Microsoft Visual C# 2005 Beitrag #59
H

Hexer1985

Bekanntes Mitglied
Dabei seit
07.02.2006
Beiträge
146
Reaktionspunkte
0
Ort
Stuttgart / Karlsruhe
wo/wie zähl ich denn dann die ergebnisse zusammen? Muss ich da ne andere Variable nutzen? Ich mach dann als Rückgabe ausgabe und übergeb den Wert? Ich bin ehrlich verzweifelt ich dacht so langsam hab ichs kapiert aber vielleicht sollt ich des Studium doch aufgeben...
 
  • Microsoft Visual C# 2005 Beitrag #60
U

UnimatrixZero

Bekanntes Mitglied
Dabei seit
27.06.2001
Beiträge
645
Reaktionspunkte
0
In Deinem Code zählst Du die Ergebnisse auch nicht zusammen ;-)

Also, hier mal die Lösung:
Code:
        static int count(string ausgabe, int summe, int grenze)
        {
            if (summe == 0)
            {
                // Wir haben eine Lösung gefunden
                Console.WriteLine(ausgabe);        // ausgeben
                return 1;                        // und zählen
            }
            else if (summe >= grenze)
            {
                // grenze paßt in summe
                // -> alle Möglichkeiten [1..grenze] durchprobieren und zusammenzählen
                int anz_summen = 0;

                for (int i = grenze; i > 0; i--)
                    anz_summen += count(ausgabe + i + " ", summe - i, i);

                return anz_summen;
            }
            else
            {
                // grenze ist zu groß
                // -> nächstkleinere Grenze probieren
                return count(ausgabe, summe, grenze - 1);
            }
        }

Um zu kapieren, wie das funktioniert, nimm ein Blatt Papier und geh das Programm Zeile für Zeile mit einem einfachen Beispiel (z.B. 3) durch. Schreib Dir für jeden Durchlauf den aktuellen Stack mit den Parametervariablen und den Rückgabewert auf.

Zum Verständnis, wie eine Rekursion funktioniert:
http://de.wikipedia.org/wiki/Rekursion
http://de.wikipedia.org/wiki/Rekursive_Programmierung
 
Thema:

Microsoft Visual C# 2005

ANGEBOTE & SPONSOREN

https://www.mofapower.de/

Statistik des Forums

Themen
213.181
Beiträge
1.579.175
Mitglieder
55.880
Neuestes Mitglied
Hahn
Oben