表达式化简

Lawrence444 2002-08-23 03:58:16
帮个忙。最近晕晕乎乎,不想写程序。

((a[9] + (((((4 * ((((9 * (1 * n)) - a[7]) * n) - a[8])) + ((a[1] + (a[8] - a[4])) + ((a[9] - (6 * (8 * (11 * ((11 * n) - a[9]))))) * n))) - (a[10] + (((9 * (((3 * ((3 * (6 * (a[10] + (4 * (a[8] - (3 * (a[1] + a[5]))))))) - a[8])) - (4 * ((((9 * n) - a[7]) * n) - a[8]))) - (4 * ((((9 * n) - a[7]) * n) - a[8])))) + ((4 * ((a[8] - (11 * ((11 * n) - a[9]))) - a[8])) + a[7])) - a[7]))) - ((((3 * n) - (7 * (6 * (a[10] + (6 * ((((a[8] - a[4]) - a[7]) * n) - a[8])))))) - a[1]) + (11 * ((11 * n) - a[9])))) - (3 * (((a[9] - ((3 * (n - a[8])) + (((n * ((3 * (9 * (a[9] - (a[9] + n)))) + ((11 * n) + (((a[9] + n) + (a[2] * ((11 * a[8]) + (((((3 * a[4]) + (n * n)) - ((a[8] - a[4]) * (a[9] - (a[9] + n)))) - ((((a[8] - a[4]) * (a[9] - (a[9] + n))) - a[3]) - a[2])) - ((a[8] - a[4]) * (a[9] - (a[9] + n))))))) - a[10])))) + (a[8] + ((11 * ((11 * n) - a[9])) + (9 * ((a[9] + (((a[9] - (6 * (a[10] + (((((a[4] + (a[4] + (a[1] + ((6 * a[3]) - (10 * (4 * ((11 * n) - a[8]))))))) - (7 * (n * n))) - a[1]) + ((n * n) + a[7])) - a[7])))) * n) - ((8 * (11 * ((11 * n) - a[9]))) + ((3 * ((3 * (6 * (a[10] + (4 * (a[8] - (3 * (a[1] + a[5]))))))) - a[8])) - ((((((a[8] - a[4]) - a[7]) * n) - a[8]) - a[7]) * n))))) + (((a[8] + (((11 * n) - a[7]) + (8 * (11 * ((11 * n) - 8))))) * n) + (((a[8] + (((((a[8] - a[4]) - a[7]) * n) * n) + (8 * (((11 * n) - a[7]) * n)))) + (7 * (a[4] + (a[1] + ((a[8] - a[4]) - (10 * (4 * (((11 * a[1]) * n) - a[8])))))))) + ((((((11 * a[8]) + (4 * (((((11 * n) + ((a[8] - a[4]) - a[7])) - a[7]) * n) - a[8]))) - a[9]) + (a[8] - a[4])) + (8 * (11 * ((7 * (a[8] - a[4])) - a[9])))) - (((((a[8] - a[4]) - a[7]) - a[8]) - (a[9] + n)) - (a[5] - (a[5] - (((a[2] * ((a[8] - a[4]) + (11 * a[8]))) + (10 * (4 * ((((9 * (1 * n)) - a[7]) * n) - a[8])))) - a[8])))))))))))) + (a[8] - a[4])))) - a[9]) - a[9])))) + (((a[2] * (10 * (a[10] + (4 * (a[8] - (3 * (a[1] + a[5]))))))) - (10 * (4 * ((11 * a[1]) * n)))) + ((a[1] + ((a[8] - a[4]) - a[7])) + ((a[9] - (6 * (8 * (11 * ((11 * n) - a[9]))))) * n))))
...全文
100 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lawrence444 2002-08-25
  • 打赏
  • 举报
回复
Thank you very much!!
孩皮妞野 2002-08-25
  • 打赏
  • 举报
回复
//==============================================================
// hard coded parser class
//==============================================================
class simplifier{
const char * expr; // the expression to be simplified
int cur,len; // expr[cur] is the current position
enum { EOI = 0, ID = 1, NUM = 2 };
private:
void advance(int off){
cur += off;
}

std::string compose_error_msg(const std::string& s){
std::stringstream ss(std::ios::out);
ss<<"\nerror occurred at "<<cur+1<<std::endl;
int start,end;
start = (cur>5) ? cur-5 : 0;
end = (cur<len-6) ? cur+6 : len;
ss<<std::string(expr+start, expr+end)<<std::endl
<<std::string(cur-start,' ')<<'^';
return s+ss.str();
}

int peek(){ //peek next token
char c;
while( (c=expr[cur])!=0 && (c == ' ' || c == '\n' || c== 't'))
++cur;
switch(c){
case EOI: case '(': case ')': case '+':
case '-': case '*': case '[': case ']':
return c;
default:
if( isdigit(c) )
return NUM;
else if( isalpha(c) )
return ID;
else
throw std::runtime_error(compose_error_msg("unknown token"));
}
}
// expr -> t
// | t + expr
// | t - expr
expression& ex_expr(expression& e){
int t;
ex_term(e);
while((t=peek())=='+' || t == '-'){
advance(1);
expression tm;
ex_term(tm);
if(t == '-') tm *= -1;
e += tm;
}
return e;
}
// t -> f
// | f * t
expression& ex_term(expression& e){
int t;
ex_factor(e);
expression tmp;
while((t=peek())=='*'){
advance(1);
e *= ex_factor(tmp);
}
return e;
}
// get a number
int get_num(){
int i = atoi(expr+cur);
while(isdigit(expr[++cur]))
;
return i;
}
// get an id
std::string get_id(){
int tmp = cur;
while(isalnum(expr[++tmp]))
;
std::string s(expr+cur,expr+tmp);
cur = tmp;
if(peek()=='['){
std::string index;
advance(1);
int t = peek();
switch(t){
case NUM:{
int i = get_num();
std::stringstream ss;
ss<<i;
ss>>index;
break;
}
case ID:
index = get_id();
break;
default:
throw std::runtime_error("expecting an number or an id");
}
if(peek()!=']')
throw std::runtime_error("expecting a ']'");
advance(1);
s += "[" + index + "]";
}
return s;
}
// f -> NUM | ID
// | ( expr )
// | - f // a negative of factor
expression& ex_factor(expression& e){
int t=peek();
switch(t){
case NUM:
return e = expression(term(get_num())); // default assignment is ok.
case ID:
return e = expression(term(get_id()));
case '(':
advance(1);
ex_expr(e);
if(peek()!=')')
throw std::runtime_error(compose_error_msg("expecting a ')'"));
advance(1);
break;
case '-': // Unary -
advance(1);
ex_factor(e) *= expression(term(-1));
break;
default:
throw std::runtime_error(compose_error_msg("expecting a factor"));
}
return e;
}
public:
simplifier(const char * expr):expr(expr),cur(0),len(strlen(expr)){}

expression& simplify(expression& e){
ex_expr(e);
switch(peek()){
case EOI:
break;
case NUM: case ID: case '(':
throw std::runtime_error(compose_error_msg("expecting one of '+-*'"));
case ')':
throw std::runtime_error(compose_error_msg("too many ')'"));
default:
throw std::runtime_error(compose_error_msg("extra chars in input"));
}
return e;
}
};


extern char * formula;

#pragma argsused
int main(int argc, char* argv[])
{
using namespace std;

try{
expression e;
string s;
ofstream of("output.txt");
simplifier(formula).simplify(e).say_it(s);
cout << s << endl;
of << s << endl;
}catch(std::runtime_error& err){
cerr << "runtime error:" << err.what() << endl;
}catch(...){
cerr << "unknown error occurred!\n";
}

return 0;
}
//---------------------------------------------------------------------------

char * formula =
"((a[9] + (((((4 * ((((9 * (1 * n)) - a[7]) * n) - a[8])) +"
"((a[1] + (a[8] - a[4])) + ((a[9] - (6 * (8 * (11 * ((11 * n)"
"- a[9]))))) * n))) - (a[10] + (((9 * (((3 * ((3 * (6 * (a[10]"
"+ (4 * (a[8] - (3 * (a[1] + a[5]))))))) - a[8])) - (4 * ((((9 * n)"
"- a[7]) * n) - a[8]))) - (4 * ((((9 * n) - a[7]) * n) - a[8]))))"
"+ ((4 * ((a[8] - (11 * ((11 * n) - a[9]))) - a[8])) + a[7]))"
"- a[7]))) - ((((3 * n) - (7 * (6 * (a[10] + (6 * ((((a[8] - a[4])"
"- a[7]) * n) - a[8])))))) - a[1]) + (11 * ((11 * n) - a[9])))) -"
"(3 * (((a[9] - ((3 * (n - a[8])) + (((n * ((3 * (9 * (a[9] -"
"(a[9] + n)))) + ((11 * n) + (((a[9] + n) + (a[2] * ((11 * a[8])"
"+ (((((3 * a[4]) + (n * n)) - ((a[8] - a[4]) * (a[9] -"
"(a[9] + n)))) - ((((a[8] - a[4]) * (a[9] - (a[9] + n)))"
"- a[3]) - a[2])) - ((a[8] - a[4]) * (a[9] - (a[9] + n)))))))"
"- a[10])))) + (a[8] + ((11 * ((11 * n) - a[9])) + (9 * ((a[9]"
"+ (((a[9] - (6 * (a[10] + (((((a[4] + (a[4] + (a[1] + ((6 * a[3])"
"- (10 * (4 * ((11 * n) - a[8]))))))) - (7 * (n * n))) - a[1])"
"+ ((n * n) + a[7])) - a[7])))) * n) - ((8 * (11 * ((11 * n) -"
"a[9]))) + ((3 * ((3 * (6 * (a[10] + (4 * (a[8] - (3 * (a[1] +"
"a[5]))))))) - a[8])) - ((((((a[8] - a[4]) - a[7]) * n) - a[8])"
"- a[7]) * n))))) + (((a[8] + (((11 * n) - a[7]) + (8 * (11 *"
"((11 * n) - 8))))) * n) + (((a[8] + (((((a[8] - a[4]) - a[7])"
"* n) * n) + (8 * (((11 * n) - a[7]) * n)))) + (7 * (a[4] +"
"(a[1] + ((a[8] - a[4]) - (10 * (4 * (((11 * a[1]) * n) - a[8])"
"))))))) + ((((((11 * a[8]) + (4 * (((((11 * n) + ((a[8] - a[4])"
"- a[7])) - a[7]) * n) - a[8]))) - a[9]) + (a[8] - a[4])) +"
"(8 * (11 * ((7 * (a[8] - a[4])) - a[9])))) - (((((a[8] - a[4])"
"- a[7]) - a[8]) - (a[9] + n)) - (a[5] - (a[5] - (((a[2] * ((a[8]"
"- a[4]) + (11 * a[8]))) + (10 * (4 * ((((9 * (1 * n)) - a[7])"
"* n) - a[8])))) - a[8])))))))))))) + (a[8] - a[4])))) - a[9])"
"- a[9])))) + (((a[2] * (10 * (a[10] + (4 * (a[8] - (3 * (a[1]"
"+ a[5]))))))) - (10 * (4 * ((11 * a[1]) * n)))) + ((a[1] +"
"((a[8] - a[4]) - a[7])) + ((a[9] - (6 * (8 * (11 * ((11 * n)"
"- a[9]))))) * n))))";
孩皮妞野 2002-08-25
  • 打赏
  • 举报
回复
a somewhat more efficient version. in case it's of some use to Lawrence444.

//---------------------------------------------------------------------------
#pragma hdrstop
#define _USE_OLD_RW_STL

#include <list>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <ctype.h>
#include <stdlib.h>
#include <fstream>

// term is a chain of factors
struct term{
int coef; // coefficient;
std::list<std::string> factors;

term(int coef = 1) : coef(coef){}
term(const char * s) : coef(1),factors(1,std::string(s)){}
term(const std::string& s) :coef(1),factors(1,s){}
term(const term& a) : coef(a.coef),factors(a.factors){}

term& operator *= (const term& rhs)
{
coef *= rhs.coef;
std::list<std::string> l( rhs.factors );
factors.merge(l);
return *this;
}

bool eq_rank(const term& rhs){
return factors == rhs.factors;
}

// write the content on s
void say_it(std::string& s, bool no_sign=false){
std::stringstream sstr;
sstr << (no_sign ? abs(coef) : coef);
s += sstr.str();
std::list<std::string>::iterator i=factors.begin(), j;
for(unsigned exp=1; i != factors.end();i=j, exp=1 ){
s += "*" + *i;
for(j=i, ++j; j!=factors.end() && *i == *j;++exp, ++j)
;
if(exp>1){
std::stringstream sstr;
sstr << exp;
s += "^"+sstr.str();
}
}
}

// required by merge algorithm
bool operator < (const term& rhs)const{
return factors < rhs.factors;
}
};

term operator * (const term& lhs, const term& rhs)
{
term tmp(lhs);
return tmp *=rhs;
}

// a chain of term
struct expression{
std::list<term> terms;

expression(){}
expression(const term& t) : terms(1,t){}
expression(const expression& e) :terms(e.terms){}

expression& operator +=(const expression& rhs)
{
std::list<term> l=rhs.terms;
terms.merge(l);
typedef std::list<term>::iterator iter;

for(iter i=terms.begin(),j; i !=terms.end(); ++i)
for(j=i,++j; j != terms.end()&& j->eq_rank(*i);j=i,++j){
i->coef += j->coef;
terms.erase(j);
if(i->coef == 0)
i=terms.erase(i);
}
return *this;
}

expression& operator *=(const term& rhs){
typedef std::list<term>::iterator iter;
for(iter i=terms.begin(); i != terms.end(); i++)
*i *= rhs;
return *this;
}

expression& operator *= (const expression& rhs){
expression result;
typedef std::list<term>::const_iterator citer;
for(citer i=rhs.terms.begin(); i != rhs.terms.end(); i++){
expression tmp(*this);
tmp *= *i;
result += tmp;
}
this->terms.swap(result.terms);
return *this;
}

std::string say_it(){
std::string s; return say_it(s);
}

std::string& say_it(std::string& s){
typedef std::list<term>::iterator iter;
if(terms.size()){
terms.front().say_it(s);
iter i = terms.begin();
for(++i; i != terms.end(); ++i){
s += (i->coef<0) ? " - " : " + ";
i->say_it(s, true); // say it without print sign
}
}
return s;
}
};




yitong111 2002-08-24
  • 打赏
  • 举报
回复
gz
zhoukun666 2002-08-24
  • 打赏
  • 举报
回复
我想会家去老婆了!真的!
Lawrence444 2002-08-24
  • 打赏
  • 举报
回复
谢谢o3y兄,算的非常对,明天给分。
FARKY 2002-08-24
  • 打赏
  • 举报
回复
9*a[2]*n*a[4]+33*a[2]*n*a[8]+9*a[2]*n^2*a[8]-9*a[2]*n^2*a[4]+3*n*a[2]*a[3]+100020*n^2-44385*n-35*a[9]+26*a[7]+15520*a[8]+23520*a[1]-16637*a[4]-1903*a[10]+23328*a[5]-83600*a[1]*n-54*n^2*a[4]-54*n^2*a[7]-1894*n*a[7]+1088*n*a[9]-6120*n*a[8]-684*n*a[4]+364*a[2]*a[8]-27*a[2]*a[4]+3*a[2]*n^3+3*n*a[2]^2-165*n*a[10]-972*n*a[3]+54*n^2*a[8]+972*n^3+10*a[2]*a[10]-120*a[2]*a[1]-120*a[2]*a[5]
孩皮妞野 2002-08-24
  • 打赏
  • 举报
回复
Lawrence444兄,

写了一个, 写起来容易,调试折腾了半天,有个bug一直找不出来,麻烦Lawrence444兄和其他精通C++的兄弟帮忙看看。

上了点彩,300分, 赢家独得。
Lawrence444 2002-08-23
  • 打赏
  • 举报
回复
我弄得很不爽啊。

表达式树平均长度达到400时候我机器就会爆掉,所以我只好给他限了一个长度300。结果收敛的特别慢。

如果o3y兄算的对的话,这个式子除以100000就是del_c_sharp兄那道题给定前十个数和n,第n项的估计最小值了。

除以100000以后还有几项能起作用啊。。。。。。。。
boodweb 2002-08-23
  • 打赏
  • 举报
回复
干吗不用Maple
八爪鱼-杭州 2002-08-23
  • 打赏
  • 举报
回复
up
tiantian335 2002-08-23
  • 打赏
  • 举报
回复
哦?
吃饭回来,结果都出来了?有代码吗?看看
孩皮妞野 2002-08-23
  • 打赏
  • 举报
回复
是你用GA进化的公式吧?

我看看。Bison用的不熟,否则会方便一点,有时间我硬编码写一个看看。
o3y 2002-08-23
  • 打赏
  • 举报
回复
23520 a1 - 1903 a10 - 120 a1 a2 + 10 a10 a2 - 16637 a4 -
27 a2 a4 + 23328 a5 - 120 a2 a5 + 26 a7 + 15520 a8 + 364 a2 a8 -
35 a9 - 44385 n - 83600 a1 n - 165 a10 n + 3 a2^2 n -
972 a3 n + 3 a2 a3 n - 684 a4 n + 9 a2 a4 n - 1894 a7 n -
6120 a8 n + 33 a2 a8 n + 1088 a9 n + 100020 n^2 - 54 a4 n^2 -
9 a2 a4 n^2 - 54 a7 n^2 + 54 a8 n^2 + 9 a2 a8 n^2 +
972 n^3 + 3 a2 n^3
Lawrence444 2002-08-23
  • 打赏
  • 举报
回复
帮我做出结果来。

有程序给我的话当然更好拉,可以考虑再加20分。
Lawrence444 2002-08-23
  • 打赏
  • 举报
回复
ALNG你知道这是哪来的表达式了吧。:-D
tiantian335 2002-08-23
  • 打赏
  • 举报
回复
你是要做结果吗? 还是最后是个表达式?我觉得要用stack来做,基本思路是: char item; ifstream inFile;
stack<char> expression;
inFile.get(item);
while( inFile )
{
while(
// 两个循环判断,第二个while里的判断,如果不是右括号,就一直读入stack,其中,当遇到括号时跳出,top stack中的数据,如果是与n 或数字,要做简单算术计算,如果遇到a[n]这种形式的,继续放到stack中,直到pop到第一个左括号时停止,再跳到外循环,继续读文件中的数据。
暂时想这么多吧,

去吃饭先~~
孩皮妞野 2002-08-23
  • 打赏
  • 举报
回复
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

推一下。

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧