|
ryax 发表于 2012-9-21 09:16 ![]()
楼主熬夜啊,我和你的答案差不多,可能是我算错了。
你答案是怎么弄出来的?
我用PLSQL写了一下,因为思路相同,答案也相同。用了二维数组确实代码少了一点,但是更难读了。
DECLARE
TYPE ta_str IS TABLE OF VARCHAR2(200);
lv_op ta_str := ta_str('+','-','*','/');
TYPE ta_num IS TABLE OF NUMBER;
lv_op_pr ta_num := ta_num(0,0,1,1);
TYPE tr_expr IS RECORD (expr VARCHAR2(200),op_pr VARCHAR2(1),pos ta_num);
TYPE ta_expr1 IS TABLE OF tr_expr INDEX BY PLS_INTEGER;
TYPE ta_expr IS TABLE OF ta_expr1 INDEX BY PLS_INTEGER; --- 2D
lv_data ta_expr;
lv_data2 ta_expr;
lv_cnt NUMBER;
TYPE tp_expr IS TABLE OF BOOLEAN INDEX BY VARCHAR2(200);
lv_expr tp_expr;
lv_cols VARCHAR2(200);
lv_pos NUMBER;
BEGIN
FOR i IN 1..6 LOOP
lv_data(1)(i).expr := CHR(ASCII('A')+i-1);
lv_data(1)(i).pos := ta_num();
END LOOP;
FOR k IN REVERSE 1..5 LOOP
lv_cnt :=0;
FOR r IN 1..lv_data.COUNT LOOP
FOR c2 IN 1..k LOOP
FOR i_op IN 1..4 LOOP
lv_cnt := lv_cnt +1;
lv_cols := '';
FOR c IN 1..k LOOP
IF c2=c THEN
lv_data2(lv_cnt)(c).expr :=
CASE
WHEN lv_data(r)(c).op_pr < lv_op_pr(i_op) THEN
'('||lv_data(r)(c).expr||')'
ELSE lv_data(r)(c).expr
END
||lv_op(i_op);
lv_pos := LENGTH(lv_data2(lv_cnt)(c).expr);
CASE
WHEN lv_data(r)(c+1).op_pr < lv_op_pr(i_op) THEN
lv_data2(lv_cnt)(c).expr := lv_data2(lv_cnt)(c).expr ||'('||lv_data(r)(c+1).expr||')';
WHEN lv_data(r)(c+1).op_pr = lv_op_pr(i_op) AND lv_op(i_op) IN ('-','/') THEN
FOR i IN 1..lv_data(r)(c+1).pos.COUNT LOOP
lv_data2(lv_cnt)(c).expr := lv_data2(lv_cnt)(c).expr ||
SUBSTR(lv_data(r)(c+1).expr
,CASE i WHEN 1 THEN 0 ELSE lv_data(r)(c+1).pos(i-1)+1 END
,lv_data(r)(c+1).pos(i)-CASE i WHEN 1 THEN 0 ELSE lv_data(r)(c+1).pos(i-1) END-1
)
||TRANSLATE(SUBSTR(lv_data(r)(c+1).expr,lv_data(r)(c+1).pos(i),1),'+-*/','-+/*');
END LOOP;
lv_data2(lv_cnt)(c).expr := lv_data2(lv_cnt)(c).expr
||SUBSTR(lv_data(r)(c+1).expr,lv_data(r)(c+1).pos(lv_data(r)(c+1).pos.COUNT)+1);
ELSE
lv_data2(lv_cnt)(c).expr := lv_data2(lv_cnt)(c).expr ||lv_data(r)(c+1).expr;
END CASE;
lv_data2(lv_cnt)(c).op_pr := lv_op_pr(i_op);
IF lv_data(r)(c).op_pr = lv_op_pr(i_op) THEN
lv_data2(lv_cnt)(c).pos := lv_data(r)(c).pos;
ELSE
lv_data2(lv_cnt)(c).pos := ta_num();
END IF;
lv_data2(lv_cnt)(c).pos.EXTEND;
lv_data2(lv_cnt)(c).pos(lv_data2(lv_cnt)(c).pos.COUNT):=lv_pos;
IF lv_data(r)(c+1).op_pr = lv_op_pr(i_op) THEN
FOR i IN 1..lv_data(r)(c+1).pos.COUNT LOOP
lv_data2(lv_cnt)(c).pos.EXTEND;
lv_data2(lv_cnt)(c).pos(lv_data2(lv_cnt)(c).pos.COUNT):=lv_pos+lv_data(r)(c+1).pos(i);
END LOOP;
END IF;
ELSIF c<c2 THEN
lv_data2(lv_cnt)(c) := lv_data(r)(c);
ELSE
lv_data2(lv_cnt)(c) := lv_data(r)(c+1);
END IF;
lv_cols := lv_cols ||lv_data2(lv_cnt)(c).expr;
END LOOP;
IF lv_expr.EXISTS(lv_cols) THEN
lv_data2.DELETE(lv_cnt);
lv_cnt := lv_cnt -1;
ELSE
lv_expr(lv_cols) := TRUE;
END IF;
END LOOP;
END LOOP;
END LOOP;
lv_data := lv_data2;
END LOOP;
DBMS_OUTPUT.PUT_LINE('COUNT='||lv_data.COUNT);
END;
/
COUNT=12608
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.55
|
|