Autor Beitrag
luckyman266
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 15.05.15 12:14 
Moin Moin,

ich habe folgendes Problem, ich muss ein Programm schreiben was mir nach eingabe eines geklammerten Ausdruckes die korrektheit der Klammerung überprüft. Das ganze mache ich mit einem Stack. Soweit so gut, ich habe das ganze einfach mal runtergeschrieben aber habe leider ein Problem zum Schluß:

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:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
class Program
    {

                 public static void main(String[] args) {
        
//        Konsoleneingabe vorbereiten
//        (die Tastatureingabe wird gelesen und in gepufferter Form gesichert)
        int laenge;
        string str;
       
        Console.WriteLine("Bitte geben Sie einen Klammerausdruck ein:");
               str = Console.ReadLine();
                     
            laenge = str.Length;
            if (laenge == 0)
            {
                Console.WriteLine("Sie haben keine Eingabe getätigt!" + "\n");
                Console.ReadKey();
            }
            if ((laenge % 2) != 0){
            Console.WriteLine("Zeichenkette ist falsch!" + "\n");
            Console.ReadKey();
             }
        
            }
        
   
        static void check(String str)
        {
            
            char[] c = str.ToCharArray();
            Stack myStack = new Stack();
            for(int i = 0; i < c.Length; i++){
                //        Die öffnenden Klammern überprüfen und ggf. in den Stack schreiben                
                if (c[i] == '('){
                    myStack.Push('(');
                    }else
                if (c[i] == '[') {
                    myStack.Push('[');
                    }else
                if (c[i] == '{'){
                    myStack.Push('{');
                    }else
                    //        Hier die schliessenden Klammern betrachten

//        Klammer ")"                                    
                if (c[i] == ')'){
                    
//        Überprüfung wenn leer, dann Abbruch
                        if (myStack.Contains(0) == true){
                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();
                            }
                                            
//        Wenn nicht zugehörige Klammer, dann Abbruch
                        if(myStack.Pop != '('){
                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();   
                            }                
                }else
                
//        Klammer "]"                                        
                        
                if (c[i] == ']'){
                                            
//        Überprüfung wenn leer, dann Abbruch                                            
                        if (myStack.Contains(0) == true){
                            Console.WriteLine("Zeichenkette ist falsch");
                            Console.ReadKey();
                            }
                        
//        Wenn nicht zugehörige Klammer dann abbruch                                                                                             
                        if(myStack.Pop != '['){
                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();   
                            }
                }else                            
                
//        Klammer "}"                                                
                                    
                if (c[i] == '}'){
                                            
//        Überprüfung wenn leer, dann Abbruch                                                
                        if (myStack.Contains(0)== true){
                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();
                            }                        
                        
//        Wenn nicht zugehörige Klammer, dann Abbruch                                                                                                    
                        if (myStack.Pop() !='{')    {
                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();    
                            }
                }else
                {
                    Console.WriteLine("Zeichenkette ist unzulässig!");    
                    Console.ReadKey();
                }
            }
//        Alle Zeichen abgearbeitet, keine Fehler, also korrekt          
            Console.WriteLine("Zeichenkette ist korrekt!");
        } 
       
            
    }
}


Als Fehler werden mir die 3 myStack.Pop() !='{') Bereiche rausgeworfen. Ich komme leider einfach nicht auf die Lösung des Problems
oder habe ich vorher schon einen Fehler begangen ?

Könnte mir da jemand einen Tipp oder denkanstoß geben ? Das wäre super
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 15.05.15 12:49 
Hallo und :welcome:

du verwendest die nicht-generische Variante des Stacks und diese gibt ein object zurück, so daß du die Rückgabe noch casten mußt.
Einfacher wäre es, wenn du einfach den generischen Stack<T> benutzt:
ausblenden C#-Quelltext
1:
Stack<char> myStack = new Stack<char>();					

Für diesen Beitrag haben gedankt: luckyman266
luckyman266 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 15.05.15 13:41 
Super! Vielen dank, das hat schonmal funktioniert :)

Meine 3 Problemzonen haben sich verabschiedet und es startet...juhu :)

Aber ich habe irgendwie, irgendwo noch einen Denkfehler.

Wenn ich nun einen Klammerausdruck ala "((((" eingebe gibt mir das Prog richtig zurück das es Falsch ist :D .
Aber wenn ich nun eingebe ((a+b)) zeigt er mir ebefalls Falsch an.

Wenn ich einen ausdruck "(())" eingebe wirft er mir nicht meine letzte Zeile
ausblenden C#-Quelltext
1:
2:
       
            Console.WriteLine("Zeichenkette ist korrekt!");

aus

Ich habe doch aber mit
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (c[i] == '('){
                    myStack.Push('(');
                    }else
                if (c[i] == '[') {
                    myStack.Push('[');
                    }else
                if (c[i] == '{'){
                    myStack.Push('{');

mitgeteilt das ich nur die angegeben Zeichen beachten will oder sehe ich das falsch ?

Und dann macht mir folgendes noch Bauchschmerzen

ausblenden C#-Quelltext
1:
if (myStack.Contains('*') == true)					

Ich weiß das es bei Java "myStack.isEmpty" gibt jedoch bei C# nicht und mit Contains kann ich doch bestimmen ob etwas im Stack liegt ?!So habe ich das zumindestens aus der MSDN Doku verstanden.

Ich hoffe meine Fragen sind nicht zu doof, ich stehe noch ganz am Anfang und versuche die Zusammenhänge zu begreifen.

Vielen Dank
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 15.05.15 13:58 
Hallo,

du hast Contains falsch verstanden - damit wird überprüft, ob sich das übergebene Element im Stack befindet.
Prüfe einfach die Anzahl
ausblenden C#-Quelltext
1:
if (myStack.Count == 0)					

Edit: Rufst du überhaupt die check-Methode aus der Main auf (im obigen Code jedenfalls noch nicht)? Du solltest auch lernen den Debugger zu benutzen, um Programmabläufe nachzuvollziehen (s. z.B. Fehlersuche mit Visual Studio [2012]).

PS: Du solltest deine Schleife im Fehlerfall noch beenden (mittels break)
Noch besser ist es, wenn die check-Methode (btw: Methodennamen sollten in C# mit einem Großbuchstaben anfangen, also Check) einfach bool als Rückgabewert hätte (und dann true oder false zurückgibt) und dann die aufrufende Methode die Konsolenausgabe tätigt (dann hättest du gleich die sinnvolle Trennung von Logik und UI).
luckyman266 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 15.05.15 16:36 
Hi,

ok count verstanden, vielen Danke !

hmmm ja ich komme gar nicht aus der Main Methode raus.

Debugger hab ich eben mal gestartet und da hört die Ausführung dann nach der Main auch auf.

Ich welz heute abend nochmal mein Buch und schaue das ich das hinbekomme.
luckyman266 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Do 28.05.15 16:53 
Hi, so hatte etwas viel zu tun die letzten Tage konnte mich jetzt erst wieder dem Thema widmen.

Ich habe nun einen try catch eingebaut und in der Main die Methode aufgerufen (denke ich)! Aber ich bekomme das einfach nicht zum laufen, ich dreh durch.... :shock:

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:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace KlammerPrüfer
{
    class Program
    {
       static int laenge;
        

        public static void Check(String str)
        {
            laenge = str.Length;

            if (laenge == 0)
            {
                Console.WriteLine(" Keine Eingabe erfolgt");
                Console.ReadKey();
            }
            if ((laenge % 2) != 0)
            {
                Console.WriteLine("Die Zeichenkette ist so nicht korrekt eingeben");
                Console.ReadKey();

            }
            char[] c = str.ToCharArray();
            Stack<char> myStack = new Stack<char>();
            for (int i = 0; i < c.Length; i++)
                if (c[i] == '(')
                {
                    myStack.Push('(');
                }
                else
                    if (c[i] == '[')
                    {
                        myStack.Push('[');
                    }
                    else
                        if (c[i] == '{')
                        {
                            myStack.Push('{');
                        }

                    else
                            //        Hier die schliessenden Klammern betrachten

                            //        Klammer ")"                                    
                         if (c[i] == ')')
                         {
                                //        Überprüfung wenn leer, dann Abbruch
                         if (myStack.Count == 0)
                             Console.WriteLine("Zeichenkette ist falsch!");
                             Console.ReadKey();
                         }
              

            //        Wenn nicht zugehörige Klammer, dann Abbruch
                         if (myStack.Pop() != '(')
                         {

                            Console.WriteLine("Zeichenkette ist falsch!");
                            Console.ReadKey();
                         }
        else
            //        Klammer "]"                                        

                        if (c[i] == ']')
                       {

                //        Überprüfung wenn leer, dann Abbruch                                            
                if (myStack.Count == 0)
                             Console.WriteLine("Zeichenkette ist falsch");
                             Console.ReadKey();
       
                       }

                //        Wenn nicht zugehörige Klammer, dann Abbruch                                                                                            
                if (myStack.Pop() != '[')
                {
                    Console.WriteLine("Zeichenkette ist falsch!");
                    Console.ReadKey();

                }

             else

                    //        Klammer "}"                                                

                    if (c[i] == '}')
                    {

                    //        Überprüfung wenn leer, dann Abbruch                                                
                    if (myStack.Count == 0)
                        Console.WriteLine("Zeichenkette ist falsch!");
                        Console.ReadKey();


                    }

                    //        Wenn nicht zugehörige Klammer, dann Abbruch                                                                                                    
                    if (myStack.Pop() != '{')
                    {

                        Console.WriteLine("Zeichenkette ist falsch!");
                        Console.ReadKey();


                    }
                    else
                    {

                        //        Alle Zeichen abgearbeitet, keine Fehler, also korrekt   
                        Console.WriteLine("Zeichenkette ist korrekt!");
                    }
        }
    }
}

        public static void Main(string[] args)
          {
                            
            Console.WriteLine("Bitte geben Sie einen Klammerausdruck ein:");
            str = Console.ReadLine ();
            try {
            
//        der gelesene Klammerausdruck wird an die Methode check uebergeben
//        wo er auf Korrektheit ueberprueft wird
            
//        Methode check aufrufen, String übergeben            
            Check(Console.ReadLine());
       
            catch (IOException ex) {
            Console.WriteLine(ex.StackTrace);
            Console.WriteLine("Ein unbekannter Fehler ist aufgetreten.");}
}
}


Magst du vielleicht noch mal drüber schauen ?
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 28.05.15 17:34 
Dem Code selber fehlen wohl einige geschweifte Klammern ;) neben diversen anderen Fehlern die ihn schon gar nicht kompilieren lassen. Das solltest du in Ordnung bringen so ist es schwer sich den Code überhaupt anzusehen und dem Sinn irgendwie zu folgen. Wenn das zumindest kompiliert oder du gezielt ein Problem ansprechen kannst an dem du hängst um es zum kompilieren zu bringen helfen wir gerne weiter. Aber deinen Codemüllberg solltest du erstmal selbst aufräumen.