如何在 C++ 中实现科学计算器






4.63/5 (20投票s)
关于使用编程语言进行数学实现的基本概述
目录
- 摘要
- 引言
- 数学问题的编码
- 输入的广泛可能性
- 输入公式应符合数学标准规则
- 输入公式的长度
- 实现概述
- Data 类
- MyChecker 类
- MyFixer 类
- Calculator 类
- 用户指南
- 附录
- 链表
- 结论
1. 摘要
您是否曾尝试在程序中输入上面的公式,但发现计算起来很困难?您是否曾因为需要使用复杂的公式而停止编写程序,因为您的编程语言中没有计算它们的方法?您是否曾为了使用某些数学功能而转向使用 FORTAN 或 MATLAB 等语言,但同时,如果您能在您的主要语言中使用这些功能,您可能会编写出更好的程序?
如果您是其中一员,那么这篇文章可能对您很有帮助,因为它提供了两个问题的解决方案;一个是关于如何编写数学程序,另一个是 C++ 的一个头文件,您可以使用它来计算如图 1 所示的公式,从而简化您的创意 C++ 程序。
2. 简介
数学编程与附属编程语言一起,是任何编程语言的支柱,也是使用计算机最重要的原因之一。这是因为世界上几乎所有的科学都依赖于数学。因此,需要更简单的方法来处理数学,这仍然是当今最受需求的,并且将一直存在直到世界末日。所以,从这个角度出发,我们正在致力于实现一个我编写的科学计算器,在接下来的几天里,您也可以用您自己的方式编写,除非您不想这样做。
在 C++ 中,有一些处理数学的库,如 math.h 和 c math,但这些库并不提供您所需的所有运算,然而,它们是我们实现的基础。3. 数学问题的编码
在编写数学程序时,您会遇到所有程序员都曾经遇到过的一些问题。我将这些问题放在您手中,以便您注意。您可能不会将这些看作是问题,但它们是我在编码过程中遇到一些困难的原因。您可能会发现
3.1. 输入的广泛可能性
您可能遇到的第一个问题是输入的广泛可能性。您不知道用户会给您什么输入,所以您应该首先确定您的程序将处理哪种数学,并确保您的用户不会输入超出范围的内容,尤其是在您接收的输入是字符串或流,或者您通过控制台界面接收输入时。为了解决这个问题,您应该先检查输入,然后逐步对输入执行操作,例如
- 您的程序是否只处理带有简单运算符 (+,-,/,*) 的公式?
- 或者您的程序会处理带有括号的交集运算符?
- 或者您的程序会处理三角函数 (sin, cos, . . . )?
- 随着您的进展,您应该首先确定您将依赖的领域,然后开始。
3.2. 输入公式符合数学标准规则
您可能遇到的第二个问题是,用户可能会输入缩写的公式,例如 2x 表示 2*x,或者 2(sin(45)) 表示 2*sin(45),或者 2++++++x,而您的程序被设计成只处理一个运算符等。
所以您应该首先编辑输入公式,使其适合您的程序,然后将其发送给您的函数。
3.3. 输入公式的长度
您可能遇到的第三个问题是输入长度,因为用户可能会输入长短不一的公式。在这种情况下,您有两个解决方案:第一个是使用一个长数组,它可以读取任何长度的输入公式,但在我看来这是一个糟糕的解决方案,因为它会浪费内存,即使用户输入的是一个很小的公式。在我看来,最好的解决方案是使用计数器,它依赖于链表(参见附录),因为它只在需要时分配内存,所以您不会分配超出您需求的内存。在这种情况下,我使用向量。
4. 实现概述
4.1. Data 类
Data
类是我实现中的容器类。在这个类中,我放置了程序所需的主要库以及我将用作辅助函数的 public
方法,例如
double charVtod (vector<char>ch)
函数将输入公式中的double
数字转换为double
数字double getNum (vector<char> &form, int &orderm, int &digit);
从输入公式中读取一个数字unsigned getDigits(long num);
计算一个长数字的位数vector<char> dtoVchar (double num);
将double
数字转换为字符向量
class Data
{
protected:
int temp; //temperature variable
char tempChar; //temperature char
bool hasVar; //checking for variables
double charVtod (vector<char>ch); //convert from vector of character to double
//reading a number from vector and return its digit's count int digit by reference
double getNum (vector<char> &form, int &orderm, int &digit);
unsigned getDigits(long num); //return the digits number of a long num
//convert double to vector
vector<char> dtoVchar (double num);
};//end data
4.2. MyChecker 类
MyChecker
类用于检查输入公式是否符合我的程序数学覆盖范围,例如,如果用户输入了错误的公式;该类应该提醒他,例如错误的输入,如
x**x ,si(45), /52312, 等等...
关于函数
inline bool isOp(char &ch);
用于检查普通运算符 +, -, *, /b-bool isVar(vector<char>vars,char &ch);
用于检查变量bool _check (vector<char> &ch, vector<char>vars);
是使用其他类函数来检查输入公式的函数bool isTriangle (vector<char> &ch , int &temp);
用于检查三角函数的函数。bool editSigns (vector<char> &ch);
用于编辑符号的函数,例如 ++ 变为 +,-+ 变为 -,等等。bool check(vector<char>form, char mainVar );
用于检查带有一个变量的输入公式的函数,该变量由另一个参数mainVar
读取,例如 2x + 2,而mainVar
= 'x'bool check(vector<char>form, vector<char>vars);
用于检查带有多个变量的输入公式的函数,这些变量由向量vars
读取,例如 2x+3y
class MyChecker : public Data
{
private:
inline bool isOp(char &ch);
bool isVar(vector<char>vars,char &ch);
//check trigonometric functions
bool _check (vector<char> &ch, vector<char>vars); //checker function
protected:
bool isTriangle (vector<char> &ch , int &temp);
bool editSigns (vector<char> &ch);
bool check(vector<char>form, char mainVar ); //check with formulas
bool check(vector<char>form, vector<char>vars); };//check with formulas and variables
4.3. MyFixer 类
MyFixer
类是其主要职责是编辑公式以使公式能够适应我的程序和下一个类calculator 的类,例如:如果输入是xx,则在它们之间插入*,结果变为x*x;此函数只有两个函数;其中一个函数调用另一个函数
void fix(vector<char> &ch);
此函数由其他子类调用,接收公式并将其发送给另一个函数。void _fix (vector<char> &ch);
此函数由类函数调用,并执行所需的编辑。
class MyFixer : public MyChecker
{
protected:
void fix(vector<char> &ch);
private:
int temp;
void _fix (vector<char> &ch);
};//end MyFixerer
4.4. Calculator 类
Calculator
类是这个程序的主干,这个类的函数是用于计算公式的函数;通过探索它的函数
firstRank
、secondRank
和 thirdRank
是将公式划分为三个阶段的函数
第一个与幂函数和三角函数相关,第二个是 * 和 / 运算,第三个是 + 和 - 运算,同时考虑 getBorder
函数用于确定计算进行的括号范围,然后将其删除。
该类有 6 个重载的 calc
函数,用于处理三种情况:接收字符向量、数组和字符串;函数 _calc
最终是接收来自六个重载函数的公式,然后执行计算的函数。
class Calculator : public MyFixer
{
private:
int str, end, // sub calculation borders
//depending on brackets
digit,digit1,digit2, //get number digit
temp, temp1; //temperature variable
vector<char> charNum;
double num, num1, num2; //storing double number bool final; //final time do mathematics
double getCaclNum (vector<char> &form, int &order, int &count);
void getBorder (vector<char> &form);
void firstRank (vector<char> &form); //trigonometric and power
void secondRank (vector<char> &form); //do multiplying and division
void thirdRank (vector<char> &form); //summing and subtracting
vector<char> _calc (vector<char> formula);
vector<char> strToVector (string form);
vector<char> charToVector(char form [] );
public:
Calculator () :final(false){}
double calc (vector<char> formula);
double calc(char formula []);
double calc(string formula );
double calc (vector<char> formula, char var, double varValue);
double calc (char formula [], char var, double varValue);
double calc (string formula , char var, double varValue);
};//end calculator
5. 用户指南
现在我们来看如何使用这些类
- 首先,您需要在您的程序中包含这些类
- 在您的 cpp 文件中包含 calculator.h 文件
- 从
calculator
类创建一个对象 - 使用六个重载的
calc
函数之一
例如,如果您想从用户那里获取一个带有一个变量的函数,然后获取该变量的值并打印结果,代码将如下所示
#include "Calculator.h"
#include <string>
using namespace std;
void main ()
{
Calculator c1; //object of Calculator
string form; //reading formula in
char var; //reading variable
double value; //reading variable value
while(true)
{
cout<<"Please, enter your formula:";cin>>form;
cout<<"enter your variable:";cin>>var;
cout<<"Enter "<<var<<" value:";cin>>value;
cout<<"result = "<<c1.calc(form, var, value)<<endl;
getche();
system("cls");
}
}//end main
结果将如图 2 所示
稍后,您可以在更复杂的程序中使用它。
6. 附录
6.1. 链表
在计算机科学中,链表1 是一种数据结构,由一组节点组成,这些节点共同表示一个序列。在最简单的形式下,每个节点包含一个数据和一个指向序列中下一个节点的引用(换句话说,一个链接);更复杂的变体会添加额外的链接。这种结构允许在序列的任何位置高效地插入或删除元素。
7. 结论
本文旨在为您提供编写科学计算器的思路,但并非包罗万象。这个领域非常广泛,有很多研究,但我希望这篇文章能帮助您入门。祝您一切顺利!