Autor |
Beitrag |
Günes
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 24.04.08 09:45
Habe eine Abgabe in der Schule zu machen, komme aber nicht weiter mit meiner Klasse.
Habe bis jetzt folgende Klasse geschrieben:
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:
| class CCalculate { public string InputData=""; public string Result=""; public bool Calculate() {
InputData = InputData.Replace("+", " + "); InputData = InputData.Replace("-", " - "); InputData = InputData.Replace("*", " * "); InputData = InputData.Replace("/", " / "); InputData = InputData.Replace("%", " % ");
char[] cTrennzeichen = { ' ' }; string[] sTerm; int iOperand1 = 0; int iOperand2 = 0; string sOperation = ""; sTerm=InputData.Split(cTrennzeichen,StringSplitOptions.RemoveEm ptyEntries); int.TryParse(sTerm[0],out iOperand1); int.TryParse(sTerm[2],out iOperand2); sOperation=sTerm[1]; switch (sOperation) { case "+": Result= Convert.ToString(iOperand1 + iOperand2); break; case "-": Result= Convert.ToString(iOperand1 – iOperand2); break; case "*": Result= Convert.ToString(iOperand1 * iOperand2); break; case "/": Result= Convert.ToString(iOperand1 / iOperand2); break; case "%": Result= Convert.ToString(iOperand1 % iOperand2); break; } return true; } } |
und muss diese klasse noch erweitern um:
Aufgabe: | Den Datentyp ändern (int zu double):
Grundsätzlich ist der Wechsel des Datentyps kein besonders großes Problem. Bedenken Sie dabei jedoch folgendes:
Jeder eingegebene Operand muss als double erfasst werden, d.h Eingaben wie z.B. 4 sind durch 4,0 zu ersetzen. Und damit ist auch gleich unser zweites Problem auf dem Tisch: das Komma(,) – Punkte (.) aus der Eingabe sind entsprechend durch das Komma (,) zu ersetzen
(vgl. Drehbuch4).
Der vermutlich anspruchsvollste Aufgabe in diesem Snapshot ist die Entwicklung einer Methode, die beliebig viele Operanden und Operatoren verarbeiten zu können. Dazu ein paar Hinweise für Ihre Analyse: |
und
das punkt vor strich gerechnet wird
Bitte um Hilfe.. muss das fertige Programm am Mittwoch haben!
mfg Günes
Moderiert von Christian S.: Color- durch C#-Tags ersetzt
Moderiert von Christian S.: Überflüssige Zeilenumbrüche entfernt, Quote-Tags eingefügtModeriert von Christian S.: Topic aus Algorithmen, Optimierung und Assembler verschoben am Do 24.04.2008 um 10:29
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Do 24.04.08 10:31
Hallo und  !
Du hast irgendwie vergessen, Deine Frage zu stellen.  Oder zu sagen, wo Du nicht weiter kommst.
Denn, um das direkt mal klar zu stellen, wir werden Dir gerne dabei helfen, aber Deine Hausaufgaben machen wir nicht für Dich.
Grüße
Christian
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
Günes 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 24.04.08 10:40
na ich will ja nicht das ihr die hausübung macht =)
ja ich weiß nicht wie ich das mit den beliebigen operanden machen kann..
da komm ich nicht weiter
wir haben uns überlegt das wir so viele operanden brauchen wie iLänge / 2 , weil wir ja immer zahl, vorzeichen , zahl ,.. haben; also müsste es ja immer 2 weiter sein
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Do 24.04.08 15:10
... und wegen "Punkt vor Strich" wird es noch deutlich komplizierter. Lösungsansätze könnten über die Forumssuche bzw. Google über "Mathematik Parser" o.ä. gefunden werden. (Ich habe es selbst noch nie gemacht, aber mehrere Diskussionen darüber gelesen; das Folgende kommt aus meiner Erinnerung.)
Der erste Schritt bleibt immer String.Split(), das geht kaum anders (siehe unten). Als zweiten Schritt bietet es sich an, immer eine Zahl und einen Operator gemeinsam zu behandeln und in einer Liste zwischenzuspeichern; das letzte Element dieser Liste enthält den Operator "Ende". Jede Teilrechnung wird so ausgeführt: In dem Paar (Zahl1 Op1) (Zahl2 Op2) wird Zahl2 ersetzt durch (Zahl1 Op1 Zahl2); das Element (Zahl1 Op1) ist damit erledigt und wird gelöscht.
Dabei sind in einer ersten Schleife die Punktrechnungen zu erledigen, also */%. In einer zweiten Schleife folgen die Strichrechnungen. (Dieses Verfahren könnte vermutlich soweit ergänzt werden, dass auch Klammern möglich wären.)
Der wichtigste Schritt ist also eine Klasse MathOperator, dazu kommt List<MathOperator>.
Den Hinweis für Dezimalpunkte würde ich ignorieren: Wenn ein String in einen double-Wert konvertiert wird, ist es ein double - unabhängig von der String-Darstellung. Auch eine ganze Zahl in der String-Form "4" kann problemlos in den double 4.0 konvertiert werden. Relevant ist der Hinweis natürlich dafür, wie das Ergebnis angezeigt werden soll.
Ergänzende Hinweise:
String.Split() kann auch anders angewendet werden, nämlich mit allen Operatoren als Trennern. Dann bekommst Du alle Zahlen "in einem Stück" und hast damit die Anzahl der Operationen, musst aber in einer weiteren Prüfung die Trenner nacheinander heraussuchen. Vielleicht wäre es deshalb sogar einfacher, den gesamten Input-String in einer Schleife manuell aufzuteilen.
Benutze möglichst nicht die Methoden der Convert-Klasse; int.TryParse ist (wie von Dir verwendet) auf jeden Fall günstiger. Gleiches gilt auch für das Ergebnis. Aber auch dann wäre es besser, das Result zunächst als double zu berechnen und erst ganz am Ende mit ToString() anzuzeigen, denn dabei kannst Du die gewünschte Formatierung vorgeben.
Gruß Jürgen
|
|
Günes 
Hält's aus hier
Beiträge: 8
|
Verfasst: Do 24.04.08 21:47
danke dir für deine antwort jürgen!
mein lehrer hatte uns eh so einen hinweis gegeben mit den operanden + vorzeichen..
also das man Zahl Vorzeichen Zahl immer in so nem pack nehmen soll.. und das ergebnis dann in die variable von der 2ten zahl zu speichern um weiter zu machen oder so..
werde es gleich mal morgen in meinem unterricht probieren!
LG Günes
|
|
Günes 
Hält's aus hier
Beiträge: 8
|
Verfasst: Fr 25.04.08 09:36
programm funktioniert tadellos!!
komme jetzt nur ned mit der punkt vor strichrechnung zurecht
bitte um hilfe
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:
| using System; using System.Collections.Generic; using System.Text;
namespace APR_111s3_V2 { class CCalculate { public string InputData = ""; public string Result = "";
public double Berechnung(double dOperand1, double dOperand2, string sOperation) { switch (sOperation) { case "+": return(dOperand1 + dOperand2); case "-": return(dOperand1 - dOperand2); case "*": return(dOperand1 * dOperand2); case "/": return(dOperand1 / dOperand2); case "%": return(dOperand1 % dOperand2);
default: return (0d);
} }
public void parse() { char[] cTrimchar = { '-', '+', '*', '/', '%' }; InputData = InputData.TrimStart(cTrimchar); InputData = InputData.Replace("+", @" + "); InputData = InputData.Replace("-", @" - "); InputData = InputData.Replace("*", @" * "); InputData = InputData.Replace("/", @" / "); InputData = InputData.Replace("%", @" % "); InputData = InputData.Replace(".", @",");
char[] cTrennzeichen = { ' ' }; string[] sTerm; double dOperand1 = 0; double dOperand2 = 0; string sOperation = ""; sTerm = InputData.Split(cTrennzeichen, StringSplitOptions.RemoveEmptyEntries); int iLaenge = sTerm.Length-1; sTerm = InputData.Split();
for (int ii = 2; ii <= iLaenge; ii += 2) {
dOperand1 = Convert.ToDouble(sTerm[ii - 2]); dOperand2 = Convert.ToDouble(sTerm[ii]); sOperation = sTerm[ii - 1];
double Ergebnis = Berechnung(dOperand1, dOperand2, sOperation); sTerm[ii] = Ergebnis.ToString(); Result = Convert.ToString(Ergebnis); }
} } } |
|
|
Th69
      

Beiträge: 4798
Erhaltene Danke: 1059
Win10
C#, C++ (VS 2017/19/22)
|
Verfasst: Fr 25.04.08 12:04
Du mußt halt erst alle Berechnungen nur für '*', '/' und '%' machen und dann im zweiten Schritt alle restlichen Operatoren ('+', '-').
Wobei du Probleme mit dem unären Minuszeichen bei deiner Methode hast, z.B. bei 2 * -3.
|
|
JüTho
      
Beiträge: 2021
Erhaltene Danke: 6
Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
|
Verfasst: Fr 25.04.08 13:02
Zitat: | programm funktioniert tadellos!! |
Naja... Dein Vorgehen gefällt mir insofern überhaupt nicht, als Du ständig mit Strings arbeitest. Es handelt sich um Zahlen; also konvertiere zuerst alle Strings in Zahlen, rechne nur mit Zahlen; erst am Ende "darf" wieder ein String entstehen.
Tut mir leid, aber bei Deinem Vorgehen kann ich nicht erkennen, welche Rechnungen bereits erledigt sind. Dieses Vorgehen ermöglicht nur, alle Rechnungen hintereinander zu erledigen, aber nicht zuerst Punkt- und dann Strichrechnungen.
Ich empfehle dringend eine eigene Klasse. Dies könnte noch ausgeweitet werden, damit nur die 5 Operationen (sowie der Ende-Vermerk) möglich sind.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| public class MathTerm { private double numeral; public double Numeral { get; set; } private string operator; public string Operator { get; set; } public MathTerm(double setNumeral, string setOperator) { numeral = setNumeral; operator = setOperator; } } |
Das eigentliche Verfahren muss dann geändert werden nach String.Split(). Zuerst werden alle Zahlen konvertiert und mit "ihrem" Operator verbunden.
C#-Quelltext 1: 2: 3: 4: 5: 6: 7:
| List<MathTerm> terms = new List<MathTerm>(sTerm.Length / 2); for(int x1 = 0; x1 < sTerm.Length; x1 += 2) { double num = 0; Double.TryParse(sTerm[x1], out num); terms.Add(new MathTerm(num, x1+2 < sTerm.Length ? sTerm[x1+1] : "Ende")); } |
Jetzt werden alle Rechnungen ausgeführt, wie ich in einem früheren Beitrag skizziert hatte - in einer ersten Schleife die Punktrechnungen, in einer zweiten Schleife die Strichrechnungen. Weil die "erledigten Rechnungen" in der Liste zu streichen sind, muss die Schleife von hinten her bearbeitet werden:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| for(int x1 = terms.Length - 1; x1 >= 0; x1--) { MathTerm term = terms[x1]; if (term.Operator == "%" || term.Operator == "*" || term.Operator == "/") { terms[x1+1].Numeral = Berechnung(term.Numeral, terms[x1+1].Numeral, term.Operator); terms.Remove(term); } } |
Am Ende der beiden Schleifen dürfte nur noch ein Element in der Liste terms übrig bleiben; und dessen Wert Numeral ist das Endergebnis.
Alternativ kann man auch zwei Schleifen verschachteln: Die äußere Schleife behandelt alle Operatoren nacheinander (zuerst */%, dann +-), die innere die Liste terms. Das spart die Unterscheidung der aktuellen Operatoren:
C#-Quelltext 1: 2: 3: 4: 5: 6:
| for (int x2 = 0; x2 < Operators.Length; x2++) { for (int x1 ... wie gehabt) { if (term.Operator == Operators[x2]) } } |
Du hast mich außerdem enttäuscht, dass Du jetzt Convert.ToDouble verwendest. Double.TryParse ist sicherer! Und die Division durch Null sollte (ebenso wie mod 0) abgefangen werden.
Gruß Jürgen
|
|
Günes 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 28.04.08 13:26
danke erstmal für eure antworten!
meine vorgehensweise in meinem bisherigen programm,
war so ausgeübt, wie der lehrer es uns erklärt hat!
in richtung punkt vor strich hat er mir das selbe gesagt wie th69!!
werde schauen was ich jetzt noch an dem programm verändere!
danke euch vorerst für eure hilfestellungen!
lg günes
|
|
derDachs
      
Beiträge: 18
|
Verfasst: Do 01.05.08 12:30
Titel: Hmm komplizierter mit Punkt vor Strich?
Hi,
Heutzutage sollte ein Taschenrechner für niemanden mehr Probleme bereiten, nun aber gleich nen Parser zu vergewohltätigen find ich ja echt n bischen übertrieben.
Der Datentyp Keller, wäre hier die supi Antwort, auch wenn du nach Post- und Präfixnotation suchst wirst du fündig.
einfaches Bsp:
3*3-6/2
"33*62/-" wäre ja Postfix
Band für Rechnung(string):
Keller für Operand:
3 gefunden schmeiß sie aufs Band
* gefunden ab in den Keller
3 gefunden scheiß sie aufs Band
- gefunden, hol das * aus dem Keller leg es aufs Band und schmeiss das Minus in den Keller
6 gefunden, ab auf´s Band
/ gefunden ab in den Keller
2 gefunden ab aufs Band
nix mehr in der Rechnung
dann hol die Operanden aus dem Keller aufs Band... voila fertig
Du must den Operanden einfach Vorangikeiten zuweisen * und / sind grösser als + und -
mit Klammern funktioniert das genauso...
Anstelle die Rechnung auf ein Band zu schreiben, kannst du auch immer gleich das Ergebnis errechnen von den
Sachen die auf dem Band wären.
Also: 3 , 3 , * gut rechne aus und merke 9
- kommt in den Keller
6 , 2 , / rechne aus und merke als 3
jetzt haste nurnoch das Minus also rechne 9-3 = 6 !!
mfG der Dachs
|
|
|