Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

1

12.01.2007, 10:39

Taschenrechner

der taschenrechner.. anscheinend eine der beliebtesten übungen bei cpp anfängern..

ich hab mir überlegt ebenfalls einen zu schreiben..
einer der rechnungen lösen kann wie:

(3/76 + 15/19) * [12/13 - 16/21 - (30 / 4,32)]

oder so in der art..
also.. wenn ich das schon ansehe wird mir schlecht ^^
aber naja, ich hab mir was vorgenommen.. jetzt weiß ich aber leider nicht so recht wie ich das angehn soll..

zum einen hab ich mir gedacht diese rechnung zum beispiel als string zu behandeln, um dann irgendwie zu analysieren, was steht wo.. (also die reihenfolge v. klammern, punkt vor strich).. aber ich glaub ehrlich gesagt dass das nicht so eine optimale lösung ist.. zumal ich mir vorstellen kann die reihenfolge der zu rechnenenden zahlen anhand von schleifen mit einem übergebenen string sich als recht schwierig und umständlich erweisen wird oder?

meine idee wäre zb (nur mal angenommen):

"(3 + 2) * (1 + 1)" <-- string

ich lass das in einer schleife durchgehn.. jetz kommt mal ne klammer.. ok
jetzt sieht er 'aha.. da is ne ganzzahl.. danach ein plus und noch na ganzzahl.. dann eine 2 und ne klammer. das muss ich dann in eine art 'zwischenspeicher verfrachten.. ausrechnen und den wert wieder zwischenspeichern.. dann gehts weiter.
jetzt kommt das '*' aber oho.. gleich ne klammer.. und dann nochmal das gleiche wie gerade eben.. und dann eben die 2 werte (also 5 und 2) multiplizieren..
aber bei einer groooßen rechnung mit brüchen oder so.. wird das dann nicht etwas heftig? ^^


aja nur dass ihrs wisst.. ich weiß schon dass ich das auch ganz einfach ausrechnen könnte.. aber ich will ja wie gesagt üben, und diese einzelnen logischen schritte selbst programmieren.. nicht dass sich jetz einer fragt: WTF? warum so umständlich.. ^^
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

2

12.01.2007, 11:01

wo ich schon dabei bin..
angenommen ich will das einer eine zahl eingibt (zb fürs menü)
wie kann ich eine abfrage machen ob der wert auch ganz sicher eine zahl ist..?

so gehts leider nicht

if(choice != int)

geht sowas eigentlich?
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

3

12.01.2007, 11:05

nene an sich ist das schon der richtige Weg. Aber es kommt drauf an was der Rechner alles können soll. Ich gah jetzt erstma nur von mul, add, div und sub aus.

- Zuerst musst du prüfen ob eingabe korrekt ist, also für jede ( auch eine ) exestiert, u.s.w.
- dann könntest du den String in Substrings splitten, ich würde das durch einen binären Baum z.B. machen.
(z.B. so: input: (3 + 2) * (4+ ACHT)

Baum dazu:

Quellcode

1
2
3
4
5
    (3 + 2) * (4+8)
     /                \
(3+2)                 (4+8)
/    \ ......
3    2


Jeder Knoten wird durch eine Datenstrruktur repräsentiert, die aus 2 Werten besteht:

- String
- Ergebnis (Zahl)
- vllt noch "Operation" als enum

Wenn du so nen Baum aufgestellt hast, kannst du - angefangen von den unteren Knoten - die Ausdrücke parsen und das Feld "Ergebnis" ausrechnen. Das Ergebnis ist dann das was im "root" Knoten drin steht.

So würde ich dat machen ^^

veranschaulich mit Datenstruktur:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
        (3 + 2) * (4+8)
                   ?
                  MUL
         /                \
      (3+2)                 (4+8)
          ?                       ?
        ADD                   ADD
      /    \ ......
     3    2
     3    2
       -    -

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

4

12.01.2007, 11:09

*hehe*

ja ungefähr so hab ich mir das auch vorgestellt.. gut zu wissen das ich mal nicht ganz so falsch lag :)

kannst du mir auch die frage beantworten wie ich sichergehn kann ob eine variable auch sicher einen wert eines bestimmten datentyps erhalten hat?

zb

int blah;
cin >> blah;

angenommen jemand gibt
'asdf' ein

wie kann ich da ne abfrage schreiben die sich wiederholt, wenn jemand keine zahl eingegeben hat?
es muss doch sowas geben wie if(blah != int) oder so in der art ^^

danke übrigens :)
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

koschka

Community-Fossil

Beiträge: 2 862

Wohnort: Dresden

Beruf: Student

  • Private Nachricht senden

5

12.01.2007, 11:14

Deine Frage ist wohl eher: wie kann string zu ints machen ;), es gibt da ne tolle atoi Funktion, vllt. gibts da aber auch was in der STL, bin mir da jetzt nicht sicher. Normalerweise kannst du nicht unterscheiden ob a oder 42 eingegeben wurde, ausser du prüfst das.

einfach atoi Funktion: (bin mir bei der 42 jetzt nicht sicher.... glaub das ist falsch, einfach mal im ANSI Ciode nachschaun), oder atoi nutzen.

Quellcode

1
2
3
4
int atoi (char a)
{
   return a - 42;
}


p.s. funzt aber nur bei einstelligen Zahlen, mach aber erstmal mit einstelligen Zahlen, kannst dann ja immernoch auf mehrstellige ausweiten.

Phil_GDM

Alter Hase

Beiträge: 443

Wohnort: Graz

Beruf: Student-Softwareentwicklung u. Wissensmanagement

  • Private Nachricht senden

6

12.01.2007, 11:18

Das ist auch eine Möglichkeit:
1. Infix Ausdruck in Postfix umwandeln
Lösung:
Gehe alle Elemente von links nach rechts durch
a: Element is ( => Lege ( auf Sack
b: Element ist Zahl => Gib Zahl aus
c: Element ist Operator. Gib alle Operatoren mit größerer oder gleicher Priorität aus bis Stapel leer ist oder ( erreicht wird. Lege nun den gegebenen Operator auf den Stapel
d: Element ist ). Gib alle Operatoren aus, bis ( gefunden. Entferne diese.
Am Ende: gib noch alle am Stack verbleibenden Operatoren aus

D.h. aus (3+4)*5^2 wird 3,4,+,5,2,^,*

2.Postfix Ausdruck auswerten
a: Element ist Zahl => lege Zahl auf Stack
b: Element ist Operator => Wende den Operator auf die beiden obersten Zahlen am Stack an, ersezte diese beiden durch das Resultat
Am Ende hast du dann das Resultat der Berechnung am Stack liegen.

mfg Philipp

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

7

12.01.2007, 11:19

Zum casten von String<->Zahl nutzt man gängigerweiße std::stringstream, oder boost::lexical_cast.

Eine stark abgespeckte Version wäre sowas:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
template< typename T, typename S >
T lexical_cast( const S& src )
{
    std::stringstream cnv;
    T result;

    if ( !( cnv << src && cnv >> result 
                       && ( cnv >> std::ws ).eof() ) )
        throw std::logic_error( "lexical_cast failed" );

    return result;
}


Verwendet so:

C-/C++-Quelltext

1
2
3
4
5
int main()
{
    std::string str = "1234";
    int i = lexical_cast< int >( str );
}


grüße
@D13_Dreinig

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

12.01.2007, 12:25

Informatiker machen das so: ;)

1. Eine kontextfreie Grammatik (Typ 2) konstruieren, die alle korrekten Ausdrücke erzeugt, die erkannt werden sollen.
2. Aus der Grammatik einen Parser (Kellerautomat) bauen.
3. Die Eingabe in Token umwandeln (das sind Klammern, Zahlen, Operatoren, Variablen, Funktionsnamen ...).
4. Den Kellerautomaten mit der "tokenisierten" Eingabe füttern.
5. Während der Kellerautomat die Eingabe abarbeitet (und damit testet, ob sie zur Sprache gehört, also gültig ist), kann man den Ableitungsbaum konstruieren.
6. Mit dem fertigen Ableitungsbaum (Termbaum) kann man jetzt relativ einfach das Ergebnis berechnen. Alle inneren Knoten sind Operatoren, und alle Blätter sind Werte (Zahlen, Variablen).

Interessantes Applet:
http://informatik.berthold-gymnasium.de/unterricht/natuwi/mathe/TermBaumApplet.html

9

12.01.2007, 14:13

Guck dir einfach mal Boost an ... da hast du schon klassen drin um die ne eigene Gramatik zu definieren usw... ist also eigentlich ganz einfach ...
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

10

18.01.2007, 17:23

danke leute.. werde ich machen :)
ich schau mich mal um ;)
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Werbeanzeige