skip to main content

kiesler.at

Spaziergang durch einen Einheitenberechner
updated by rck, 2004-10-10

Der Ernstfall ist eingetreten. EPROG. Drei Beispiele, eines schlimmer als das andere. Zu allem Überfluss sind die mitgelieferten "Unterstützungsprogramme" mehr ein Klotz am Bein als sonst was.

Wie geht's weiter, wenn kein Stein und kein Seil verfügbar ist, das einen den Weg in die Donau begleiten könnte?

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13

Einhexpr.java

Hier noch der gesamte Sourcecode von Einhexpr.java. Die relevanten Stellen habe ich bereits kommentiert. Sollte es zu anderen Stellen Fragen geben oder generell irgendwelche Bemerkungen, bitte im Kommentarbereich schreiben.

Ich freue mich über jeden Kommentar!

1 import eprog.*;
2 
3 import java.io.*;
4 import java.util.*;
5 
6 class Einhexpr {
7 
8 
9         private final static String ERROR="FALSCHE EINGABE";
10         private static ArrayList ausdruck;
11 
12 
13         // ---------------- HILFSFUNKTIONEN ------------------------------------------------
14         //
15 
16 
17         public static final boolean debugging=false;
18 
19         public static void debug(String s) throws Exception {
20                 if(debugging)
21                         System.out.println(s);
22         }
23         
24         public static void reset() throws Exception {
25                 ausdruck=new ArrayList();
26         }
27 
28 
29         public static String ArrayListRangeToString(ArrayList al, int von, int bis)
30                 throws Exception {
31 
32                 if(von==bis)
33                         return("[]");
34 
35                 if((bis-von)==1)
36                         return("["+al.get(von)+"]");
37 
38 
39                 String s="[";
40 
41                 for(int i=von; i
42                         s=s+al.get(i)+",";
43 
44                 s=s+al.get(bis);
45 
46                 return(s+"]");
47         }
48 
49 
50         // ----------------- HAUPTFUNKTIONEN -----------------------------------------------
51         //
52         public static void tokenize(String s)
53                 throws Exception {
54 
55                 // siehe: http://java.sun.com/j2se/1.3/docs/
56                 //               api/java/util/StringTokenizer.html
57                 
58                 StringTokenizer st=new StringTokenizer(
59                                 s, "()+-*/", true);
60 
61                 int Klammerebene=0;
62                 String token;
63 
64                 while(st.hasMoreTokens()) {
65                         token=st.nextToken();
66 
67 
68                         // Klammern sind was ganz spezielles...
69 
70                         if(token.equals("("))
71                                 Klammerebene++;
72                         else
73                         if(token.equals(")")) {
74                                 Klammerebene--;
75                                 if(Klammerebene<0)
76                                         throw(new Exception("Zuviele schließende Klammern!"));
77                         }
78 
79                         ausdruck.add(token);
80                         
81                 }
82 
83 
84                 if(Klammerebene!=0)
85                         throw(new Exception("Zuviele öffnende Klammern!"));
86 
87                 return;
88         }
89 
90 
91         public static void verify() throws Exception {
92                 for(int i=0; i
93                         if(     !Berechner.isValidWert((String)ausdruck.get(i)) &&
94                                 !Berechner.isValidOperator((String)ausdruck.get(i)) )
95 
96                                 throw(new Exception("Token "+i+" ('"+
97                                         (String)(ausdruck.get(i))+"') ist weder "+
98                                         "Operator noch Wert."));
99         }
100 
101 
102         public static boolean isGeklammert() throws Exception {
103                 // Annahme: Korrekt geklammert. Sollte ja mit tokenize
104                 //   gecheckt worden sein!
105 
106                 return(ausdruck.contains(new String("(")));
107         }
108 
109 
110         public static int posMulDiv(int von, int bis) throws Exception {
111                 for(int i=von; i
112                         if(ausdruck.get(i).equals("*") ||
113                            ausdruck.get(i).equals("/"))
114                                 return(i);
115 
116                 return(-1);
117         }
118 
119 
120         public static int posAddSub(int von, int bis) throws Exception {
121                 for(int i=von; i
122                         if(ausdruck.get(i).equals("+") ||
123                            ausdruck.get(i).equals("-"))
124                                 return(i);
125 
126                 return(-1);
127         }
128 
129 
130         // berechne(int i)
131         // ..................................................................
132         // ersetzt im Ausdrucksarray eine Stelle der Form
133         //    ...ausdruck[i-1]=A, ausdruck[i]=operator, ausdruck[i+1]=B
134         // durch
135         //    ...ausdruck[i]=A operator B
136         //
137         // --> A und B werden ausdruck gelöscht, ausdruck verliert somit
138         //     zwei Elemente. Übrig bleibt das Ergebnis, von A und B, ver-
139         //     knüpft mit dem operator
140         //
141         // das Ergebnis wird ZUSÄTZLICH als String zurückgegeben, kann aber
142         //     genausogut ignoriert werden.
143         //
144         public static String berechne(int i) throws Exception {
145 
146                 debug("berechne(): vor Berechnung");
147                 String resultat=Berechner.berechne(     (String)ausdruck.get(i-1),
148                                                         (String)ausdruck.get(i),
149                                                         (String)ausdruck.get(i+1));
150 
151                 debug("berechne(): nach Berechnung");
152                 ausdruck.set(i, resultat);
153 
154                 debug("berechne(): entferne Operatoren");
155                 ausdruck.remove(i+1);
156                 ausdruck.remove(i-1);
157 
158                 debug("berechne(): liefere "+resultat);
159                 return(resultat);
160         }
161 
162 
163         public static String berechne(int von, int bis) throws Exception {
164 
165                 int i;
166 
167                 while( (i=posMulDiv(von,bis)) != -1) {
168                         berechne(i);
169                         bis-=2;
170                 }
171 
172                 while( (i=posAddSub(von,bis)) != -1) {
173                         berechne(i);
174                         bis-=2;
175                 }
176 
177                 if(bis-von>1)
178                         throw(new Exception("beim Berechnen von "+von+
179                                 " bis "+bis+" ist was übrig geblieben: "+
180                                 ArrayListRangeToString(ausdruck,von,bis)));
181 
182                 return((String)(ausdruck.get(von)));
183         }
184 
185 
186         public static int posInnersteKlammerAuf() throws Exception {
187                 int Klammerebene=-1, MaxKlammerebene=-1, MaxI=-1;
188 
189                 for(int i=0; i
190                         if(ausdruck.get(i).equals("(")) {
191                                 Klammerebene++;
192 
193                                 if(Klammerebene > MaxKlammerebene) {
194                                         MaxKlammerebene=Klammerebene;
195                                         MaxI=i;
196                                 }
197                         } else
198                         if(ausdruck.get(i).equals(")"))
199                                 Klammerebene--;
200 
201                 if(MaxI==-1)
202                         throw(new Exception("Es gibt keine innerste Klammerebene!"));
203 
204                 return(MaxI);
205         }
206 
207 
208         public static int posInnersteKlammerZu(int posKlammerAuf) throws Exception {
209 
210                 for(int i=posKlammerAuf; i
211                         if(((String)ausdruck.get(i)).equals(")"))
212                                 return(i);
213 
214                 throw(new Exception("Es gibt keine anschließende schließende Klammer!"));
215 
216         }
217 
218 
219         public static String berechneInnersteKlammer() throws Exception {
220 
221                 int auf=posInnersteKlammerAuf();
222                 int zu=posInnersteKlammerZu(auf);
223 
224 
225                 if(zu-auf<=1)
226                         throw(new Exception("() ist ungültig!"));
227                 
228 
229                 berechne(auf+1,zu-1);
230 
231 
232                 // Klammern entfernen
233 
234                 ausdruck.remove(auf+2);
235                 ausdruck.remove(auf);
236 
237                 return((String)(ausdruck.get(auf)));
238         }
239 
240 
241         public static String beautify(String s) throws Exception {
242                 return( Berechner.normalisiereWert(
243                                 Berechner.getWertNumeric(s))+
244                         " "+Berechner.getEinheit(s));
245         }
246 
247 
248         public static String berechne(String s) throws Exception {
249 
250                 // 1. Platz für den zerlegten Ausdruck reservieren
251                 //
252                 reset();
253 
254                 // 2. Ausdruck in mundgerechte Stücke zerteilen
255                 //    (dabei gleich auf die Klammern schauen)
256                 //    
257                 tokenize(s);
258 
259 
260                 // 3. Happen genauer analysieren. Alles syntaktisch
261                 //    korrekt ?
262                 //
263                 verify();
264 
265 
266                 // 4. zuerst alle Klammern auflösen (innerste zuerst)...
267 
268                 while(isGeklammert())
269                         berechneInnersteKlammer();
270 
271 
272                 // 5. ...und dann den gesamten verbleibenden Ausdruck
273                 //    gab's bis jetzt keine Exception, können wir das
274                 //    Ergebnis gleich ausgeben.
275 
276                 s=berechne(0, ausdruck.size());
277 
278 
279                 // 6. nachdem die Eingabe OHNE Leerzeichen, die Ausgabe
280                 //    aber mit ist, das ganze noch anpassen & gleich
281                 //    ausgeben.
282                 //
283                 return(beautify(s));
284         }
285 
286 
287         public static void main(String[] args) {
288                 // EprogIO.readln gibt's leider keins,
289                 // readWord() funktioniert nicht so wirklich...
290                 //
291                 InputStreamReader ins=new InputStreamReader(System.in);
292                 BufferedReader reader=new BufferedReader(ins);
293 
294                 try {
295 
296                         EprogIO.println(berechne(reader.readLine()));
297 
298                 } catch(Exception e) {
299                         EprogIO.println(ERROR);
300                 }
301         }
302 }

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13



RSSComments - Make a comment
The comments are owned by the poster. We are not responsible for its content.
RSSAll Articles
2008, 2007, 2006, 2005, 2004