質問編集履歴
4
正規表現の誤りを修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -121,7 +121,7 @@
|
|
121
121
|
|
122
122
|
function convertToPostfix($expression) {
|
123
123
|
$expression = preg_replace('/\s/', '', $expression);
|
124
|
-
preg_match_all('/[0-9a-zA-Z-_]+|&&|\|\||\(\)/', $expression, $matches);
|
124
|
+
preg_match_all('/[0-9a-zA-Z-_]+|&&|\|\||\(|\)/', $expression, $matches);
|
125
125
|
|
126
126
|
if(substr_count($expression, '(') !== substr_count($expression, ')')) return false;
|
127
127
|
|
3
引数と返り値を変更
title
CHANGED
File without changes
|
body
CHANGED
@@ -90,8 +90,10 @@
|
|
90
90
|
var_dump(checkFlags( $expression, $flags ) );
|
91
91
|
|
92
92
|
function checkFlags($expression, $flags){
|
93
|
-
$postfix = convertToPostfix($expression
|
93
|
+
$postfix = convertToPostfix($expression);
|
94
|
+
|
94
|
-
|
95
|
+
$postfix = strtr($postfix, $flags);
|
96
|
+
|
95
97
|
$parts = preg_split('/\s/', $postfix, -1, PREG_SPLIT_NO_EMPTY);
|
96
98
|
$stack = [];
|
97
99
|
|
@@ -99,8 +101,8 @@
|
|
99
101
|
if (is_numeric($part)) {
|
100
102
|
$stack[] = $part;
|
101
103
|
} else {
|
102
|
-
$b = (
|
104
|
+
$b = (float)array_pop($stack);
|
103
|
-
$a = (
|
105
|
+
$a = (float)array_pop($stack);
|
104
106
|
|
105
107
|
switch ($part) {
|
106
108
|
case "&&":
|
@@ -117,12 +119,9 @@
|
|
117
119
|
return (bool)$stack[0];
|
118
120
|
}
|
119
121
|
|
120
|
-
function convertToPostfix($expression
|
122
|
+
function convertToPostfix($expression) {
|
121
123
|
$expression = preg_replace('/\s/', '', $expression);
|
122
|
-
if(substr_count($expression, '(') !== substr_count($expression, ')')) return false;
|
123
|
-
|
124
|
-
$expression = strtr($expression, $flags);
|
125
|
-
preg_match_all('/[0-
|
124
|
+
preg_match_all('/[0-9a-zA-Z-_]+|&&|\|\||\(\)/', $expression, $matches);
|
126
125
|
|
127
126
|
if(substr_count($expression, '(') !== substr_count($expression, ')')) return false;
|
128
127
|
|
@@ -134,8 +133,18 @@
|
|
134
133
|
$priorities = [ '&&' => 2, '||' => 2, '(' => 1, ')' => 1 ];
|
135
134
|
|
136
135
|
foreach ($parts as $part) {
|
136
|
+
if( $part == '&&' || $part == '||' ) {
|
137
|
-
|
137
|
+
if (!empty($stack)) {
|
138
|
+
while (true) {
|
139
|
+
$end = end($stack);
|
140
|
+
if ($end && $priorities[$part] <= $priorities[$end]) {
|
141
|
+
$output []= array_pop($stack);
|
142
|
+
} else {
|
143
|
+
break;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
138
|
-
$
|
147
|
+
$stack[] = $part;
|
139
148
|
} elseif ($part == '(') {
|
140
149
|
$stack[] = $part;
|
141
150
|
} elseif ($part == ')') {
|
@@ -149,18 +158,8 @@
|
|
149
158
|
}
|
150
159
|
}
|
151
160
|
} else {
|
152
|
-
if (!empty($stack)) {
|
153
|
-
while (true) {
|
154
|
-
$end = end($stack);
|
155
|
-
if ($end && $priorities[$part] <= $priorities[$end]) {
|
156
|
-
|
161
|
+
$output[] = $part;
|
157
|
-
} else {
|
158
|
-
break;
|
159
|
-
|
162
|
+
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
$stack[] = $part;
|
163
|
-
}
|
164
163
|
}
|
165
164
|
|
166
165
|
while (count($stack) > 0) {
|
2
floatをintに変更
title
CHANGED
File without changes
|
body
CHANGED
@@ -99,8 +99,8 @@
|
|
99
99
|
if (is_numeric($part)) {
|
100
100
|
$stack[] = $part;
|
101
101
|
} else {
|
102
|
-
$b = (
|
102
|
+
$b = (int)array_pop($stack);
|
103
|
-
$a = (
|
103
|
+
$a = (int)array_pop($stack);
|
104
104
|
|
105
105
|
switch ($part) {
|
106
106
|
case "&&":
|
1
解決方法を追記
title
CHANGED
File without changes
|
body
CHANGED
@@ -63,4 +63,110 @@
|
|
63
63
|
限られた条件式においては動作しますが、丸括弧が2重になっている場合などでは正しく動作しません。
|
64
64
|
おそらく再帰関数を使わなければならないのだとは思いますが、どのようにすればいいのでしょうか?
|
65
65
|
おかしなやり方をしている部分もあると思いますし、根本的に間違っている場合は全く別のやり方でも構いません。
|
66
|
-
よろしくお願いします。
|
66
|
+
よろしくお願いします。
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
### 追記
|
71
|
+
|
72
|
+
2017-09-14
|
73
|
+
|
74
|
+
shimitei様にコメントで教えていただいた逆ポーランド記法を使いソース全体を作り直しました。
|
75
|
+
ひとまず正しく動作できているようなので掲載しておきます。改善点や修正点がありましたらコメントか編集をお願い致します。
|
76
|
+
|
77
|
+
```PHP
|
78
|
+
<?php
|
79
|
+
$flags = [
|
80
|
+
'flag1' => 1,
|
81
|
+
'flag2' => 0,
|
82
|
+
'flag3' => 0,
|
83
|
+
'flag4' => 1,
|
84
|
+
'flag5' => 1
|
85
|
+
];
|
86
|
+
|
87
|
+
// 「&&」は AND, 「||」 は OR を表す
|
88
|
+
$expression = 'flag1 && (flag2 || flag3) || (flag4 && flag5)';
|
89
|
+
|
90
|
+
var_dump(checkFlags( $expression, $flags ) );
|
91
|
+
|
92
|
+
function checkFlags($expression, $flags){
|
93
|
+
$postfix = convertToPostfix($expression, $flags);
|
94
|
+
|
95
|
+
$parts = preg_split('/\s/', $postfix, -1, PREG_SPLIT_NO_EMPTY);
|
96
|
+
$stack = [];
|
97
|
+
|
98
|
+
foreach ($parts as $part) {
|
99
|
+
if (is_numeric($part)) {
|
100
|
+
$stack[] = $part;
|
101
|
+
} else {
|
102
|
+
$b = (float)array_pop($stack);
|
103
|
+
$a = (float)array_pop($stack);
|
104
|
+
|
105
|
+
switch ($part) {
|
106
|
+
case "&&":
|
107
|
+
$x = $a && $b;
|
108
|
+
array_push($stack, $x);
|
109
|
+
break;
|
110
|
+
case "||":
|
111
|
+
$x = $a || $b;
|
112
|
+
array_push($stack, $x);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
return (bool)$stack[0];
|
118
|
+
}
|
119
|
+
|
120
|
+
function convertToPostfix($expression, $flags) {
|
121
|
+
$expression = preg_replace('/\s/', '', $expression);
|
122
|
+
if(substr_count($expression, '(') !== substr_count($expression, ')')) return false;
|
123
|
+
|
124
|
+
$expression = strtr($expression, $flags);
|
125
|
+
preg_match_all('/[0-9]+|&&|\|\||\(\)/', $expression, $matches);
|
126
|
+
|
127
|
+
if(substr_count($expression, '(') !== substr_count($expression, ')')) return false;
|
128
|
+
|
129
|
+
$parts = $matches[0];
|
130
|
+
|
131
|
+
$stack = [];
|
132
|
+
$output = [];
|
133
|
+
|
134
|
+
$priorities = [ '&&' => 2, '||' => 2, '(' => 1, ')' => 1 ];
|
135
|
+
|
136
|
+
foreach ($parts as $part) {
|
137
|
+
if (is_numeric($part)) {
|
138
|
+
$output[] = $part;
|
139
|
+
} elseif ($part == '(') {
|
140
|
+
$stack[] = $part;
|
141
|
+
} elseif ($part == ')') {
|
142
|
+
while (count($stack) > 0) {
|
143
|
+
$end = end($stack);
|
144
|
+
if ($end == '(') {
|
145
|
+
array_pop($stack);
|
146
|
+
break;
|
147
|
+
} else {
|
148
|
+
$output[] = array_pop($stack);
|
149
|
+
}
|
150
|
+
}
|
151
|
+
} else {
|
152
|
+
if (!empty($stack)) {
|
153
|
+
while (true) {
|
154
|
+
$end = end($stack);
|
155
|
+
if ($end && $priorities[$part] <= $priorities[$end]) {
|
156
|
+
$output []= array_pop($stack);
|
157
|
+
} else {
|
158
|
+
break;
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
$stack[] = $part;
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
while (count($stack) > 0) {
|
167
|
+
$output[] = array_pop($stack);
|
168
|
+
}
|
169
|
+
|
170
|
+
return implode(' ', $output);
|
171
|
+
}
|
172
|
+
```
|