#include <string>
#include <iostream>
#include <vector>
using namespace std;
#define SIN_FN 1
#define COS_FN 2
class Expression
{
public:
Expression();
Expression(int fn, const string* args, int n_args);
void varVecToString(string& out);
void varComboToString(string& out);
void toString(string& out, bool omit_positive_sign);
Expression* calculate();
public:
bool is_positive;
struct Var
{
int fn;
string name;
};
vector<Var> var_vec;
int combo_fn;
vector<string> var_combo;
Expression* prev;
Expression* next;
protected:
void varToString(int i, string& output);
};
static string* s_sin_prefix = NULL;
static string* s_cos_prefix = NULL;
int main()
{
s_sin_prefix = new string("sin");
s_cos_prefix = new string("cos");
string str;
int fn;
int n_args;
string* args = NULL;
// read the function
retry_fn:
cout<<">> Please input function c(cos) or s(sin): "<<endl;
cin>>str;
if (str.length() == 0
|| (str[0] != 'c' && str[0] != 's'))
goto retry_fn;
fn = str[0] == 'c' ? COS_FN : SIN_FN;
// read number of args
retry_args:
cout<<">> Please input number of args : "<<endl;
cin>>n_args;
if (n_args <= 0)
goto retry_args;
// init the arguement names
args = new string[n_args];
for (int i = 0; i < n_args; i++)
{
char buf[16];
sprintf(buf, "A%d", i + 1);
args[i] = buf;
}
Expression* exp = new Expression(fn, args, n_args);
string output;
exp->toString(output, true);
cout<<output<<endl;
bool expanded = false;
while (true)
{
Expression* p = exp;
while (p != NULL)
{
Expression* new_exp = p->calculate();
if (new_exp != NULL)
{
expanded = true;
break;
}
p = p->next;
}
if (!expanded)
break;
p = exp;
while (p != NULL)
{
p->toString(output, p == exp);
cout<<output;
p = p->next;
}
cout<<endl;
expanded = false;
}
delete []args;
return 1;
}
Expression::Expression():next(NULL), prev(NULL)
{
}
Expression::Expression(int fn, const string* args, int n_args):next(NULL), prev(NULL)
{
is_positive = true;
combo_fn = fn;
int i = 0;
while (i < n_args)
{
var_combo.push_back(args[i]);
i++;
}
}
void Expression::varToString(int i, string& output)
{
output.clear();
if (i >= var_vec.size())
return;
int fn = var_vec[i].fn;
output = (fn == SIN_FN ? *s_sin_prefix : *s_cos_prefix);
output += var_vec[i].name;
}
void Expression::varVecToString(string& output)
{
output.clear();
if (var_vec.size() > 0)
{
string tmp;
for (int i = 0; i < var_vec.size() - 1; i++)
{
varToString(i, tmp);
output += (tmp + "*");
}
varToString(var_vec.size() - 1, tmp);
output += tmp;
}
}
void Expression::varComboToString(string& output)
{
output.clear();
if (var_combo.size() == 1)
{
output = (combo_fn == SIN_FN ? *s_sin_prefix : *s_cos_prefix);
output += var_combo[0];
}
else
{
output = (combo_fn == SIN_FN ? *s_sin_prefix : *s_cos_prefix);
output += "(";
for (int i = 0; i < var_combo.size() - 1; i++)
output += (var_combo[i] + "+");
output += (var_combo[var_combo.size() - 1] + ")");
}
}
void Expression::toString(string& out, bool omit_positive_sign)
{
string tmp;
out.clear();
if (!is_positive)
out = " - ";
else if (is_positive && !omit_positive_sign)
out = " + ";
varVecToString(tmp);
out += tmp;
if (var_vec.size() > 0)
out += "*";
varComboToString(tmp);
out += tmp;
}
Expression* Expression::calculate()
{
if (var_combo.size() == 1)
return NULL;
Var var;
Expression* new_exp = new Expression();
if (next != NULL)
next->prev = new_exp;
new_exp->prev = this;
new_exp->next = next;
next = new_exp;
new_exp->is_positive = is_positive;
new_exp->var_vec = var_vec;
new_exp->var_combo = var_combo;
if (combo_fn == SIN_FN)
{
var.fn = COS_FN;
var.name = var_combo[0];
new_exp->var_vec.push_back(var);
new_exp->combo_fn = SIN_FN;
new_exp->var_combo.erase(new_exp->var_combo.begin());
combo_fn = COS_FN;
var_combo.erase(var_combo.begin());
var.fn = SIN_FN;
var_vec.push_back(var);
}
else
{
new_exp->is_positive = !(new_exp->is_positive);
var.fn = SIN_FN;
var.name = var_combo[0];
new_exp->var_vec.push_back(var);
new_exp->combo_fn = SIN_FN;
new_exp->var_combo.erase(new_exp->var_combo.begin());
combo_fn = COS_FN;
var_combo.erase(var_combo.begin());
var.fn = COS_FN;
var_vec.push_back(var);
}
return new_exp;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 我用GCC编译的,你试试你的编译器能不能通过,另外自己根据需要改main函数
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
温馨提示:答案为网友推荐,仅供参考