求用C++语言实现cos(α1+α2+α3+……+αn) = 和sin(α1+α2+α3+……+αn) =的分解

cos(α+β) = cosαcosβ- sinαsinβ, sin(α+β) = sinαcosβ+ cosαsinβ
cos(α+β+γ) = cos(α+(β+γ)) = cosαcos(β+γ) - sinαsin(β+γ) =cosαcosβcosγ-cosαsinβsinγ- sinαsinβcosγ- sinαcosβsinγ,
sin(α+β+γ) = sin(α+(β+γ)) = sinαcos(β+γ) + cosαsin(β+γ) =sinαcosβcosγ-sinαsinβsinγ+ cosαsinβcosγ+ cosαcosβsinγ

#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函数
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
温馨提示:答案为网友推荐,仅供参考
第1个回答  2011-04-20
CString fcos(const CString ab)
{
CString a,b;
int loc;

loc = ab.Find('+');
if(loc==-1)
return CString("cos") + ab;
else
{
a = ab;
b = ab;
a = a.Left(loc);
b.Delete(0,loc+1);
return fcos(a) + "*" + fcos(b) + "-" + fsin(a) + "*" + fsin(b);
}
}
CString fsin(const CString ab)
{
CString a,b;
int loc;

loc = ab.Find('+');
if(loc==-1)
return CString("sin") + ab;
else
{
a = ab;
b = ab;
a = a.Left(loc);
b = b.Delete(0,loc+1);
return fsin(a) + "*" + fcos(b) + "-" + fcos(a) + "*" + fsin(b);
}
}
main()
{
CString str;
str = fcos("A+B+C");
}