我试图在数组中添加一行数字和运算符。我怎么能正确地做到这一点?
我希望将每个数字组分隔为一个索引和下一个索引运算符。
我需要你的帮助来告诉我代码中的错误在哪里:
function toArray($s){
$le = strlen($s);
$j = 0;
$ordered_numbers_operators = array();
$operators = array('+','-','*','/','%','(',')');
for ( $i=0;$i<$le;$i++ ){
if ( in_array( $s[$i], $operators ) ) {
$ordered_numbers_operators[$j] = $s[$i];
$j++;
} else {
if ( $i+1 == $le ){
$ordered_numbers_operators[$j] = $s[$i];
} else {
if ( $s[$i+1] !== in_array( $s[$i+1], $operators )) {
if ( $s[$i+1] == in_array( $s[$i+1], $operators )){
echo "\$i = " . $i . "<br />" ;
$ordered_numbers_operators[$j]=$s[$i];
$j++;
} else {
$ordered_numbers_operators[$j] = $s[$i] . $s[$i+1];
$i++; $j++;
}
}
}
}
}
return $ordered_numbers_operators;
}
$string = '6+4*4+100+444*6*13*14';
$arr = toArray($string);
预期结果:
[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 100
[7] => +
[8] => 444
[9] => *
[10] => 6
[11] => *
[12] => 13
[13] => *
[14] => 14
实际结果:
[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 1
[7] => 0
[8] => 0
[9] => +
[10] => 44
[11] => 4
[12] => *
[13] => 6
[14] => *
[15] => 13
[16] => *
[17] => 14
答案 0 :(得分:5)
如果没有正则表达式,您可以更简单地完成此操作。见this example, to test and run:
<?php
function toArray($s){
$operators = array('+','-','*','/','%','(',')');
$finalArr = [];
$curStr = '';
foreach (str_split($s) as $char) {
if (in_array($char, $operators)) {
//Alright, we have an operator. Append the entire number
$finalArr[] = $curStr;
//And also the operator
$finalArr[] = $char;
//Reset the current string back to empty
$curStr = '';
} else {
//Not an operator? Just keep appending the current number
$curStr .= $char;
}
}
//Add final leftover string
if ($curStr !== '') { //Sanity check here (This shouldn't ever be empty, as you wouldn't end with an operator)
$finalArr[] = $curStr;
}
//Return
return $finalArr;
}
$string = '6+4*4+100+444*6*13*14';
$arr = toArray($string);
print_r($arr);
答案 1 :(得分:4)
您可以使用正则表达式和preg_split
来完成,更容易一些。
$parts = preg_split('~([+*/-])~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);
请注意-
,因为字符类中的最后一个字符很重要。如果在此之后添加更多字符,-
将在每边最近的字符之间创建一个范围。您要分隔的任何字符都可以添加到[]
中。如果添加]
,请务必将其转义,以便闭包正确。您可以在此处阅读有关角色类的更多信息,https://www.regular-expressions.info/charclass.html。
字符类也可以使它不需要转义特殊的正则表达式字符。您也可以像这样删除字符类。
$parts = preg_split('~(\+|\*|/|-)~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);
此外,在运算符之前和之后,\s*
或\h*
可以选择空格。
$parts = preg_split('~\h*([+*/-])\h*~', '6+4*4+100+444*6*13*14', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);
答案 2 :(得分:1)
另一种无正则表达式的方法是使用array_reduce
。
您可以使用str_split
将字符串拆分为数组,然后使用array_reduce
构建所需的数组(以便连接连续的数字)。让我们一步一步来做。首先,使用array_reduce
中的简单回调函数,我们得到与str_split
相同的结果:
function toArray($string) {
$chars = str_split($string);
return array_reduce($chars, function($result, $current) {
$result[] = $current;
return $result;
}, []);
}
$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));
/*
Array
(
[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 1
[7] => 0
[8] => 0
[9] => +
[10] => 4
[11] => 4
[12] => 4
[13] => *
[14] => 6
[15] => *
[16] => 1
[17] => 3
[18] => *
[19] => 1
[20] => 4
)
*/
下一步是在迭代array_reduce
中的字符时检查先前的值和当前值。如果它们都是数字,我们想加入它们:
function toArray($string) {
$chars = str_split($string);
return array_reduce($chars, function($result, $current) {
$previous = $result[] = array_pop($result);
if (is_numeric($previous) && is_numeric($current)) {
$result[] = array_pop($result) . $current;
} else {
$result[] = $current;
}
return $result;
}, []);
}
$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));
/*
Array
(
[0] =>
[1] => 6
[2] => +
[3] => 4
[4] => *
[5] => 4
[6] => +
[7] => 100
[8] => +
[9] => 444
[10] => *
[11] => 6
[12] => *
[13] => 13
[14] => *
[15] => 14
)
*/
几乎就在那里!该数组在索引零处包含一个额外元素。 (这是因为我们使用$previous = $result[] = array_pop($result);
获取上一项。其值为null
,因为最初$result
是一个空数组,因此array_pop
返回null
。我们可以摆脱额外的元素,例如与array_slice
:
function toArray($string) {
$chars = str_split($string);
$array = array_reduce($chars, function($result, $current) {
$previous = $result[] = array_pop($result);
if (is_numeric($previous) && is_numeric($current)) {
$result[] = array_pop($result) . $current;
} else {
$result[] = $current;
}
return $result;
}, []);
return array_slice($array, 1);
}
$input = '6+4*4+100+444*6*13*14';
print_r(toArray($input));
/*
Array
(
[0] => 6
[1] => +
[2] => 4
[3] => *
[4] => 4
[5] => +
[6] => 100
[7] => +
[8] => 444
[9] => *
[10] => 6
[11] => *
[12] => 13
[13] => *
[14] => 14
)
*/