PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : string überprüfen und vergleichen


The Serious Sam
02.06.2007, 20:02:01
Hallo!

Ich stehe vor folgendem problem.
Ich wollte ein script zeigen, mit dem man einen String berechnen kann.

z.B.: $aufgabe = "2+3*4^2";

Das Funktioniert bis jetzt super und nun wollte ich noch zusätzlich
die möglichkeit einbauen Klammer zu setzen.

z.B.: $aufgabe = "3*(3+7)-2";

ich habe einfach die aufgabe zweimal un unterschiedlichen stellen "explodieren" lassen.

Das sieht dann so aus:


$new_string1 = explode("(",$string);
$new_string2 = explode(")",$string);


in den Arrays steht dan nach dem beispiel:

$new_string1[1] = "3+7)-2";
$new_string2[0] = "3*(3+7";

So nun sieht man das ein teil in beiden Array exact übereinstimmt, und zwar der, der oben in der Klammer steht.
Den wollte ich nun rausbekommen. Und das ist nun auch meine Frage.

Wie mach ich das?


wenn ich dann den Inhalt der Klammer berechnet habe,
kann ich ganz leich diesen wieder in die ursprüngliche Aufgabe einsetzen und
dann diese vollständig ausrechnen.

Serp
04.06.2007, 00:47:50
Ich würde empfehlen, die Zeichenkette vernünftig zu parsen, als solche Verrenkungen zu machen...

feuervogel
04.06.2007, 01:37:52
dazu gibts bereits nen thread, hab da ne funktion geschrieben die alles berücksichtigt (also klammern, alle rechenarten und auch punkt vor strich).

moment...

<?php

$exp = '(((3*5)-523/2))-23';
$val = evaluate($exp);

if( $val === null ) {

echo 'Falscher Ausdruck!';

} else {

echo 'Ergebnis: ' . $exp . ' = ' . $val;

}

function evaluate($algebraic_expression) {

#leerzeilen und unnötige zeichen entfernen
$clean = preg_replace( '=[^+\-*/0-9()]=i' , '' , $algebraic_expression );

#nach syntaktischen fehlern schauen
if( preg_match('=(\d\(|\)\d|\([+\-*/\)]|[\(+\-*/]\)|^[+\-*/)]|[+\-*/(]$)=i' , $clean) ) {#

return null;

}

#sind die öffnenden und schließenden klammern richtig gesetzt?
$z = 0;

for( $i = 0; $i < strlen( $clean ); $i++ ) {

if( $clean{$i} == '(' ) {

$z++;

} elseif( $clean{$i} == ')' ) {

$z--;

}

if( $z < 0 ) {

return null;

}

}

#jetzt ist alles okay => auswerten
return eval("return " . $clean . ";");

}

?>

The Serious Sam
06.06.2007, 17:19:00
Das muss einer mal verstehen:

((2+3)*4-(2+3))/2 = 7.5

und

2^2 = 22

Ich glaub da stimmt bei deinem script was net^^

Trotzdem vielen Dank

mfg The Serious Sam

PS: das mit den Klammer hab ich schon oben war ne doofe idee is schon längst weg^^

feuervogel
06.06.2007, 17:23:27
Das muss einer mal verstehen:

((2+3)*4-(2+3))/2 = 7.5


richtig: ((2+3) * 4 - (2+3)) / 2 = (5 * 4 - 5) / 2 = (20 - 5) / 2 = 15 / 2 = 7.5


2^2 = 22

Ich glaub da stimmt bei deinem script was net^^

Trotzdem vielen Dank

mfg The Serious Sam

Was ist denn ^ für ein Grundrechenartensymbol? Ich kenne + - * und /. alles andere wird vorher entfernt (also u.a. das ^)

The Serious Sam
06.06.2007, 17:30:44
Wegen der Aufgabe sry mein Fehler hab mich irgendwo verrechnet.

Hoffe du verzeichst meinen (anfänger) Fehler

Und nun eine Frage:

Wie kann ich das Script verändern, das Potenzen möglich sind?

Das "^" war dafür gedacht^^ (*muhaha* schon wieder dieses Zeichen)


mfg The Serious Sam

feuervogel
06.06.2007, 18:23:18
hm, also ^ ist eigentlich ein bitoperator.

dass das auch noch berechnet wird, ist ganz schön schwer einzubauen, denn dazu bräuchte man einen richtigen syntaxparser.

da ich den ausdruck mittels php berechnen lasse und php potenzen eigentlich mit pow() berechnet, ist das so erst mal nicht machbar. wie gesagt, php kennt das ^ nur als bitoperator, da wäre ein % (modulo) schon leichter zu implementieren.

allerdings können ja deine eingebenden pow(2,3) so eingeben: 2*2*2

The Serious Sam
06.06.2007, 18:59:34
die idee ist schonmal nicht schlecht.

Aber was mach ich das hiermit?

2^1/2

sprich wurzel aus 2

ich hatte vorher mal das hier: (leider nur ohne Klammern)


<?

function parseterm($string)
{
$string = preg_replace('/\s/', '', $string);


if(preg_match('/^(.+?)\+(.+)$/', $string, $matches)) {
return(parseterm($matches[1]) + parseterm($matches[2]));
} elseif(preg_match('/^(.+?)\-(.+)$/', $string, $matches)) {
return(parseterm($matches[1]) - parseterm($matches[2]));
} elseif(preg_match('/^(.+?)\*(.+)$/', $string, $matches)) {
return(parseterm($matches[1]) * parseterm($matches[2]));
} elseif(preg_match('/^(.+?)\/(.+)$/', $string, $matches)) {
return(parseterm($matches[1]) / parseterm($matches[2]));
} elseif(preg_match('/^(.+?)\^(.+)$/', $string, $matches)) {
return(pow(parseterm($matches[1]), parseterm($matches[2])));
} elseif(preg_match('/^\d+$/', $string)) {
return((int)$string);
} else {
echo "<p>\n";
echo " Der zu untersuchende String ist nicht gültig:<br />\n";
echo $string;
echo "</p>\n";
die();
}
}

?>


Naja wie gesagt kann der hier net mit klammer umgehen.

The Serious Sam
06.06.2007, 19:04:09
Achja die Frage:

Kann ich evtl die beiden Scripts verbinden?

wenn ja wie?

Ich hab das Gefühl, dass der Beitrag im falschen Forum gelandet ist :)

naja kann man nichts dran ändern

mfg The Serious Sam

feuervogel
07.06.2007, 00:39:06
nur kurz:

Aber was mach ich das hiermit?

2^1/2

die potenz hat einen höheren rang als die division, also steht da 2^1/2 = 2/2 = 1

willst du die wurzel haben, müsste es so lauten: 2^(1/2)

dann wird zuerst die klammer ausgerechnen und dann potenziert...

The Serious Sam
10.06.2007, 18:10:49
Ja das ist mir klar

Aber du wolltest ja potenzen mit $zahl*$zahl ausgeben.

das wäre nun z.b. 4^2 aber wie soll das bei

4^(1/2) aussehen? $zahl * 1/$zahl oder was? *ironie*

naja ich hoffe du verstehst mich^^