Impressum · Kontakt · Hilfe
Besucher online · Mitglieder



Portal > Foren > PHP > PHP-Programmierung > Problem bei Stringverarbeitung in PHP
Antwort
 
Themen-Optionen
Alt 05.11.2006, 12:55   Nach oben    #1
Ilinsekt
/(bb|[^b]{2})/
 
Registriert seit: 05.11.2006
Beiträge: 29
Standard Problem bei Stringverarbeitung in PHP

Hi@all!

Ich habe ein kleines Prob. Und zwar habe ich diesen Code:

PHP-Code:
<html>
<head>
<title>Testseite</title>
</head>
<body>

<?php

error_reporting
(E_ALL);


if (!isset(
$_GET['nullgleichung']) or $_GET['nullgleichung']=="") {}
else
{
  
  
  
$potenzen=substr_count($_GET['nullgleichung'],'^');       //Anzahl der Cirkoflexe(=Potenzen)
  
$variablen=substr_count($_GET['nullgleichung'],'x');      //Anzahl der X (=Variablen)
  
  
$varpos[-1]=-2;       //wichtig für die for-Schleife, definiert eine Variable
  
$xnull2[-1]=$_GET['nullgleichung'];   //wichtig für die for-Schleife, definiert eine Variable
  
for ($a=0;$a<$variablen;$a++)
  {
    
$varpos[$a]=strpos($xnull2[$a-1],'x',$varpos[$a-1]+2);   //Position der Variable x
    
$grundstring[$a]=substr($xnull2[$a-1],$varpos[$a]-1,1);   //Das Zeichen, das vor x steht
    
    
if (ord($grundstring[$a])!=43 and ord($grundstring[$a])!=42 and ord($grundstring[$a])!=45 and ord($grundstring[$a])!=47)  //prüft, ob vor dem x eine Grundrechenart steht
    
{
      
$xnull2[$a]=substr_replace($xnull2[$a-1],'*x',$varpos[$a],1);   //ersetzt x durch *x
    

    

  

  
$xnull1=preg_replace("/x/i",'$null',$xnull2[$a-1]);   //Ersetzt alle x durch $null
  
$xnull=str_replace($xnull1,$xnull1.'+0-0/1*1',$xnull1);          //fügt am Ende der Gleichung ein + hinzu
  
  
$grundposition[-1]=-6;                          //wichtig für die for-Schleife, definiert eine Variable
  
$grundpos[-1]=-6;                         //wichtig für die for-Schleife, definiert eine Variable
  
$xpotenz[-1]=$xnull;                     //wichtig für die for-Schleife, definiert eine Variable
 

  
for ($i=0;$i<$potenzen;$i++)                               //for-Schleife
{
    
  
$nullpos[$i]=strpos($xpotenz[$i-1],'$null^',$grundpos[$i-1]+6);     //Position von $null^
  
  
$pluspos[$i]=strpos($xpotenz[$i-1],'+',$nullpos[$i]);               //Position des nächsten Pluszeichens
  
$minuspos[$i]=strpos($xpotenz[$i-1],'-',$nullpos[$i]);               //Position des nächsten Minuszeichens
  
$malpos[$i]=strpos($xpotenz[$i-1],'*',$nullpos[$i]);                //Position des nächsten Mal-Zeichens
  
$geteiltpos[$i]=strpos($xpotenz[$i-1],'/',$nullpos[$i]);             //Position des nächsten Geteilt-Durch-Zeichens
  
  
$grundarray=array(1=>$pluspos[$i],2=>$minuspos[$i],3=>$malpos[$i],4=>$geteiltpos[$i]);  //Array aus den Positionen

  
$grundpos[$i]=min($grundarray)
       
  
$potenzpos[$i]=strpos($xpotenz[$i-1],'^');  //Position der Potenzen hinter dem Cirkoflex
  
$potenz[$i]=substr($xpotenz[$i-1],$potenzpos[$i]+1,$grundpos[$i]-1-$potenzpos[$i]);  //Die Potenz als Teilstring
     
  
$xpotenz[$i]=str_replace('$null^'."$potenz[$i]",'pow($null,'.$potenz[$i].')',$xpotenz[$i-1]);//Umwandlung der Potenz in PHP-Code
  
}  
  
  echo 
$_GET['nullgleichung']."........".$xnull.".......".$xpotenz[$i-1];
}
?>






<br><br>
<span class='normal'>Hier können Sie die Nullstelle einer beliebigen Gleichung mit einer Variablen berechnen. Die Variable muss X heißen. Potenzen werden als x^y angegeben</span>
<form action='405.php' method='get'>
<table border='0' cellpadding='0' cellspacing='4'>
<tr>
 <td align='right'>Gleichung:</td>
 <td><input class='mOFF' name='nullgleichung' type='text' size='20' maxlength='160'></td>
 </tr><tr>
   <td align='right'><input type='submit' value='Berechnen!'></td>  
 </tr>
</table> 
</form>

</body>
</html>

Der soll für eine Gleichung, die ich eingebe, die x durch $null ersetzen und davor ein* hinzufügen, falls da kein +-*/ steht. Leider kriege ich immer, wenn ich ihn ausführe, einige Warnungen und Notizen, dass in Zeile soundso (je nach Gleichung) der Offset undefiniert ist und in der Funktion strpos() der Offset nicht funktioniert. Wenn ich in Zeile 27 die and durch or ersetze, kriege ich keine Meldungen, aber dann fügt der in jedem Fall ein * vor dem x ein, auch wenn da ein+-*/ steht.

Kann mir jemand helfen?

Greetz, Ilinsekt

Geändert von Ilinsekt (05.11.2006 um 15:00 Uhr).
Ilinsekt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.11.2006, 12:59   Nach oben    #2
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.800
Standard

Hallo und willkommen im Forum.
Du kannst deine Beiträge editieren. Bitte tu dies und nutze die PHP-Tags.

Danke dir.
Danach schaue ich mir dein Problem auch an.

Grüße, Ben.


[EDIT]
Danke, ich schau mal.

Geändert von Ben (05.11.2006 um 13:24 Uhr).
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.11.2006, 13:31   Nach oben    #3
Ben
Erfahrener Benutzer
 
Benutzerbild von Ben
 
Registriert seit: 02.12.2004
Ort: Remagen
Beiträge: 4.800
Standard

Äh, ja. Also ich erhalte das hier
Code:
y = x^2........y = *$null^2+0-0/1*1.......y = *pow($null,2)+0-0/1*1
wenn ich y = x^2 in das Formularfeld einsetze.

Der Code ist recht wirr, da nicht wirklich dokumentiert.
Zitat:
//wichtig für die for-Schleife, definiert eine Variable
Ist jetzt nicht wirklich hilfreich.

Was genau ist dein Fehler? (Muss gestehen, dass ich mich jetzt nicht intensiv damit befasst habe .. mich hat die Lust verlassen, als ich den Code gesehen hab ).

Kannst du uns eventuell sagen, wann genau du eine Meldung erhälst?

Danke.
Grüße, Ben.
Ben ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 05.11.2006, 14:58   Nach oben    #4
Ilinsekt
/(bb|[^b]{2})/
 
Registriert seit: 05.11.2006
Beiträge: 29
Standard

Wenn ich eingebe: 25x^23+5*x^2

sollte er das in 25*pow($null,23)+5*($null,2) umwandeln, d.h. wenn kein +-*/ vor dem x steht, soll er ein *-Zeichen hinzufügen. Bei dieser Gleichung erhalte ich folgendes:
Zitat:
Notice: Undefined offset: 1 in /usr/export/www/vhosts/funnetwork/hosting/ilinsekt/405.php on line 35

Warning: strpos() [function.strpos]: Offset not contained in string. in /usr/export/www/vhosts/funnetwork/hosting/ilinsekt/405.php on line 46

Notice: Undefined offset: 2 in /usr/export/www/vhosts/funnetwork/hosting/ilinsekt/405.php on line 77
Sonst kriege ich keine Antwort ($xpotenz[$i-1] ist anscheinend undefiniert/enthält einen leeren String.




Zitat:
Zitat von Ben
Der Code ist recht wirr, da nicht wirklich dokumentiert.
Zitat:
//wichtig für die for-Schleife, definiert eine Variable
Ist jetzt nicht wirklich hilfreich.
Die Funktionen in der For-Schleife greifen auf den Output des letzten Durchlaufs zu, z.B. $xnull2[$a-1] . Beim ersten Durchlauf der Schleife existiert kein Output aus dem vorhergehenden Durchlauf, sodass ich $xnull[-1] vor der Schleife definierten muss.

Greetz, Ilinsekt

Geändert von Ilinsekt (05.11.2006 um 15:08 Uhr).
Ilinsekt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 06.11.2006, 02:02   Nach oben    #5
Jojo
Irgendwas mit e
 
Benutzerbild von Jojo
 
Registriert seit: 26.08.2005
Ort: Mannheim
Beiträge: 388
Standard

ALso ich habe deinen Code ausprobiert und versucht, ihn zu verstehen, aber ich glaube, dass du leider auf dem falschen Dampfer bist.
Denn sobald du eine Funkton vom Format [i}y=(24+x)^4-x(5+x)[/i] bekommst, wirst du ein Problem haben.

Ich würde folgendermaßen vorgehen:
Zuerst würde ich eine Art Hierarchie der Funktion entwerfen entsprechend den Zugehörigkeiten der einzelnen Teile.
Für unsere Beispielfunktion sähe diese Hierarchie folgendermaßen aus: (in geschweiften Klammern nach dem Wort "Array" immer der Teil auf das sich das Array bezieht)
Code:
$function =
Array { (24+x)^4-x(5+x) }
[0] => Array { (24+x)^4 }
         [0] => Array { 24+x }
                  [0] => 24
                  [1] => x
                  ['Konnektor'] => +
         [1] => 4
         ['Konntektor'] => ^
[1] => Array { x(5+x) }
         [0] => x
         [1] => Array { 5+x }
                  [0] => 5
                  [1] => x
                  ['Konnektor'] => +
         ['Konnektor'] => *
['Konnektor'] => -
Dies wird nicht einfach werden, vor allem weil du noch beachten musst, dass du gleich starke Verknüpfungen zusammenfassen musst, da du auf einer Ebene nur 2 Elemente + Konnektor haben darfst.
( aus 25+x+3 wird 28+x )
Ich kann dir jetzt nicht sagen, wie du das exakt machen kannst, aber im Grunde funktioniert es so.
Ich würde so vorgehen:
Zuerst würde ich alle Leerstellen aus der Gleichung entfernen.
Anschließend würde ich alle ax bzw. xa zu a*x bzw. zu x*a umwandeln.
Danach würde ich alle Zugehörigkeiten anhand von Klammern in eine Hierarchie umwandeln.
Dann würde ich innerhalb der gleichen Ebene (in der gleichen Klammer) nach gleich starken Verknüpfungen suchen und sie zusammenfassen. ( 4+(5+x) ist legitim (4+5+x) nicht!! )
Danach könnte man die Hierarchie von vorhin aufstellen.
Und dann würde ich daran gehen, die x durch $null zu ersetzen und die einzelnen Operatoren durch ihre Entsprechung in PHP
Und dann alles wieder zusammensetzen, wobei Ebenen geklammert werden.

Tadaaa! Fertig.
Noch dabei?
Gut, weil ich nämlich fast nicht mehr
Also ich fände es eine Herausforderung.

Helfen würde dir dabei die Funktion preg_match_all sowie weitere pref-Funktionen.
Und vielleicht auch das Tut über Rekursion

Grüße,
Jojo
__________________
In the beginning was the word
and the word was content-type: plain/text

heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int
Jojo ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 06.11.2006, 09:59   Nach oben    #6
Jojo
Irgendwas mit e
 
Benutzerbild von Jojo
 
Registriert seit: 26.08.2005
Ort: Mannheim
Beiträge: 388
Standard

Also ich lag gestern noch lange wach, weil mich ein ungutes Gefühl bei meiner Antwort plagte.
Am Ende habe ich dann doch nen Fehler gefunden.

Mit meiner Technik hast du leider folgenden Fall nicht abgedeckt:
Code:
y=(23+x)^3+2x^2+2
Daher nun meine Korrrektur:
Zuerst trennst du wie gehabt die Gleichung nach Klammern auf.
Dann erstellt du auf dieser Basis davon einen Hierarchiebaum, mit jeweils zwei Elementen.
mehrere gleiche Verknüpfungen würde ich wie folgt aufbauen:
x^3+x^2+x wird zu
Code:
Array
[0] => x^3+x^2
[1] => x
['Konnektor'] => +
was dann wieder zu
Code:
Array
[0] => Array
         [0] => x^3
         [1] => x^2
         ['Konnektor'] => +
[1] => x
['Konnektor'] => +
So in der Form für jede gleich starke Verbindung
So hast du nicht das Problem, zusammenfügen zu müssen und behälst doch die binäre Struktur bei.
Dann fängst du an, aufgrund deines "Klammerbaumes" die Elemente aufsteigend nach ihren Verknüpfungen immer mehr zu unterteilen, bis du zu einem Baum wie in meinem Thread vorher kommst.
Dann entsprechend ersetzen und fertig.
__________________
In the beginning was the word
and the word was content-type: plain/text

heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int
Jojo ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 06.11.2006, 13:03   Nach oben    #7
Ilinsekt
/(bb|[^b]{2})/
 
Registriert seit: 05.11.2006
Beiträge: 29
Standard

Also, danke erstmal für die Antworten!

Mein ursprüngliches Problem habe ich jetzt gelöst, es hat eine else-Struktur gefehlt.

Nun zu deiner Idee, Jojo: Ich finde, das ist unnötig, da PHP die Klammerregeln kennt. Ich werde meinen Code halt etwas umbauen müssen, á la wenn vor dem Cirkoflex eine Klammer steht, dann sucht er die vorherige Position einer öffnenden Klammer und ersetzt die Klammern und die Potent durch pow(Klammerinhalt z.B. 5+$null,Potenz z.B. 4). Es geht darum, in der Stringvariable $xpotenz einen gültigen PHP-Code als String zu speichern, sodass ich ihn mit eval() nutzen kann.

Greetz, Ilinsekt
Ilinsekt ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 06.11.2006, 14:54   Nach oben    #8
Jojo
Irgendwas mit e
 
Benutzerbild von Jojo
 
Registriert seit: 26.08.2005
Ort: Mannheim
Beiträge: 388
Standard

Mir ist klar, dass PHP Klammern kennt.
Nur könntest du eventuell Schwierigkeiten bekommen, wenn du damit bestimmte Funktionen ausführst.
Aber nun gut, war ein Vorschlag.
Kann man sicherlich auch anders machen.

Grüße,
Jojo
__________________
In the beginning was the word
and the word was content-type: plain/text

heute code ich, morgen debug ich und uebermorgen cast ich die koenigin auf int
Jojo ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 09.11.2006, 18:46   Nach oben    #9
Ilinsekt
/(bb|[^b]{2})/
 
Registriert seit: 05.11.2006
Beiträge: 29
Standard

Der Code ist jetzt soweit fertig, dass er die Gleichung in PHP-Code übersetzt, auch wenn vor der Potenz Klammern oder Zahlen stehen. eval() funktioniert auch, fehlt nur noch die Bestimmung der Nullstelle, was aber einfach sein dürfte, da ich den dafür nötigen Code bereits auf meinem Taschenrechner (Texas Instruments TI 82 Stats, bin jetzt 10. Klasse, da kriegt man sowas) programmiert habe, muss ihn nur noch für PHP abschreiben. Falls es dich interessiert, hier mein Code soweit:

PHP-Code:
<html>
<head>
<title>Testseite</title>
</head>
<body>

<?php

error_reporting
(E_ALL);


if (!isset(
$_GET['nullgleichung']) or $_GET['nullgleichung']=="") {}
else
{
  
  
  
$potenzen=substr_count($_GET['nullgleichung'],'^');       //Anzahl der Cirkoflexe(=Potenzen)
  
$variablen=substr_count($_GET['nullgleichung'],'x');      //Anzahl der X (=Variablen)
  
$gleich=strpos($_GET['nullgleichung'],'=');
  if (
substr_count($_GET['nullgleichung'],'=')!=0)
  {
    
$xnull3=substr($_GET['nullgleichung'],$gleich+1);       //entfernt alles vor der Gleichung inkl. Gleichheitszeichen
}
else
{
  
$xnull3=$_GET['nullgleichung'];
}
  
  
$varpos[-1]=-2;
  
$xnull2[-1]=$xnull3;
  for (
$a=0;$a<$variablen;$a++)
  {
    
$varpos[$a]=strpos($xnull2[$a-1],'x',$varpos[$a-1]+2);   //Position der Variable x
    
$grundstring[$a]=substr($xnull2[$a-1],$varpos[$a]-1,1);   //Das Zeichen, das vor x steht
    
    
if ($varpos[$a]==0)
    {
      
$xnull2[$a]=$xnull3;
    }    
    else if (
ord($grundstring[$a])!=43 and ord($grundstring[$a])!=42 and ord($grundstring[$a])!=45 and ord($grundstring[$a])!=47)  //prüft, ob vor dem x eine Grundrechenart steht
    
{
      
$xnull2[$a]=substr_replace($xnull2[$a-1],'*x',$varpos[$a],1);   //ersetzt x durch *x
    

    else
    {
      
$xnull2[$a]=$xnull2[$a-1];
    }
    

  

  
$xnull1=preg_replace("/x/i",'$null',$xnull2[$a-1]);   //Ersetzt alle x durch $null
  
$xnull=str_replace($xnull1,$xnull1.'+0-0/1*1',$xnull1);          //fügt am Ende der Gleichung ein +0-0/1*1 hinzu
  
  
$potenzpos[-1]=0;                          //wichtig für die for-Schleife, definiert eine Variable
  
$grundpos[-1]=-6;                         //wichtig für die for-Schleife, definiert eine Variable
  
$xpotenz[-1]=$xnull;                     //wichtig für die for-Schleife, definiert eine Variable
 

  
for ($i=0;$i<$potenzen;$i++)                               //for-Schleife
{
    
  
$potenzpos[$i]=strpos($xpotenz[$i-1],'^');  //Position der Potenzen hinter dem Cirkoflex
  
  
$vorpotenz[$i]=substr($xpotenz[$i-1],$potenzpos[$i]-1,1);    //Zeichen vor dem Cirkoflex (=Potenz)
  
  
if (ord($vorpotenz[$i])==41)        //prüft, ob vor der Potenz eine Zuklammer steht
  
{
    
$aufklammer[$i]=strpos($xpotenz[$i-1],'(',$grundpos[$i-1]+6);     // sucht die vorherige Aufklammer
    
$potenzbase[$i]=substr($xpotenz[$i-1],$aufklammer[$i]+1,$potenzpos[$i]-$aufklammer[$i]-2);   //Die Zahlenfolge, die potenziert werden soll
    
$potenzklammer[$i]=substr($xpotenz[$i-1],$aufklammer[$i],$potenzpos[$i]-$aufklammer[$i]);  //die Zahlenfolge mit Klammern
  
}
  else if (
ord($vorpotenz[$i])==48 or ord($vorpotenz[$i])==49 or ord($vorpotenz[$i])==50 or ord($vorpotenz[$i])==51 or ord($vorpotenz[$i])==52 or ord($vorpotenz[$i])==53 or ord($vorpotenz[$i])==54 or ord($vorpotenz[$i])==55 or ord($vorpotenz[$i])==56 or ord($vorpotenz[$i])==57)        //prüft, ob vor der Potenz eine Zahl steht
  
{
  
$potenzbase[$i]=substr($xpotenz[$i-1],$grundpos[$i-1]+6,$vorpotenz[$i]-1-$grundpos[$i-1]+6);  //Die Zahl, die potenziert werden soll
  
$potenzklammer[$i]=$potenzbase[$i];    //die Zahl
}
else
{
  
$potenzbase[$i]='$null';    //$null als String
  
$potenzklammer[$i]=$potenzbase[$i];   //$null alst String
}
  
  
  
  
  
$pluspos[$i]=strpos($xpotenz[$i-1],'+',$potenzpos[$i]);               //Position des nächsten Pluszeichens
  
$minuspos[$i]=strpos($xpotenz[$i-1],'-',$potenzpos[$i]);               //Position des nächsten Minuszeichens
  
$malpos[$i]=strpos($xpotenz[$i-1],'*',$potenzpos[$i]);                //Position des nächsten Mal-Zeichens
  
$geteiltpos[$i]=strpos($xpotenz[$i-1],'/',$potenzpos[$i]);             //Position des nächsten Geteilt-Durch-Zeichens
  
  
$grundarray=array(1=>$pluspos[$i],2=>$minuspos[$i],3=>$malpos[$i],4=>$geteiltpos[$i]);  //Array aus den Positionen

  
$grundpos[$i]=min($grundarray);       //die kleinste Position aus dem Array

  
$potenz[$i]=substr($xpotenz[$i-1],$potenzpos[$i]+1,$grundpos[$i]-1-$potenzpos[$i]);  //Die Potenz als Teilstring
     
  
$xpotenz[$i]=str_replace($potenzklammer[$i].'^'.