📄 form1.cs
字号:
//以下代码使待扫描字符串的单目('+'和'-')变为双目
if(startString.Length!=0)
if(startString[0]=='+'||startString[0]=='-')
{
startString=startString.Insert(0,"0");
}
for(int i=0;i<startString.Length-1;i++)
{
if((startString[i]=='(')&&(startString[i+1]=='-'))
startString=startString.Insert(i+1,"0");
}
startString=startString.Insert(startString.Length,")");
//将待扫描字符串字号字母转化为小写字母
startString=startString.ToLower();
////**试验用语句
//label4.Text=startString;
}
public bool CheckParentthese() //检查括号是否匹配
{
int number=0;
for(int i=0;i<startString.Length-1;i++)
{
if(i=='(') number++;
if(i==')') number--;
if(number<0) return false;
}
if(number!=0)
{
return false;
}
return true;
}
public int CheckFollowCorrect() //给运算表达式分块(三角函数...算术运算符等),再根据其返回值来检验其属于哪类错误
{
string str,oldString="",newString="";
int dataCount=0,characterCount=0;
if(startString.Equals(")"))
return 0; //输入字符串为空返回值
if((startString[0]=='*')||(startString[0]=='/')||(startString[0]=='^')||(startString[0]==')'))
return 11; //首字符输入错误返回值
for(int i=0;i<startString.Length;i++)
{
if((oldString.Equals("三角函数"))&&(newString.Equals("右括号")))
return 2; //三角函数直接接右括号错误返回值
if((oldString.Equals("左括号"))&&(newString.Equals("算术运算符")))
return 3; //左括号直接接算术运算符错误返回值
if((oldString.Equals("数字序列"))&&(newString.Equals("三角函数")))
return 4; //数字序列后直接接三角函数错误返回值
if((oldString.Equals("数字序列"))&&(newString.Equals("左括号")))
return 5; //数字序列后直接接左括号错误返回值
if((oldString.Equals("算术运算符"))&&(newString.Equals("右括号")))
return 6; //算术运算符后直接接右括号错误返回值
if((oldString.Equals("右括号"))&&(newString.Equals("左括号")))
return 7; //右括号直接接左括号错误返回值
if((oldString.Equals("右括号"))&&(newString.Equals("三角函数")))
return 8; //右括号直接接三角函数错误返回值
if((oldString.Equals("数字序列"))&&(newString.Equals("数字序列")))
return 9; //数字序列后直接接'pi'/'e'或'pi'/'e'直接接数字序列错误返回值
if((oldString.Equals("算术运算符"))&&(newString.Equals("算术运算符")))
return 10; //算术运算符后直接接算术运算符错误返回值
oldString=newString;
if(i<startString.Length-5&&startString.Length>=6)
{
str=startString.Substring(i,6);
if((str.CompareTo("arcsin")==0)||(str.CompareTo("arccos")==0)||(str.CompareTo("arctan")==0)||(str.CompareTo("arccot")==0))
{
newString="三角函数";
i+=5; characterCount++;
continue;
}
}
if(i<startString.Length-2&&startString.Length>=3)
{
str=startString.Substring(i,3);
if((str.CompareTo("sin")==0)||(str.CompareTo("cos")==0)||(str.CompareTo("tan")==0)||(str.CompareTo("cot")==0)||(str.CompareTo("sec")==0)||(str.CompareTo("csc")==0))
{
newString="三角函数";
i+=2; characterCount++;
continue;
}
}
if(i<(startString.Length-1)&&(startString.Length)>=2)
{
str=startString.Substring(i,2);
if(str.CompareTo("ln")==0)
{
newString="三角函数";
i+=1; characterCount++;
continue;
}
if(str.CompareTo("pi")==0)
{
newString="数字序列";
i+=1;dataCount++;
continue;
}
}
str=startString.Substring(i,1);
if(str.Equals("^")||str.Equals("*")||str.Equals("/")||str.Equals("+")||str.Equals("-"))
{
newString="算术运算符";
characterCount++;
continue;
}
if(str.Equals("e"))
{
newString="数字序列";
dataCount++;
continue;
}
/*if(str.Equals("x"))
{
newString="数字序列";
dataCount++;
continue;
}*/
if(str.Equals("("))
{
newString="左括号";
characterCount++;
continue;
}
if(str.Equals(")"))
{
newString="右括号";
characterCount++;
continue;
}
if(Char.IsDigit(startString[i]))
{
while(Char.IsDigit(startString[i]))
{
i++;
}
if(startString[i]=='.'&&(!Char.IsDigit(startString[i+1]))&&(i+1)!=startString.Length)
return 13;
if(startString[i]=='.')
{
i++;
}
while(Char.IsDigit(startString[i]))
{
i++;
}
newString="数字序列";
i--; dataCount++;
continue;
}
return 1; //非法字符
}
if((dataCount==0&&characterCount!=0)||(startString[0]=='0'&&dataCount==1&&characterCount>1&&startString.Length!=2))
return 12;
return 100;
}
public int IsCharacterOrData(ref double num)
{
string str="";
startTop+=startTopMoveCount; startTopMoveCount=0;
int i=startTop;
if(i<startString.Length-5&&startString.Length>=6)
{
str=startString.Substring(i,6);
for(int j=4;j<=7;j++)
if(str.Equals(opchTbl[j].op))
{
startTopMoveCount=6;
return opchTbl[j].code;
}
}
if(i<startString.Length-2&&startString.Length>=3)
{
str=startString.Substring(i,3);
for(int j=0;j<10;j++)
if(str.CompareTo(opchTbl[j].op)==0)
{
startTopMoveCount=3;
return opchTbl[j].code;
}
}
if(i<(startString.Length-1)&&(startString.Length)>=2)
{
str=startString.Substring(i,2);
if(str.CompareTo("ln")==0)
{
startTopMoveCount=2;
return 11;
}
if(str.CompareTo("pi")==0)
{
startTopMoveCount=2;
num=Math.PI;
return 100;
}
}
//以下开始确认一个字符是属于什么值类型
if(i<startString.Length)
{
str=startString.Substring(i,1);
for(int j=11;j<19;j++)
{
if(str.Equals(opchTbl[j].op))
{startTopMoveCount=1;return opchTbl[j].code;}
}
if(str.CompareTo("e")==0)
{
startTopMoveCount=1; num=Math.E;
return 100;
}
/*if(str.CompareTo("x")==0)
{
startTopMoveCount=1; num=variableX;
return 100;
}*/
if(Char.IsDigit(startString[i]))
{
double temp=0,M=10; int j=i;
while(Char.IsDigit(startString[j]))
{
temp=M*temp+Char.GetNumericValue(startString[j]);
startTop++;
j++;
}
if(startString[j]=='.')
{
j++;startTop++;
}
while(Char.IsDigit(startString[j]))
{
temp+=1.0/M*Char.GetNumericValue(startString[j]);
M/=10;j++;
startTop++;
}
startTopMoveCount=0;
num=temp;
return 100;
}
}
return -1;
}
public double DoubleCount(string opString,double data1,double data2)
{ //双目运算
if(opString.CompareTo("+")==0) return (data1+data2);
if(opString.CompareTo("-")==0) return (data1-data2);
if(opString.CompareTo("*")==0) return (data1*data2);
if(opString.CompareTo("/")==0) return (data1/data2);
if(opString.CompareTo("^")==0)
{
double end=data1;
for(int i=0;i<data2-1;i++)
end*=data1;
return (end);
}
return Double.MaxValue; //定义域不对,返回
}
public double DoubleCount(string opString,double data1)
{ //单目运算
if(opString.CompareTo("sin")==0) return Math.Sin(data1);
if(opString.CompareTo("cos")==0) return Math.Cos(data1);
if(opString.CompareTo("tan")==0) return Math.Tan(data1);
if(opString.CompareTo("cot")==0) return (1/(Math.Tan(data1)));
if(opString.CompareTo("arcsin")==0)
if(-1<=data1&&data1<=1) return Math.Asin(data1);
if(opString.CompareTo("arccos")==0)
if(-1<=data1&&data1<=1) return Math.Acos(data1);
if(opString.CompareTo("arctan")==0)
if(-Math.PI/2<=data1&&data1<=Math.PI/2)return Math.Atan(data1);
if(opString.CompareTo("arccot")==0)
if(-Math.PI/2<=data1&&data1<=Math.PI/2)return (-Math.Atan(data1));
if(opString.CompareTo("sec")==0) return (1/(Math.Cos(data1)));
if(opString.CompareTo("csc")==0) return (1/(Math.Sin(data1)));
if(data1>0) if(opString.CompareTo("ln")==0) return Math.Log(data1);
return Double.MaxValue; //定义域不对
}
public bool CountValueY(ref double tempY) //方法功能为求得解
{
int type=-1; //存放正在扫描的字符串是为数字类型还是(单双目运算符)
double num=0; //如果是数据,则返回数据的值
//进栈底结束符"end"
opTop++;
operateStack[opTop].op="end"; operateStack[opTop].code=18; operateStack[opTop].grade=' ';
while(startTop<=startString.Length-1)
{
start:
type=IsCharacterOrData(ref num); //调用判断返回值类型函数
//if(type==17) ;
if(type==-1){return false;}
if(type==100)
{
dataTop=dataTop+1;
//Console.WriteLine(dataTop);
dataStack[dataTop]=num;
}
else
{
if(osp[type-1]>isp[operateStack[opTop].code-1]) //操作符进栈
{
opTop++;
operateStack[opTop].op=opchTbl[type-1].op; operateStack[opTop].code=opchTbl[type-1].code; operateStack[opTop].grade=opchTbl[type-1].grade;
}
else
{
while(osp[type-1]<=isp[operateStack[opTop].code-1]) //弹出操作符跟数据计算,并存入数据
{
if(operateStack[opTop].op.CompareTo("end")==0)//当遇到"end"结束符表示已经获得结果
{
if(dataTop==0)
{
tempY=dataStack[dataTop]; startTop=0; startTopMoveCount=0; opTop=-1; dataTop=-1;
return true;
}
else return false; //运算符和数据的个数不匹配造成的错误
}
if(operateStack[opTop].op.CompareTo("(")==0) //如果要弹出操作数为'( ',则消去左括号
{
opTop--; goto start;
}
//弹出操作码和一个或两个数据计算,并将计算结果存入数据栈
double data1,data2; opTable operate;
if(dataTop>=0) data2=dataStack[dataTop];
else return false;
operate.op=operateStack[opTop].op; operate.code=operateStack[opTop].code; operate.grade=operateStack[opTop].grade;
opTop--; //处理一次,指针必须仅且只能下移一个单位
if(operate.grade=='d')
{
if(dataTop-1>=0) data1=dataStack[dataTop-1];
else return false;
double tempValue=DoubleCount(operate.op,data1,data2);
if(tempValue!=Double.MaxValue) dataStack[--dataTop]=tempValue;
else return false;
}
if(operate.grade=='s')
{
double tempValue=DoubleCount(operate.op,data2);
if(tempValue!=Double.MaxValue)
dataStack[dataTop]=tempValue;
else return false;
}
}
//如果当前栈外操作符比栈顶的操作符优先级别高,则栈外操作符进栈
opTop++;
operateStack[opTop].op=opchTbl[type-1].op; operateStack[opTop].code=opchTbl[type-1].code; operateStack[opTop].grade=opchTbl[type-1].grade;
}
}
}
return false;
}
public void StartExcute()
{
InitializeOpchTblStack();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -