Когда-то на третьем курсе писал перевод строки в обратную польсую запись. Теперь эта функция мне нужна на php.
Вот мой код на С++
C++ |
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
| stack<char> s;
string r,str;
cin>>str;
int i,q=0,a,b,size=str.length();
for(i=0;i<size;i++)
{
if(((str[i]>47) && (str[i]<58)) || ((str[i]>64) && (str[i]<91)) || ((str[i]>96) && (str[i]<123))) {cout<<str[i];goto L;}
else M: if(s.empty()) {switch(str[i])//если стек пустой
{case '*': s.push(str[i]);break;
case '/': s.push(str[i]);break;
case '+': s.push(str[i]);break;
case '-': s.push(str[i]);break;
case '(': goto O;break;
case ')': goto D;break;
default:cout<<"Unknown symbol '"<<str[i]<<"'"<<endl;}
goto L;}
else //если не пустой
{switch(str[i])//приоритет входного символа
{case '*': a=3;break;
case '/': a=3;break;
case '+': a=2;break;
case '-': a=2;break;
case '(':goto O;break;
case ')': goto D;break;
default:cout<<"Unknown symbol '"<<str[i]<<"'"<<endl;}
switch(s.top())//приоритет верхнего символа стека
{case '*': b=3;break;
case '/': b=3;break;
case '+': b=2;break;
case '-': b=2;break;
case '(': b=1;break;}
if(b<a) switch(str[i])
{case '*': s.push(str[i]);break;
case '/': s.push(str[i]);break;
case '+': s.push(str[i]);break;
case '-': s.push(str[i]);break;
case '(': goto O;break;
case ')': goto D;break;
default:cout<<"Unknown symbol '"<<str[i]<<"'"<<endl;}
if(b>=a)
{bool bl=0;
while(bl==0)
{int c;
switch(s.top())
{case '*': c=3;break;
case '/': c=3;break;
case '+': c=2;break;
case '-': c=2;break;
case '(': c=1;break;
default:cout<<"Unknown symbol '"<<str[i]<<"'"<<endl;}
cout<<s.top();
s.pop();
if((c<a) || (s.empty())) bl=1;}//{b=1;break;}}//поправка в алгоритм
goto M;}goto L;}
O: if(str[i]==40) s.push(str[i]);
D: if(str[i]==41)
{bool bl=0;
while(bl==0)
{cout<<s.top();
s.pop();
if(s.top()==40) {s.pop();bl=1;}}}
L:;}
if(!s.empty())
{bool bl=0;
while(bl==0)
{cout<<s.top();
s.pop();
if(s.empty()) bl=1;}}
getch(); |
|
Вот как получилось перевсти на php
PHP |
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
| function cppVersion ($str)
{
$s=array();//cntr
$size = strlen($str);//размер полученой строк
for($i=0;$i<$size;$i++)
{$ord = ord($str[$i]);//перевод сивола в его аски-код (для того, чтобы узнать в каком диапазоне он)
if((($ord>47) && ($ord<58)) || (($ord>64) && ($ord<91)) || (($ord>96) && ($ord<123))) {$ret.= chr($ord); goto L;}
else M: if(empty($s)) {switch($ord)//если стек пуст
{case '*': {array_push($s,chr($ord));break;}
case '/': {array_push($s,chr($ord));break;}
case '+': {array_push($s,chr($ord));break;}
case '-': {array_push($s,chr($ord));break;}
case '(': {goto O;break;}
case ')': {goto D;break;}
default: $ret .= '<br>Unknown symbol "'.chr($ord).'"<br>';}
goto L;}
else //если не пуст
{switch(chr($ord))//приоритет входного символа
{case '*': {$a=3;break;}
case '/': {$a=3;break;}
case '+': {$a=2;break;}
case '-': {$a=2;break;}
case '(': {goto O;break;}
case ')': {goto D;break;}
default: $ret .= '<br>Unknown symbol "'.chr($ord).'"<br>';}
switch(last ($s))//приоритет верхнего символа стека
{case '*': $b=3;break;
case '/': $b=3;break;
case '+': $b=2;break;
case '-': $b=2;break;
case '(': $b=1;break;}
if($b<$a) switch(chr($ord))//сравнение текущего символа с верним в стеке
{case '*': {array_push($s,chr($ord));break;}
case '/': {array_push($s,chr($ord));break;}
case '+': {array_push($s,chr($ord));break;}
case '-': {array_push($s,chr($ord));break;}
case '(': goto O;break;
case ')': goto D;break;
default: $ret .= "<br>Unknown symbol '".chr($ord)."'<br>";}
if($b>=$a)//если приоритет больше
{$bl=0;
while($bl==0)
{
switch(last($s))//приоритет верхнего символа в стеке
{case '*': $c=3;break;
case '/': $c=3;break;
case '+': $c=2;break;
case '-': $c=2;break;
case '(': $c=1;break;
default: $ret .= "<br>Unknown symbol '".chr($ord)."'<br>";}
$ret.= last ($s);
array_pop($s);
if(($c<$a) || (empty($s))) $bl=1;}//{b=1;break;}}//поправка в алгоритм
goto M;}goto L;}//а ниже влом бошку ломать
O: if($ord==40) array_push($s,chr($ord));
D: if($ord==41)
{$bl=0;
while($bl==0)
{$ret.=last($s);
array_pop($s);
if(last($s)==40) {array_pop($s);$bl=1;}}}
L:;}
if(!empty($s))
{$bl=0;
while($bl==0)
{$ret .= last($s);
array_pop($s);
if(empty($s)) $bl=1;}
}
return $ret;//возврат строки в виде ОПЗ
}
function last ($s)
{
$l = $s[count($s)-1];
return $l;
} |
|
Проверка:
PHP |
1
2
| $expr = '(3+2)/5)';
var_dump(cppVersion($expr)); |
|
Результат:
string '<br>Unknown symbol "("<br>3<br>Unknown symbol "+"<br>2<br>Unknown symbol ")"<br><br>Unknown symbol "/"<br>5<br>Unknown symbol ")"<br>' (length=133)
Что я сделал неправильно?
Добавлено через 9 минут
Или такая проверка
PHP |
1
2
| $a = cppVersion($expr);
echo $a; |
|
Результат:
Unknown symbol "("
3
Unknown symbol "+"
2
Unknown symbol ")"
Unknown symbol "/"
5
Unknown symbol ")"
Получается только цыфры видит.