求教一段程序该如何写

时间:2022-01-24 23:28:07
id0  id1 id2 id3  id4
1    ko   >   11   0
2    ko   >   12   0
3    ko   >   13   2
4    ko   >   14   0
5    ko   >   15   0
6    ko   >   16   5
7    ko   >   14   0

结果=》((ko>11 and ko>12) or ko>13 and ko>14 and ko>15 )or ko>16 and ko>17

如题,上面是一个数据库表  可以用数组表示,现在我想做的功能是
当id4=0的时候  我会从id0依次往下走   碰到0就用AND连接2个数据。碰到大于0的就表示要把这个数字前面的列用or连接,就像我上面贴出的结果。 请教这个程序该如何写 

19 个解决方案

#1



$data = array(
array(
'id0'=>1,
'id1'=>'ok',
'id2'=>'>',
'id3'=>11,
'id4'=>0
),
array(
'id0'=>1,
'id1'=>'ok1',
'id2'=>'>',
'id3'=>11,
'id4'=>0
),
array(
'id0'=>1,
'id1'=>'ok2',
'id2'=>'>',
'id3'=>8,
'id4'=>2
),
);

foreach($data as $key=>$val){
$str .= " {$val['id1']} {$val['id2']} {$val['id3']} ";
if($key + 1 >= count($data)){
break;
}
if($val['id4'] == 0){
$str .= "and";
}else{
$str .= "or";
}
}

这里小于0的情况都算作用or连接了

#2


$dat = array(
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$stack = array();
$res = array();
foreach($dat as $v) {
  if($v[1]) $stack = array( '(' . join(' and ', $stack) . ') or ');
  $stack[] = $v[0];
}
echo join(' and ', $stack);
((ko>11 and ko>12) or and ko>13 and ko>14 and ko>15) or and ko>16 and ko>14

#3



$arr=array(
0=>array('ko','>',11,0),
1=>array('ko','>',12,0),
2=>array('ko','>',13,2),
3=>array('ko','>',14,0),
4=>array('ko','>',15,0),
5=>array('ko','>',16,5),
6=>array('ko','>',17,0),
);
$str='';
$l="(";
$r=")";
foreach($arr as $key=>$val){
if($key==0){
if($val[3]==0){
$str.=$val[0].$val[1].$val[2];
}else{
$str.=$val[0].$val[1].$val[2];
}
}else{
if($val[3]==0){
$str.=' and '.$val[0].$val[1].$val[2];
}else{
$str=$l.$str;
$str.=$r.' or '.$val[0].$val[1].$val[2];
}
}
}
echo $str;

((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>17

#4



$arr=array(
0=>array('ko','>',11,0),
1=>array('ko','>',12,0),
2=>array('ko','>',13,2),
3=>array('ko','>',14,0),
4=>array('ko','>',15,0),
5=>array('ko','>',16,5),
6=>array('ko','>',17,0),
);
$str='';
$l="(";
$r=")";
foreach($arr as $key=>$val){
if($key==0){
if($val[3]==0){
$str.=$val[0].$val[1].$val[2];
}else{
$str.=$val[0].$val[1].$val[2];
}
}else{
if($val[3]==0){
$str.=' and '.$val[0].$val[1].$val[2];
}else{
$str=$l.$str;
$str.=$r.' or '.$val[0].$val[1].$val[2];
}
}
}
echo $str;

((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>17

#5


引用 1 楼  的回复:
PHP code

$data = array(
    array(
        'id0'=>1,
        'id1'=>'ok',
        'id2'=>'>',
        'id3'=>11,
        'id4'=>0
    ),
    array(
        'id0'=>1,
        'id1'=>'ok1',
        '……

朋友,我这边碰到or就是要扩上括号的,上述方法无法做到。单一匹配倒是没问题

#6


引用 2 楼  的回复:
PHP code
$dat = array(
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$stack = array();
$res = array()……

唠叨兄。我运行出来在OR的后面多了一个AND  我改成echo join(' ', $stack);这样了。不知道是为什么

#7


本帖最后由 xuzuning 于 2012-08-13 17:48:44 编辑
嗯,是的
事情也没有那么简单,你的 id4 并不只是标志,他的值表示前多少项要用括号括起
$dat = array(
 array('a=1', 0), //我在这里加了一项
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$sign = array_fill(0, count($dat), '');

foreach($dat as $i=>$v) {
  $sign[$i+1] = ' and ';
  if($v[1]) {
    $sign[$i-$v[1]] .= '(';
    $sign[$i] = ') or ';
  }
}
array_pop($sign);
$s = '';
foreach($sign as $i=>$v) $s .= $v . $dat[$i][0];

echo $s;
a=1 and ((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>14

#8


我研究了半天终于放弃,我发现这样的数据取决于录入人员的输入问题,没个统一的规则,我很难把他们的各种条件匹配出来。唠叨兄的办法很好,感谢!

#9


录入的话,应该是管理员录入的,应该不是乱输入的,一般不能出差错,也可权当成规则
若是随便输的,那就不行了,因为有and or问题,无规则,肯定是没办法

#10


该回复于2012-08-14 15:48:56被版主删除

#11


唠叨兄,我按你提供的方法得到的数据有点出入,麻烦帮我看看

Array
(
    [0] => Array
        (
            [eo_id] => 10
            [pt] => 'a'
            [operation_id] => >=
            [info] => 1
            [link] => 0
        )

    [1] => Array
        (
            [eo_id] => 11
            [pt] => 'b'
            [operation_id] => <
            [info] => 2
            [link] => 10
        )

    [2] => Array
        (
            [eo_id] => 12
            [pt] => 'c'
            [operation_id] => =
            [info] => 3
            [link] => 0
        )

    [3] => Array
        (
            [eo_id] => 13
            [pt] => 'd'
            [operation_id] => >
            [info] => 4
            [link] => 12
        )

    [4] => Array
        (
            [eo_id] => 15
            [pt] => 'e'
            [operation_id] => >=
            [info] => 5
            [link] => 0
        )

)

应该要的结果为:  (((a >=1) or b<2 and c=3) or d>4) and e>=5
实际结果为:             a >=1) or b<2 and c=3) or d>4 and e>=5((


$sign = array_fill(0, count($tmp), '');
     
        foreach($tmp as $i=>$v) {
            $sign[$i+1] = ' and ';
            if($v['link']) {
                $sign[$i-$v['link']] .= '(';
                $sign[$i] = ') or ';
            }
        }
        array_pop($sign);
        $s = '';//print_r($tmp);
        foreach($sign as $i=>$v) $s .= $v . $tmp[$i]['pt'] .$tmp[$i]['operation_id'] . $tmp[$i]['info']  ;

#12


你不是放弃了这个方案吗?怎么还弄?
对于 $sign[$i-$v['link']] .= '('; 要求$v['link']的值是自$i起的向前偏移量。
你的显然不是

动态输入表达式要这样方式,处理起来就简单了
开弧 变量名 关系 值 与下一项的关系 闭弧

#13


没办法,客户那边要这种方案。
link的值是连接eo_id的,并不是表示前面要连接起来的列的数量

我这样的需求是不是没法实现了?

#14


你哥的条件不充分
$dat = array (
  0 => array (
    'eo_id' => 10,
    'pt' => 'a',
    'operation_id' => '>=',
    'info' => 1,
    'link' => 0,
  ),
  1 => array (
    'eo_id' => 11,
    'pt' => 'b',
    'operation_id' => '<',
    'info' => 2,
    'link' => 10,
  ),
  2 => array (
    'eo_id' => 12,
    'pt' => 'c',
    'operation_id' => '=',
    'info' => 3,
    'link' => 0,
  ),
  3 => array (
    'eo_id' => 13,
    'pt' => 'd',
    'operation_id' => '>',
    'info' => 4,
    'link' => 10,
  ),
  4 => array (
    'eo_id' => 15,
    'pt' => 'e',
    'operation_id' => '>=',
    'info' => 5,
    'link' => 0,
  ),
);
$k = '';
foreach($dat as $item) {
  $st[$item['eo_id']] = array('', $item['pt'].$item['operation_id'].$item['info']);
  if($item['link']) {
    $st[$item['link']][0] .= '(';
    $st[$item['eo_id']][0] = ') or ';
  }else {
    $st[$item['eo_id']][0] = $k;
  }
  $k = ' and ';
}
$s = '';
foreach($st as $item) $s .= join('', $item);
echo $s;

((a>=1) or b<2 and c=3) or d>4 and e>=5

#15


引用 13 楼  的回复:
没办法,客户那边要这种方案。
虽然说用户是上帝
但上帝也是会犯错的

要是用户让你写程序得到 1 + 1 = 3,你也照着做吗?

#16


求教一段程序该如何写
唠叨大哥谢谢了,我现在就过去砍了客户。稍后跟各位汇报情况

#17


你就跟客户说这种方案是不可取的 没法做的。 真想这样做,就拿高价吓唬他,换一种方法能实现想要的就行。

#18


客户方被我弄死了1个。高枕无忧。啊哈哈哈!!!

#19



<?php
$dat = array (
  0 => array (
    'eo_id' => 10,
    'pt' => 'a',
    'operation_id' => '>=',
    'info' => 1,
    'link' => 0,
  ),
  1 => array (
    'eo_id' => 11,
    'pt' => 'b',
    'operation_id' => '<',
    'info' => 2,
    'link' => 10,
  ),
  2 => array (
    'eo_id' => 12,
    'pt' => 'c',
    'operation_id' => '=',
    'info' => 3,
    'link' => 0,
  ),
  3 => array (
    'eo_id' => 13,
    'pt' => 'd',
    'operation_id' => '>',
    'info' => 4,
    'link' => 10,
  ),
  4 => array (
    'eo_id' => 15,
    'pt' => 'e',
    'operation_id' => '>=',
    'info' => 5,
    'link' => 0,
  ),
);

$result = '';
$first = 0;
foreach($dat as $v)
{
    $exp = $v['pt'].$v['operation_id'].$v['info'];
    if($v['link'] == 0) {
        $result .= ($first++ == 0) ? $exp : " and " . $exp;
    } else {
        $result = "($result) or " . $exp;
    }
}
print($result);
?>

#1



$data = array(
array(
'id0'=>1,
'id1'=>'ok',
'id2'=>'>',
'id3'=>11,
'id4'=>0
),
array(
'id0'=>1,
'id1'=>'ok1',
'id2'=>'>',
'id3'=>11,
'id4'=>0
),
array(
'id0'=>1,
'id1'=>'ok2',
'id2'=>'>',
'id3'=>8,
'id4'=>2
),
);

foreach($data as $key=>$val){
$str .= " {$val['id1']} {$val['id2']} {$val['id3']} ";
if($key + 1 >= count($data)){
break;
}
if($val['id4'] == 0){
$str .= "and";
}else{
$str .= "or";
}
}

这里小于0的情况都算作用or连接了

#2


$dat = array(
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$stack = array();
$res = array();
foreach($dat as $v) {
  if($v[1]) $stack = array( '(' . join(' and ', $stack) . ') or ');
  $stack[] = $v[0];
}
echo join(' and ', $stack);
((ko>11 and ko>12) or and ko>13 and ko>14 and ko>15) or and ko>16 and ko>14

#3



$arr=array(
0=>array('ko','>',11,0),
1=>array('ko','>',12,0),
2=>array('ko','>',13,2),
3=>array('ko','>',14,0),
4=>array('ko','>',15,0),
5=>array('ko','>',16,5),
6=>array('ko','>',17,0),
);
$str='';
$l="(";
$r=")";
foreach($arr as $key=>$val){
if($key==0){
if($val[3]==0){
$str.=$val[0].$val[1].$val[2];
}else{
$str.=$val[0].$val[1].$val[2];
}
}else{
if($val[3]==0){
$str.=' and '.$val[0].$val[1].$val[2];
}else{
$str=$l.$str;
$str.=$r.' or '.$val[0].$val[1].$val[2];
}
}
}
echo $str;

((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>17

#4



$arr=array(
0=>array('ko','>',11,0),
1=>array('ko','>',12,0),
2=>array('ko','>',13,2),
3=>array('ko','>',14,0),
4=>array('ko','>',15,0),
5=>array('ko','>',16,5),
6=>array('ko','>',17,0),
);
$str='';
$l="(";
$r=")";
foreach($arr as $key=>$val){
if($key==0){
if($val[3]==0){
$str.=$val[0].$val[1].$val[2];
}else{
$str.=$val[0].$val[1].$val[2];
}
}else{
if($val[3]==0){
$str.=' and '.$val[0].$val[1].$val[2];
}else{
$str=$l.$str;
$str.=$r.' or '.$val[0].$val[1].$val[2];
}
}
}
echo $str;

((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>17

#5


引用 1 楼  的回复:
PHP code

$data = array(
    array(
        'id0'=>1,
        'id1'=>'ok',
        'id2'=>'>',
        'id3'=>11,
        'id4'=>0
    ),
    array(
        'id0'=>1,
        'id1'=>'ok1',
        '……

朋友,我这边碰到or就是要扩上括号的,上述方法无法做到。单一匹配倒是没问题

#6


引用 2 楼  的回复:
PHP code
$dat = array(
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$stack = array();
$res = array()……

唠叨兄。我运行出来在OR的后面多了一个AND  我改成echo join(' ', $stack);这样了。不知道是为什么

#7


本帖最后由 xuzuning 于 2012-08-13 17:48:44 编辑
嗯,是的
事情也没有那么简单,你的 id4 并不只是标志,他的值表示前多少项要用括号括起
$dat = array(
 array('a=1', 0), //我在这里加了一项
 array('ko>11', 0),
 array('ko>12', 0),
 array('ko>13', 2),
 array('ko>14', 0),
 array('ko>15', 0),
 array('ko>16', 5),
 array('ko>14', 0),
);
$sign = array_fill(0, count($dat), '');

foreach($dat as $i=>$v) {
  $sign[$i+1] = ' and ';
  if($v[1]) {
    $sign[$i-$v[1]] .= '(';
    $sign[$i] = ') or ';
  }
}
array_pop($sign);
$s = '';
foreach($sign as $i=>$v) $s .= $v . $dat[$i][0];

echo $s;
a=1 and ((ko>11 and ko>12) or ko>13 and ko>14 and ko>15) or ko>16 and ko>14

#8


我研究了半天终于放弃,我发现这样的数据取决于录入人员的输入问题,没个统一的规则,我很难把他们的各种条件匹配出来。唠叨兄的办法很好,感谢!

#9


录入的话,应该是管理员录入的,应该不是乱输入的,一般不能出差错,也可权当成规则
若是随便输的,那就不行了,因为有and or问题,无规则,肯定是没办法

#10


该回复于2012-08-14 15:48:56被版主删除

#11


唠叨兄,我按你提供的方法得到的数据有点出入,麻烦帮我看看

Array
(
    [0] => Array
        (
            [eo_id] => 10
            [pt] => 'a'
            [operation_id] => >=
            [info] => 1
            [link] => 0
        )

    [1] => Array
        (
            [eo_id] => 11
            [pt] => 'b'
            [operation_id] => <
            [info] => 2
            [link] => 10
        )

    [2] => Array
        (
            [eo_id] => 12
            [pt] => 'c'
            [operation_id] => =
            [info] => 3
            [link] => 0
        )

    [3] => Array
        (
            [eo_id] => 13
            [pt] => 'd'
            [operation_id] => >
            [info] => 4
            [link] => 12
        )

    [4] => Array
        (
            [eo_id] => 15
            [pt] => 'e'
            [operation_id] => >=
            [info] => 5
            [link] => 0
        )

)

应该要的结果为:  (((a >=1) or b<2 and c=3) or d>4) and e>=5
实际结果为:             a >=1) or b<2 and c=3) or d>4 and e>=5((


$sign = array_fill(0, count($tmp), '');
     
        foreach($tmp as $i=>$v) {
            $sign[$i+1] = ' and ';
            if($v['link']) {
                $sign[$i-$v['link']] .= '(';
                $sign[$i] = ') or ';
            }
        }
        array_pop($sign);
        $s = '';//print_r($tmp);
        foreach($sign as $i=>$v) $s .= $v . $tmp[$i]['pt'] .$tmp[$i]['operation_id'] . $tmp[$i]['info']  ;

#12


你不是放弃了这个方案吗?怎么还弄?
对于 $sign[$i-$v['link']] .= '('; 要求$v['link']的值是自$i起的向前偏移量。
你的显然不是

动态输入表达式要这样方式,处理起来就简单了
开弧 变量名 关系 值 与下一项的关系 闭弧

#13


没办法,客户那边要这种方案。
link的值是连接eo_id的,并不是表示前面要连接起来的列的数量

我这样的需求是不是没法实现了?

#14


你哥的条件不充分
$dat = array (
  0 => array (
    'eo_id' => 10,
    'pt' => 'a',
    'operation_id' => '>=',
    'info' => 1,
    'link' => 0,
  ),
  1 => array (
    'eo_id' => 11,
    'pt' => 'b',
    'operation_id' => '<',
    'info' => 2,
    'link' => 10,
  ),
  2 => array (
    'eo_id' => 12,
    'pt' => 'c',
    'operation_id' => '=',
    'info' => 3,
    'link' => 0,
  ),
  3 => array (
    'eo_id' => 13,
    'pt' => 'd',
    'operation_id' => '>',
    'info' => 4,
    'link' => 10,
  ),
  4 => array (
    'eo_id' => 15,
    'pt' => 'e',
    'operation_id' => '>=',
    'info' => 5,
    'link' => 0,
  ),
);
$k = '';
foreach($dat as $item) {
  $st[$item['eo_id']] = array('', $item['pt'].$item['operation_id'].$item['info']);
  if($item['link']) {
    $st[$item['link']][0] .= '(';
    $st[$item['eo_id']][0] = ') or ';
  }else {
    $st[$item['eo_id']][0] = $k;
  }
  $k = ' and ';
}
$s = '';
foreach($st as $item) $s .= join('', $item);
echo $s;

((a>=1) or b<2 and c=3) or d>4 and e>=5

#15


引用 13 楼  的回复:
没办法,客户那边要这种方案。
虽然说用户是上帝
但上帝也是会犯错的

要是用户让你写程序得到 1 + 1 = 3,你也照着做吗?

#16


求教一段程序该如何写
唠叨大哥谢谢了,我现在就过去砍了客户。稍后跟各位汇报情况

#17


你就跟客户说这种方案是不可取的 没法做的。 真想这样做,就拿高价吓唬他,换一种方法能实现想要的就行。

#18


客户方被我弄死了1个。高枕无忧。啊哈哈哈!!!

#19



<?php
$dat = array (
  0 => array (
    'eo_id' => 10,
    'pt' => 'a',
    'operation_id' => '>=',
    'info' => 1,
    'link' => 0,
  ),
  1 => array (
    'eo_id' => 11,
    'pt' => 'b',
    'operation_id' => '<',
    'info' => 2,
    'link' => 10,
  ),
  2 => array (
    'eo_id' => 12,
    'pt' => 'c',
    'operation_id' => '=',
    'info' => 3,
    'link' => 0,
  ),
  3 => array (
    'eo_id' => 13,
    'pt' => 'd',
    'operation_id' => '>',
    'info' => 4,
    'link' => 10,
  ),
  4 => array (
    'eo_id' => 15,
    'pt' => 'e',
    'operation_id' => '>=',
    'info' => 5,
    'link' => 0,
  ),
);

$result = '';
$first = 0;
foreach($dat as $v)
{
    $exp = $v['pt'].$v['operation_id'].$v['info'];
    if($v['link'] == 0) {
        $result .= ($first++ == 0) ? $exp : " and " . $exp;
    } else {
        $result = "($result) or " . $exp;
    }
}
print($result);
?>

#20