1
已解决
王梓轩
资深光能
资深光能
谁能改成有括号的?
#include<bits/stdc++.h>
#include<windows.h>
#include<mmsystem.h>
#include<locale.h>
#include<direct.h>
#include<tchar.h>
#include<conio.h>
#pragma GCC optimize(3)
#pragma GCC target("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC optimize(2)
#pragma comment(lib,"winmm.lib")
#define KEY_DOWN(VK_NONAME)((GetAsyncKeyState(VK_NONAME)&0x8000)?1:0)
#define _CRT_SECURE_NO_WARNINGS
using namespace std;
/*函数提前声明*/
/*-----------------------------*/
string PLUS(string,string);
string MINUS(string,string);
string MUL(string,string);
string DIV(string,string,int);
bool bijiao(string,string);
bool judge(string);
/*-----------------------------*/
string PLUS(string a,string b)//高精度加法
//循环次数≈a.size()*1.5
{
string c="";//结果
int flag=0;//负数标志
if(a[0]=='-'&&b[0]=='-')
flag=1,a.erase(0,1),b.erase(0,1);//都是负数,去除'-',答案加上'-'
if(b[0]=='-'&&a[0]!='-')swap(a,b);//对下一步预处理
if(a[0]=='-'&&b[0]!='-')//一个是负数,一个不是
{
a.erase(0,1);//去掉'-'
if(a==b)return "0";//相等为0
return bijiao(a,b)?'-'+MINUS(a,b):MINUS(b,a);//判断大小做减法
}
int carry=0;//进位+a[i]+b[j]
//没有使用逆序,时间复杂度优化
for(int i=a.size()-1,j=b.size()-1; i>=0||j>=0; i--,j--)//i遍历a,j遍历b
{
if(i>=0)carry+=a[i]-'0';//加a[i]
if(j>=0)carry+=b[j]-'0';//加b[j]
c+=carry%10+'0';//加上末位,其余进位
carry/=10;//去掉最后一位,下次进位
}
if(carry)c+=carry%10+'0';//还能进一位
if(flag)c+='-';//负数
for(int i=0; i<c.size()/2; i++)swap(c[i],c[c.size()-1-i]);//优化逆序
return c;//返回值
}
/*-----------------------------*/
string MINUS(string a,string b)//高精度减法
//循环次数:a.size()*2
{
int flag=0;//负数标志
if(a==b)return "0";//结果为0的特判
if(b[0]=='-')//b是负数,跳转至加法
{
b.erase(0,1);//去掉b的'-',做加法
return PLUS(a,b);//加法
}
if(a[0]=='-'&&b[0]!='-')//a是负数,b不是负数
{
a.erase(0,1);//去掉a的'-',做加法
return '-'+PLUS(a,b);//结果必定为负数
}
if((a.size()==b.size()&&a<b)||a.size()<b.size())
swap(a,b),flag=1;//a比b小,交换,标记结果负数
int carry;//每一位
string c="";
for(int i=a.size()-1,j=b.size()-1; i>=0||j>=0; i--,j--)//i遍历a,j遍历b
{
carry=0;
if(i>=0)carry+=a[i];//防止某一个变量<0
if(j>=0)carry-=b[j]-'0';//防止某一个变量<0
if(carry<'0')a[i-1]--,carry+=10;//结尾(若a[i-1]=='0',也没有问题,'0'-1-'0'==-1)
c+=carry;//c加上这一位
}
while(c[c.size()-1]=='0'&&c.size()>0)c.erase(c.size()-1,1);//去除前缀0
if(flag)c+='-';//负数
for(int i=0; i<c.size()/2; i++)swap(c[i],c[c.size()-1-i]);//优化逆序
return c;//返回值
}
/*-----------------------------*/
string MUL(string a,string b)//高精度乘法
//循环次数:a.size()*b.size()+a.size()+b.size()
{
string ans="";//结果
int flag=0;
if(a[0]=='-'&&b[0]!='-')flag=1,a.erase(0,1);//a是负数,b不是
if(b[0]=='-'&&a[0]!='-')flag=1,b.erase(0,1);//b是负数,a不是
if(a[0]=='-')a.erase(0,1);//去a的'-'
if(b[0]=='-')b.erase(0,1);//去b的'-'
short c[1000005]= {0};//数位用short(-32768~32767)
int k=a.size()+b.size()+1;//结果位数最大
for(int i=a.size()-1; i>=0; i--)//双重循环遍历,不使用逆序,优化时间复杂度
for(int j=b.size()-1; j>=0; j--)
{
int iplusj=a.size()-i-1+b.size()-j-1;//过程较复杂,提前存好
c[iplusj]+=(a[i]-'0')*(b[j]-'0');//逐位相乘
c[iplusj+1]+=c[iplusj]/10;//进位
c[iplusj]%=10;//保留个位
}
while(c[k]==0&&k>=0)k--;//去除前缀0
while(k>=0)ans+=c[k--]+'0';//结果
if(flag)return '-'+ans;//负数
return ans;//无负数
}
bool bijiao(string a,string b)
{
if(a.size()>b.size()||a.size()==b.size()&&a>=b)return 1;//比较大小
return 0;
}
string DIV(string a,string b,int x)//高精度除法
{
if(b=="0")exit(0);//除数为0,这里使用c语言的退出程序
int flag=0,flagg=0;//负数
string c;//商
if(a[0]=='-')a.erase(0,1),flag=1,flagg=1;//a是负数
if(b[0]=='-')//b是负数
{
b.erase(0,1);//删除'-'
if(flag==1)flag=0;//取反
else flag=1;//取反
}
int t=b.size();//b的初始长度
for(int i=b.size(); i<a.size(); i++)b+='0';//把b的位数变得和a一样大
while(t<=b.size())//b不能改变本身
{
int s=0;//该位的值
while(bijiao(a,b))//a必须比b大
{
a=MINUS(a,b);//做减法
s++;//这一位+1
}
b.erase(b.size()-1,1);//删除b的最后一位(0)
c+=s+'0';//c加上这一位
}
while(c[c.size()-1]=='0'&&c.size()>1)c.erase(c.size()-1,1);//去除前缀0
if(x==1)//取商
{
if(flag)return '-'+c;//负数
return c;//结果
}
else//取余数
{
if(flagg)return '-'+a;//负数
return a;//结果
}
}
bool judge(string a)//判断表达式合法(该区域有BUG,无法判断括号是否正常,此代码不会计算括号)
{
for(int i=1; i<a.size()-1; i++)//遍历表达式
{
if(isdigit(a[i])||//数字
((a[i]=='('&&//左括号
isdigit(a[i+1])&&
(a[i-1]=='+'||
a[i-1]=='-'||
a[i-1]=='*'||
a[i-1]=='/'||
a[i-1]==' ')&&isdigit(a[i+1]))||
(a[i]==')'&&
(a[i+1]=='+'||
a[i+1]=='-'||
a[i+1]=='*'||
a[i+1]=='/'||
a[i+1]==' ')&&isdigit(a[i-1]))))continue;//数字或者符号,合理
else if(a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/')//符号且有数字在两边,合理
if((isdigit(a[i-1])||a[i-1]==')')&&(isdigit(a[i+1])||a[i+1]=='('))continue;
else if((a[i]=='+'||a[i]=='-'||a[i]=='*'||a[i]=='/')&&a[i+1]=='-')//负数,合理
{
i++;
continue;
}
else if(a[i]=='-'&&i==1)continue;//开头负数,合理
return 0;//不合理
}
for(int i=1; i<a.size()-1; i++)
if(a[i]=='(')
{
int flag=0;
for(int j=a.size(); j>=i+1; j--)
{
if(a[j]==')')
{
flag=1;
if(!judge(a.substr(i+1,j-1)))return 0;
}
}
if(flag==0)return 0;
}
return 1;
}
void clearbug(string a)//把所有--删除
{
for(int i=1; i<a.size()-2; i++)if(a[i]=='-'&&a[i+1]=='-')a.erase(i,2);
}
string wkhbds(string a)//无括号表达式的计算
{
for(int i=1; i<a.size()-1; i++)//遍历
{
if(a[i]=='*')//乘法
{
//字符串模拟
/*-------------------------------------*/
int begin,end;
for(int j=i-1; j>=1; j--)
if((isdigit(a[j])||a[j]=='-')&&(a[j-1]=='+'||a[j-1]=='-'||a[j-1]=='*'||a[j-1]=='/'||a[j-1]==' '))
{
begin=j;
if(isdigit(a[j])&&(a[j-2]=='+'||a[j-2]=='-'||a[j-2]=='*'||a[j-2]=='/'||a[j-2]==' '))begin=j-1;
break;
}
for(int j=i+1; j<=a.size()-1; j++)
if(isdigit(a[j])&&(a[j+1]=='+'||a[j+1]=='-'||a[j+1]=='*'||a[j+1]=='/'||a[j+1]==' '))
{
end=j;
break;
}
/*-------------------------------------*/
string z=a.substr(begin,i-begin),y=a.substr(i+1,end-i);//两个乘数
a.erase(begin,end-begin+1);//删除两个数的表达式
a.insert(begin,MUL(z,y));//换成结果
i=begin;//将i设为begin,继续遍历
clearbug(a);//删除所有--
// cout<<a.substr(1,a.size()-2)<<endl;
}
if(a[i]=='/')//除法,注释略
{
int begin,end;
for(int j=i-1; j>=1; j--)
if((isdigit(a[j])||a[j]=='-')&&(a[j-1]=='+'||a[j-1]=='-'||a[j-1]=='*'||a[j-1]=='/'||a[j-1]==' '))
{
begin=j;
if(isdigit(a[j])&&(a[j-2]=='+'||a[j-2]=='-'||a[j-2]=='*'||a[j-2]=='/'||a[j-2]==' '))begin=j-1;
break;
}
for(int j=i+1; j<=a.size()-1; j++)
if(isdigit(a[j])&&(a[j+1]=='+'||a[j+1]=='-'||a[j+1]=='*'||a[j+1]=='/'||a[j+1]==' '))
{
end=j;
break;
}
string z=a.substr(begin,i-begin),y=a.substr(i+1,end-i);
a.erase(begin,end-begin+1);
a.insert(begin,DIV(z,y,1));
i=begin;
clearbug(a);
// cout<<a.substr(1,a.size()-2)<<endl;
}
}
for(int i=1; i<a.size()-1; i++)//加减法,注释略
{
if(a[i]=='+')
{
int begin,end;
for(int j=i-1; j>=1; j--)
if((isdigit(a[j])||a[j]=='-')&&(a[j-1]=='+'||a[j-1]=='-'||a[j-1]=='*'||a[j-1]=='/'||a[j-1]==' '))
{
begin=j;
if(isdigit(a[j])&&(a[j-2]=='+'||a[j-2]=='-'||a[j-2]=='*'||a[j-2]=='/'||a[j-2]==' '))begin=j-1;
break;
}
for(int j=i+1; j<=a.size()-1; j++)
if(isdigit(a[j])&&(a[j+1]=='+'||a[j+1]=='-'||a[j+1]=='*'||a[j+1]=='/'||a[j+1]==' '))
{
end=j;
break;
}
string z=a.substr(begin,i-begin),y=a.substr(i+1,end-i);
a.erase(begin,end-begin+1);
a.insert(begin,PLUS(z,y));
i=begin;
clearbug(a);
// cout<<a.substr(1,a.size()-2)<<endl;
}
if(a[i]=='-')
{
int cnt=0;//统计'-'的出现次数
for(int j=1; j<a.size()-2; j++)if(a[j]=='+'||a[j]=='-'||a[j]=='*'||a[j]=='/')cnt++;//遍历
if(cnt==1&&i==1)break;//在第一位出现,只有一个负数,退出循环
if(i==1)continue;//首位的负数
int begin,end;
for(int j=i-1; j>=1; j--)
if((isdigit(a[j])||a[j]=='-')&&(a[j-1]=='+'||a[j-1]=='-'||a[j-1]=='*'||a[j-1]=='/'||a[j-1]==' '))
{
begin=j;
if(isdigit(a[j])&&(a[j-2]=='+'||a[j-2]=='-'||a[j-2]=='*'||a[j-2]=='/'||a[j-2]==' '))begin=j-1;
break;
}
for(int j=i+1; j<=a.size()-1; j++)
if(isdigit(a[j])&&(a[j+1]=='+'||a[j+1]=='-'||a[j+1]=='*'||a[j+1]=='/'||a[j+1]==' '))
{
end=j;
break;
}
string z=a.substr(begin,i-begin),y=a.substr(i+1,end-i);
a.erase(begin,end-begin+1);
a.insert(begin,MINUS(z,y));
i=begin;
clearbug(a);
if(cnt==1)break;//计算完最后的减法,完成
// cout<<a.substr(1,a.size()-2)<<endl;
}
}
return a.substr(1,a.size()-2);//返回值
}
int main()
{
string a;//表达式
getline(cin,a);//输入a
if(a[0]=='-')a='0'+a;//-1==0-1
a=' '+a+' ';//字符串模拟
if(!judge(a))//表达式合法问题
{
cout<<"表达式不合法!";
return 0;
}
cout<<wkhbds(a);//输出
}
王梓轩在2023-05-19 20:39:17追加了内容
ding
0
已采纳
吴章鹏
中级光能
中级光能
//高精度加法
string ADD_PARENTHESES(string origin){//函数名已贴合意义
string res(origin);
string ans = "";
int right = -1; // 暂时存储右括号所在下标
for(int i = 0 ; i < res.size() ; ++i){
if(res[i] == '+' || res[i] == '*' || res[i] == '-'){
ans += '(';
bool flag = 1;
if(res[0] == '-') ans+= '(', ans+=res[0], res = res.substr(1), flag = 0;
for(int j = 0 ; j < res.size() ; ++j){
if(res[j] == res[i] && j < i){ans+=res[j]; continue;}//此时为前方隐含乘号 或者是只有首位负号的情况
ans+=res[j];
if(flag&&res[j] == '-'){ans += '(', res = res.substr(j+1) , j = -1, right = -2; flag = 0;} //flag为了只在第一次遇到负号后添加括号
if(flag&&res[j] == '+'){ans += '(', res = res.substr(j+1) , j = -1, right = -3; flag = 0;}
if(flag&&res[j] == '*'){ans += '(', res = res.substr(j+1) , j = -1, right = -4; flag = 0;}
if(right == -2 && res[j] == ')'){ans += ')'; right = -1; if(j != res.size() - 1) ans += '*';}
if(right == -3 && res[j] == ')'){ans += ')'; right = -1; if(j != res.size() - 1) ans += '+';}
if(right == -4 && res[j] == ')'){ans += ')'; right = -1; if(j != res.size() - 1) ans += '*';}
}
ans += ')';
return ans;
}
}
return origin; //可能不存在符号的情况
}
?
0
0
0