// author: klaffenboeck patrick // matr.-nr: 0125335 // bsp.-nr: 4033 // datei: ReNe.java (REsistorNEtwork) // beschreibung: diese klasse stellt die methoden syntaxCheck() und // - " - : solve() zur verfuegung, die den gesamtwiderstand // - " - : eines widerstandsnetzwerke berechnen koennen. // for better readability try "sed '/ \/\//d' ...." ;-) package Wider; public class ReNe { /* * geprueft wird: - ob fuer jede oeffnende klammer eine * schlieszende da ist (und umgekehrt) * - ob zwei operatoren hintereinander stehen * - ob ungueltige zeichen im string sind * - mehr als 15 widerstaende angegeben wurden * (eprog einschraenkung) * - ein operator direkt vor einer schlieszenden * klammer oder ganz am ende des ausdruck steht */ public static void syntaxCheck( String input, boolean eprog ) throws ReNeX { int i; int currentChar; int brackets = 0; int opCount = 0; boolean lastWasOperator = false; for (i = 0; i < input.length(); i++) { currentChar = input.charAt(i); switch (currentChar) { case '(': brackets++; lastWasOperator = false; break; case ')': brackets--; if (brackets < 0) throw new ReNeX(ReNeX.MISS_LBR, i); if (lastWasOperator) throw new ReNeX(ReNeX.INV_POS, i - 1); lastWasOperator = false; break; case '+': case '/': if (lastWasOperator) throw new ReNeX(ReNeX.TWO_OPS, i); if ((eprog) & (++opCount >= 15)) throw new ReNeX(ReNeX.EPROG, i); lastWasOperator = true; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': lastWasOperator = false; break; // andere zeichen sind nicht erlaubt, daher ... default: throw new ReNeX(ReNeX.INV_CHAR, i); } } // wenn eine klammer nicht wieder geschlossen wurde, dann ... if (brackets != 0) throw new ReNeX(ReNeX.MISS_RBR, input.lastIndexOf("(")); // ganz am ende darf natuerlich kein operator stehen if (lastWasOperator) throw new ReNeX(ReNeX.INV_POS, i - 1); } // end void syntaxCheck( String, boolean ) /* * zerteilt den string so lange und ruft sich damit wieder * selbst auf, bis nur noch zahlenwerte umzuwandeln sind. */ public static double solve( String input ) throws ReNeX { int pos; pos = find(input, '+'); if (pos > 0) { // serielle und parallele widerstaende muessen durch klammern gruppiert sein. if (find(input, '/') > 0) throw new ReNeX(ReNeX.MIX_OP, find(input, '/')); // alles vor und nach dem plus aufloesen und zusammenzaehlen return solve(before(input, pos)) + solve(after(input, pos)); } pos = find(input, '/'); if (pos > 0) { // alles vor dem slash aufloesen und den kehrwert bilden double foo = 1 / solve(before(input, pos)); // alles nach dem slash aufloesen und den kehrwert bilden double bar = 1 / solve(after(input, pos)); // die beiden zusammenzaehlen und davon wieder den kehrwert bilden return 1 / (foo + bar); } // wenn keine operatoren gefunden wurden, ist entweder der ganze // ausdruck in einer klammer ... if (input.startsWith("(")) return solve(input.substring(1, input.length() - 1)); // ... oder es ist nur noch eine zahl int ret = 0; // jeder eingelesene widerstand muss ein positiver int sein try { ret = Integer.parseInt(input); if (ret < 1) throw new ReNeX(ReNeX.NON_POS, 0); } catch (Exception e) { throw new ReNeX(input); } return ret; } // end int solve( String ) /* * liefert die position des ersten auftretens des angegebenen * zeichens. findet keine zeichen innerhalb von klammern. */ private static int find( String haystack, char needle ) throws ReNeX { int i; int brackets = 0; // hat keinen sinn etwas anderes als '+' oder '/' zu suchen if ((needle != '+') & (needle != '/')) throw new ReNeX(ReNeX.FIND, 0); for (i = 0; i < haystack.length(); i++) { if (haystack.charAt(i) == '(') brackets++; else if (haystack.charAt(i) == ')') brackets--; // nur wenn KEINE klammern offen sind, kann das zeichen gefunden werden else if ((brackets == 0) & (haystack.charAt(i) == needle)) return i; } // nichts gefunden return 0; } // end int find( String, char ) /* * liefert den substring VOR dem ersten auftreten des * angegebenen zeichens. */ private static String before( String input, int pos ) throws ReNeX { return input.substring(0, pos); } // end String before( String, char ) /* * liefert den substring NACH dem ersten auftreten des * angegebenen zeichens. */ private static String after( String input, int pos ) throws ReNeX { return input.substring(pos + 1, input.length()); } // end String after( String, char ) } // end class ReNe