Erste Schritte Im arithm. Ausdruck Zeichen trennen?

Terry12

Aktives Mitglied
hi,

wir sollen einen arithm. Ausdruck einlesen z.B :

( ( a + b ) * ( ( c - d ) ) )

Die einzelnen Zeichen lese ich anschließend nacheinander in eine Queue ein.
Dabei ist bei mir im moment das Leerzeichen zwischen jedem Zeichen das Trennzeichen für die Wörter,
wenn jetzt aber ein Ausdruck ohne Trennzeichen (Leerzeichen) da steht, gehts nimmer...
wie könnte man es anders machen?

also operatoren sind: ( , ) , + , - , * , /

und die Identifier dazwischen können sonstige Strings sein....

im moment mach ich das mit regex :
String[] teile = line.split(" +");
 
naja das Problem ist aber dass die Identifier dazwischen nicht nur aus einem char bestehen können.
Es könnten auch Namen oder sonst was sein : "Hans" , "aa", "bb" ,"cc" usw.
 
schon klar. du überprüfst jedes zeichen, ob es ein operator ist. wenn nicht, fügst du es einem stringbuilder hinzu. jedes mal, wenn du einen operator gefunden hast, merkst du dir den string im stringbuilder (=Identifier) und leerst ihn.
 
hm das ging bisschen zu schnell 😀
operatoren adde ich in den stringbuilder und übergebe den operator wieder an die funktion, dabei leere ich ihn, ok
und was ist mit den operanden bzw identifiern?
 
ich möchte den String einfach zerhacken und nacheinander jedes "Wort" weiterreichen, z.B

a + b * (cc-ddd)

=>

a
+
b
*
(
cc
-
ddd
)

also bei den Operatoren muss getrennt werden, und solange kein operator kommt, jedes zeichen weiterlesen und als ganzes Wort weitergeben solange bis wieder ein operatorzeichen kommt...
 
Ich habe es aus eigenem Interesse so versucht, wie es nrg erklärt hat:
Java:
		String input = "a + b * (cc-ddd)";
		ArrayList<String> separated = new ArrayList<>();
		StringBuilder sb = new StringBuilder();
		
		for (char c : input.toCharArray()) {
			if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')') {
				if (sb.length() > 0)
					separated.add(sb.toString());
				separated.add(String.valueOf(c));
				sb = new StringBuilder();
			} else if (c != ' ')
				sb.append(c);
		}
		if (sb.length() > 0)
			separated.add(sb.toString());
		
		System.out.println(separated);
Da lässt sich bestimmt noch etwas verbessern, aber im Großen und Ganzen sollte es das sein, was du wolltest. 🙂
 
Aber nicht viel, ist schon ganz gut mE.

Java:
String input = "a + b * (cc-ddd)";
		List<String> separated = new ArrayList<String>();
		StringBuilder sb = new StringBuilder();
		for (char c : input.toCharArray()) {
			if (c == '+' || c == '-' || c == '*' || c == '/' || c == '('
					|| c == ')') {
				if (sb.length() > 0) {
					separated.add(sb.toString());
					sb.setLength(0);
				}
				separated.add(String.valueOf(c));
			} else {
				if (c != ' ') {
					sb.append(c);
				}
			}

		}
 
Falls das letzte Zeichen kein Operator ist, fehlt da noch ein
Code:
separated.add(...)
, oder?

Ein Test ergab, dass dem so ist. Ein

Java:
        if (sb.length() > 0) {
            separated.add(sb.toString());
        }

am Ende hilft.

Als ganzer Testcode:

Java:
package forumProblems;

import java.util.ArrayList;
import java.util.List;

public class FormulaParser {

    private List<Character> symbols;

    public FormulaParser(String input) {
        initSymbols();
        List<String> separated = splitFormula(input);
        System.out.println("Aus [" + input + "] wird " + separated);
    }

    private void initSymbols() {
        symbols = new ArrayList<Character>();
        symbols.add('+');
        symbols.add('-');
        symbols.add('*');
        symbols.add('/');
        symbols.add('(');
        symbols.add(')');
    }

    private List<String> splitFormula(String input) {
        List<String> separated = new ArrayList<String>();

        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            if (symbols.contains(c)) {
                if (sb.length() > 0) {
                    separated.add(sb.toString());
                    sb.setLength(0);
                }
                separated.add(String.valueOf(c));
            }
            else {
                if (c != ' ') {
                    sb.append(c);
                }
            }
        }
        if (sb.length() > 0) {
            separated.add(sb.toString());
        }

        return separated;
    }

    public static void main(String[] args) {
        new FormulaParser("a + b * (cc-ddd)");
        new FormulaParser("a + b * (cc-ddd) + eee");
    }

}

Ausgabe

Code:
Aus [a + b * (cc-ddd)] wird [a, +, b, *, (, cc, -, ddd, )]
Aus [a + b * (cc-ddd) + eee] wird [a, +, b, *, (, cc, -, ddd, ), +, eee]
 
Zuletzt bearbeitet:
So etwas sollte man eher nicht selbst schreiben, sondern die Java eigenen Methoden verwenden. String.split() bringt eigentlich alles mit, auch wenn regular expressions vielleicht nicht jedermanns Sache sind.

Java:
		final String SEPARATOR = "(?<=\\+)|(?=\\+)|(?<=\\*)|(?=\\*)|(?<=\\-)|(?=\\-)|(?<=\\()|(?=\\))";
		String input = "a + b * (cc-ddd) + eee".replace(" ", "");

		String[] separated = input.split(SEPARATOR);
		System.out.println(Arrays.toString(separated));

Alternativ der wahrscheinlich leichter verständliche StringTokenizer:
Java:
		final String SEPARATOR = "+-*()";
		String input = "a + b * (cc-ddd) + eee".replace(" ", "");

		StringTokenizer tokenizer = new StringTokenizer(input, SEPARATOR, true);
		while (tokenizer.hasMoreTokens())
			System.out.println(tokenizer.nextToken());
 

Neue Themen


Zurück
Oben