#include<iostream.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>//定义函数atoi() itoa()
#include<ctype.h>//定义函数isdigit() isalpha()
#include<fstream.h>
#include<process.h>
#include<conio.h>
#include<stdio.h>
#pragma warning(disable : 4996)
using namespace std;
class Equ
{
private:
char equ[200];//方程
int n,numbers;//n为方程的阶次,numbers为方程的项数
char terms[100][40];//全局,放置每一项数
public:
Equ(char* );//新增函数,直接输入方程的构造
Equ();//新增函数,默认的构造
void InputEqu();//新增函数,从键盘输入方程
void InputEquFromFile();//新增函数,从输入文件输入方程
void quadraticequation(int a, int b, int c);//求解一元二次方程ax^2+bx+c=0
void getterm(char* src, char* dest, int&loc);/从字符串scr的第loc个字符起复制一个完整的项到dest字符串/
void getfactorsof(intfactor_list, int&num, int val);/将val项的整数因子放入数组factor_list中,共有num个/
void reduceequbyfactor(charbase, charnewequ, float factor);/降阶,base原方程,newequ新方程/
void gettermforpower(charequ, chardest, int power);//将阶数为power的项数复制到dest
int getcoeff(charterm);//返回一项的系数
int getdegreeofterm(charterm);//返回term这项的x的阶数
int remaindertheorem(charequ, float root);//判断root是否为方程解,不是返回1
int exp(int val, int e);//求解val的e次幂
float forallfactors(inta, intk, int n_a, int n_k, charequ);/将所有(常数项分解的因子/最高阶系数分解的因子)作为方程的解进行验证/
float exp(float, int);//求解val的e次幂
float calcequval(charequ, float val);//得出val带入x后该项的数值
float getcoeff_f(char* term);//取得一项的系数
void zero(char*);//求解0次方程
void one(int b, int c);//求解一次方程
void process();//新增函数,主要操作过程
};
void Equ::InputEquFromFile()//从文件输入
{
int i;
ifstream ins;//说明一个文件流对象ins
char equation[200];
cout << "请输入文件名: ";
cin >> equation;//输入文件名
ins.open(equation, ios::in);//打开文件
if (ins.fail())//文件不存在,终止函数的函数的运行
{
cerr << "该文件不存在!" << endl;
return;
}
else
{
ins.getline(equ, 10000);//从文件中读取数据,一次读100个字节
cout << "方程: " << equ << "的根为:";
int loc = 0;
char* e;e = equ;
if (strchr(e, 'x') != NULL)
{
if (strchr(e, '^') != NULL)
{
for (i = 0;e[i] != '^';i++);//跳过第一项系数、x和'^',找到'^'后的字符,即为阶数最高项的阶数
i++;
n = (int(e[i] - '0'));
}
else n = 1;//方程里没有字符'^',方程为1次
}
else n = 0;//方程中没有x,方程为0次
for (i = 0;i < (n + 1) && equ[loc] != '=' && equ[loc] != '\0' && equ[loc] != '\n';i++)//将方程的各项依次放入term所指向二维数组的各行中
getterm(equ, terms[i], loc);
numbers = i;//将方程的项数赋给numbers
ins.close();//关闭文件
}
}
void Equ::zero(chart)//求解0次方程
{
if (t[0] == '0' && t[1] == '\0')//若方程为0=0,解为全体实数
cout << "全体实数" << endl;
else cout << "无解" << endl;//若方程为一个非零常数等于零,无解
}
void Equ::one(int b, int c) //求解一次方程
{
cout << -(float)c / (float)b << endl;
}
Equ::Equ(char*fc)
{
int i;
strcpy(equ, fc);
int loc = 0;
char* e;
e = equ;
if (strchr(e, 'x') != NULL)
{
if (strchr(e, '^') != NULL)
{
for (i = 0;e[i] != '^';i++);//跳过第一项系数、x和'^',找到'^'后的字符,即为阶数最高项的阶数
i++;
n = (int(e[i] - '0'));
}
else n = 1;//方程里没有字符'^',方程为1次
}
else n = 0;//方程中没有x,方程为0次
for (i = 0;i < (n + 1) && equ[loc] != '=' && equ[loc] != '\0' && equ[loc] != '\n';i++)//将方程的各项依次放入term所指向二维数组的各行中
getterm(equ, terms[i], loc);
numbers = i;//将方程的项数赋给numbers
}
void Equ::process()//主要操作过程
{
char equ2[5000];
int loc = 0, a = 0, b = 0, c = 0, i, numterms = numbers;//把项数赋给numterms
int f_a[1000], f_k[1000], num_a, num_k;//把最高阶的系数放在数组f_a中,将常数项分解后放在f_k中
float result;//结果
if (n == 0) { zero(terms[0]);return; }//求解零次方程
if (n == 1) { one(getcoeff(terms[0]), getcoeff(terms[1]));return; }//求解一次方程
for (int z = n;z > 2;z--)
{
getfactorsof(f_a, num_a, getcoeff(terms[0]));//最高阶的系数放入f_a中,共num_a个
c = 0;
for (i = 1;i < numterms;i++)
if (getdegreeofterm(terms[i]) == 0)
c = getcoeff(terms[i]);//将常数项赋值给c
getfactorsof(f_k, num_k, c);//将常数项的整数倍数分解放入f_k中,共有num_k个
result = forallfactors(f_a, f_k, num_a, num_k, equ);//依次验证k/a是否为方程的解
if (result<0.0 && result>-0.05)//没有求出解,结束
{
cout << "\n无法求解!\n";
return;
}
reduceequbyfactor(equ, equ2, result);//降阶,equ为原方程,equ2为新方程
strcpy(equ, equ2);
loc = 0;
for (i = 0;i < (n + 1) && equ[loc] != '=' && equ[loc] != '\0' && equ[loc] != '\n';i++)//
getterm(equ, terms[i], loc);//将降阶后的方程的各项依次放入terms的各行
numbers = i;//将方程的项数赋给numbers
}
b = c = 0;
for (i = 1;i < numterms;i++)
if (getdegreeofterm(terms[i]) == 1)
b = getcoeff(terms[i]);//b为x一次项的系数
for (i = 1;i < numterms;i++)
if (getdegreeofterm(terms[i]) == 0)
c= getcoeff(terms[i]);//c为常数项
quadraticequation(getcoeff(terms[0]), b, c);//求解一元二次方程
cout << endl;
}
void Equ::quadraticequation(int a, int b, int c)
{
if ((b * b - 4 * a * c )< 0)//当b*b-4*a*c<0时,解为虚根
{
cout << (-b) / (2 * a) << "+i*" << sqrt(4 * a * c - b * b) / (2 * a)<<" ";
cout << (-b) / (2 * a) << "-i*" << sqrt(4 * a * c - b * b) / (2 * a);
}
else {
if ((b * b - 4 * a * c) == 0) //有两个相等的根
{
cout << (-b / (2.0 * a)) << " ";
cout << (-b / (2.0 * a));
}
else//有两个不等的根
{
cout << ((-b + sqrt(b * b - 4 * a * c)) / (2 * a)) << " ";
cout << ((-b - sqrt(b * b - 4 * a * c)) / (2 * a)) << " ";
}
}
}
void Equ::getterm(char* src, char* dest, int& loc)//从字符串scr的第loc个字符起复制一完整的项到字符串dest
{
int loc2 = 0;
if (src[loc] == '-') {
dest[loc2] = '-';//系数前有负号
loc2++;
}
for (;src[loc + loc2] != '+' && src[loc + loc2] != '-' && src[loc + loc2] != '\n' && src[loc + loc2] != '\0' && src[loc + loc2] != '=';loc2++)
dest[loc2] = src[loc + loc2];//将一完整的项复制到目的字符串
dest[loc2] = '\0';//字符串以0结尾
loc += loc2;//起始字符的位置跳过赋过值的项
if (src[loc] != '-' && src[loc] != '\0')
loc++;//若该项后面是+号,则跳过下一项
}
void Equ::getfactorsof(int* factor_list, int& num, int val)//将val项的整数因子放入数组factor_list中,有num项,并返回整数因子表factor_list
{
int fcount = 0;
num = 0;
val = abs(val);//求val的绝对值
for (int i = 1;i <= val;i++)
if ((float)((float)((float)val / (float)i) - (int)((float)val / (float)i)) == 0.0f)//判断val能否被i整除
num++;
for (int i = 1;i <= val;i++)
if ((float)((float)((float)val / (float)i) - (int)((float)val / (float)i)) == 0.0f)
{
factor_list[fcount] = i;//若val能够被i整除,则将i放入factor_list中
fcount++;
}
}
int Equ::getcoeff(char* term)//返回一项的系数
{
int i;
char* temp;
int mult = 1;
if (term[0] == '\0')
return 0;
temp = (char*)malloc(strlen(term));
for (i = 0;term[i] == ' ';i++);//删除字符串前的空格
if (term[i]== '-')//如果第一个字符为’-‘,表示该项系数为负
{
mult = -1;
i++;
}
for (;!isdigit(term[i]) && !isalpha(term[i]);i++);//忽略其前不是字母或与数字无意义的字符
if (isalpha(term[i]))//如果碰到字母,返回1
return mult;
for (int j = 0;isdigit(term[i + j]);j++)//如果是数字字符,将连续的数字放入字符串temp
temp[j] = term[i + j];
return atoi(temp) * mult;//返回其所代表的数值与符号的乘积
}
float Equ::getcoeff_f(char* term) //取得一项的系数,系数为实数就返回实数
{
char* temp;
int i;
int mult = 1;
if (term[0] == '\0')//若这项为空.则返回0
return 0.0f;
temp = (char*)malloc(strlen(term));
for (i = 0;term[i] == ' ';i++);//删除字符串前的空格
if (term[i] == '-')//如果第一个字符为’-‘,表示该项系数为负
{
mult = -1;
i++;
}
for (;!isdigit(term[i]) && !isalpha(term[i]);i++);//忽略其前不是字母或与数字无意义的字符
if (isalpha(term[i]))//如果碰到字母,返回-1
return (float)mult;
for (int j = 0;isdigit(term[i + j]);j++)//如果是数字字符,将连续的数字放入字符串temp
temp[j] = term[i + j];
return(float)atof(temp) * (float)mult;//返回其所代表的数值与符号的乘积
}
int Equ::getdegreeofterm(char* term)//返回term这项的x的阶数
{
int i;
if (strchr(term, 'x') != NULL) //判断term中是否有x
{
if (strchr(term, '^') != NULL)//判断term中是否含有'^'
{
for (i = 0;term[i] != '^';i++);//指针移到后面,看看该项是x的多少阶
i++;
return(int(term[i]) - '0'); //字符转化为整数,即为阶数
}
else
return 1;//若有x而无'^',返回1
}
else
return 0;//若无x返回0
return -1;//出错返回-1
}
int Equ::remaindertheorem(char* equ, float root)//判断root是否为方程的解,不是返回1
{
int i;
char terms[100][40];
float* val = new float[n+1], totoalval = 0.0f;
int loc = 0;
for ( i = 0;i < (n+1) && equ[loc] != '=' && equ[loc] != '\0' && equ[loc] != '\n';i++)
getterm(equ, terms[i], loc);//将x的各阶项数取到term[i]中
int numterms = i;//numterms为x的最高阶次
for (i = 0;i < numterms;i++)
{//求出root为解时这一项的数值
val[i] = calcequval(terms[i], root);//将各项值相加
totoalval += val[i];
}
if (totoalval * 1.0f > -0.002f && totoalval * 1.0f < 0.002f)//各项值之和在-0.002到0.002之间,近似为0,认为root即为方程的解
return 0;
else return 1;//root不是方程的解,返回1
}
int Equ::exp(int val, int e)//求解val的e次幂,val为整数
{
int v2 = val;
if (e == 0)
return 1;
for (int i = 1;i < e;i++)
v2 *= val;
return v2;
}
float Equ::exp(float val, int e)//求解val的e次幂,val为实数
{
float v2 = val;
if (e == 0)
return 1.0f;
for (int i = 1;i < e;i++)
v2 *= val;
return v2;
}
float Equ::calcequval(char* equ, float val)//得出val代入x后该项的数值
{
int coeff = getcoeff(equ);//取得某一项的系数
int power = getdegreeofterm(equ);//取得该项的阶数
return coeff * exp(val, power);//返回val为解时该项的值
}
void Equ::reduceequbyfactor(char* base, char* newequ, float factor)//降阶
{
int i;
float *synthterms = new float[n+1];
int *newterms = new int[n+1];
for (int w = 0;w <= n;w++) { synthterms[w] = 0.0f;newterms[w] = 0; }
int j = 0, olddegree;
char temp[50] =" ", exp[10] =" ", tempterms[100][40];
if (remaindertheorem(base, factor))//如果factor不是方程的根,返回
return;
olddegree = getdegreeofterm(terms[0]);//旧的阶数
for (int i =0;i <= olddegree;i++) {
gettermforpower(base, temp, i);//将原方程各阶项数复制到temp中,i为该项阶数
synthterms[i] = getcoeff_f(temp);//将各阶系数赋值到synthterms中
}
newterms[n-1] = (int)synthterms[n];//最高项系数降阶
for (i = n-1;i >= 1;i--)
newterms[i - 1] = (int)((float)(newterms[i] * factor + synthterms[i]));
for (i = n-1;newterms[i]==0;i--);
strcpy(newequ, "");//准备赋新的项数
for (;i >= 0;i--) {
if (newterms[i] != 0) {
if (i == 0) strcpy(exp, "");
else if (i == 1) strcpy(exp, "x");
else {
exp = 'x';(exp + 1) = '^';
(exp + 2) = (char)(i + '0');
(exp + 3) = '\0';
}//将x^i放到exp中
char s[200];
if (newterms[i] != 1) {
if (newterms[i] < 0)//系数为负,把系数给tempterms
{
strcpy(tempterms[i],itoa(newterms[i], s, 100));
strcat(tempterms[i],exp);//系数与tempterms拼接起来,形成完整的一项
}
else {
if (i < olddegree - 1) //拼接完整的一项
{
strcpy(tempterms[i],"+");
strcat(tempterms[i],itoa(newterms[i],s,100));
strcat(tempterms[i], exp);
}
else//拼接最后一项
{
strcpy(tempterms[i], itoa(newterms[i], s, 100));
strcat(tempterms[i], exp);
}
}
}
else //系数小于0,拼接完整的一项
{
if (newterms[i] < 0)
strcpy(tempterms[i],exp);
else {
if (i < olddegree - 1) {
strcpy(tempterms[i], "+");
strcat(tempterms[i], exp);
}
else
strcpy(tempterms[i], exp);
}
}
if (newterms[i] == 1 && exp[0] == '\0') {
if (newterms[i] > 0)
{
strcpy(tempterms[i], "+");
strcat(tempterms[i], itoa(newterms[i], s, 100));
}
else
strcpy(tempterms[i],itoa(newterms[i], s, 100));
}
strcat(newequ, tempterms[i]);//将新的项数依次输入到newequ字符串中
}
}
}
void Equ::gettermforpower(char equ, char dest, int power)//将阶数为power的项数复制到dest
{
int i;
for (i = 0;i < n+1;i++)
if (getdegreeofterm(terms[i]) == power)//将power的项数复制到dest
{
strcpy(dest, terms[i]);
return;
}
strcpy(dest, "0");//没有阶数为power的项,则dest为空}
float Equ::forallfactors(int a, int* k, int n_a, int n_k, char* equ)//验根
{
for (int i = 0;i < n_a;i++)//将所有常数项分解的因子或最高阶系数分解的因子代入方程
for (int j = 0;j < n_k;j++) {
if (remaindertheorem(equ, (float)((float)k[j] / (float)a[i])) == 0)
{
float r =(float) k[j] /(float) a[i];//如果是方程的解,输出
cout<<r<<" ";
return (float)r;//返回这个解
}
if (remaindertheorem(equ, (float)((float)k[j] / (float)a[i]) *( - 1.0f)) == 0)
{
float r = -(float)k[j] / (float) a[i];
cout<<r<<" ";
return (float)r;
}
}
if (remaindertheorem(equ, 0.0f) == 0) {//如果0是方程的根,输出并返回0
cout << "0" << " ";
return 0.0f;
}
return -0.0001f;//没有求出解,返回
}
void main()
{
cout << "请选择所需要的操作:\n";
char ch;
int y;
do
{
y =1;
cout << "键盘读取方程请按1" << endl;
cout << "文件读取方程请按2" << endl;
cout << "确认退出程序请按3" << endl;
cin.get(ch);//用于存放输入的字符
cin.ignore(80, '\n');
switch (ch)//用于控制do-while
{
case'1':
{
cout << "请输入方程:";
char A[2000];
cin.getline(A, 2000);
if (strlen(A) == 0)
{
cout << "没有方程!\n";
cout << "输入‘enter’键继续";
cin.ignore(800, '\n');
break;
}
Equ FC(A);
cout << "方程的根为:";
FC.process();
cout << "输入'enter'键继续";
cin.ignore(80, '\n');
break;
}
case'2':
{
char B[12] = "\0";
Equ FC(B);
FC.InputEquFromFile();
FC.process();
cout << "输入'enter'键继续";
cin.get();
cin.ignore(80, '\n');
break;
}
case '3':
{
y = 0;
cout << "确认退出程序";
break;
}
default:
cout << "输入错误";
}
} while (y != 0);
}
你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答
本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。
因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。