`
buliedian
  • 浏览: 1245731 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

反向工程之四则混合运算优先级判断--加括号问题

阅读更多

我们在栈内已经取得两个数或者表达式,已经以字符串的形式存放了:

asStackArray[iStackPoint] : 1+2+3+4

asStackArray[iStackPoint -1] :1-2-3-4*5

如果将要进行的操作是除法。那优先级比他低的是:1. 乘法,2.加法,3.减法 4.自己(我的程序代码有这个bug,需要连自己也检测,但是仅仅限与上栈操作。也就是 - -, / /碰到一起时,后面要加括号的。)

我们就在上栈和下栈寻找这三个符号(括号内不寻找,比如:"(1+2+3)/4",在下栈可以直接除,上栈必须加括号 )

是不是在括号内的话,用一个计数器来标示。

另外,同级的操作符,+ ,- 如果是+,他对任何表达式都不加括号,因为它是数值类运算的最低级别。而减法对下栈数没影响,但是对上栈操作数有影响,同样,除号也只对同级的上栈操作数有影响。所以只需要判断一个栈。通常,因为除对加减都有管制,所以我们一般只对最低级的减号做单栈判断。等,不等,大于等于,小于等于,大于,小于等返回逻辑值,它的表达式如(a and b or c)=true,其级别比and,not,or都要高,所以要加括号。而 a +b = c+d,就不需要。

最后,bool类型的变量在赋值时,如果写: boolean lbn = 1=2 and 2=3;这样的话看起来比较费解,所以对除单值(true,false)以外的逻辑赋值,我们在右表达式都加上括号,成:boolean lbn = (1=2 and 2=3); 这样看起来舒服明白一点。

经过这样的处理后,表达式的括号就比较合理了。等下我在后面补一个效果图。

//----------------------------------------------------------------------------------

ll_aaa = ((1 + 2 + 3 - 6) * 2) ^ 2 / 3 ^ 3 - (20 - 30 + 30)
ll_aaa = 1 + 2 + 3 + 4 - 9 - (20 - 30 + 30)
ll_aaa = (-(10 - (-100))) * 100
ll_aaa = (10 - (-100)) * 100
ll_aaa = 100 - (-100)
lb = ( not (1 = 20 or 2 = 3) or 2 = 3 and (1 = 20 or 2 = 3))

------------------------------------------------------------------------------------//

bool __fastcall TForm1::PriorityCheck(const unsigned char asPcode,astring &asExpression)
{
//四则混合运算优先级判断
const astring asBracketLEFT = "(",asBracketRIGHT=")";
char HasBracketcount = 0;
char *pExpression,*pTemp;
char ach,ach2,ach3;

pExpression = asExpression.c_str();
pTemp = pExpression;

//取数时检测,如果是带符号就加上括号
switch (asPcode)
{
case 'g': //get 数值时用,凡是带符号的数,都加上括号,以免影响阅读,比如 a - -b,这样写可以,但不好看。
if (*pTemp == '-'){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
return false;
break;


case '-':
for(int i= asExpression.Length();i>=0;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}
if (HasBracketcount !=0) continue;

//减号遇到减号会变换符号,所以要在后面一个括起来,也就是说前操作数不用检查。
if (ach == '-' ){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;

return true;
}
}
break;


///////////////////////////
case '*': //乘法
for(int i= asExpression.Length();i>=0;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if (ach == '+' ||
ach == '-' ){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}
break;


//////////////////////////
case '/': //除法
for(int i= asExpression.Length();i>=0;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if (ach == '+' ||//这里需要加上除号。。!!
ach == '-' ||
ach == '*'){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}
break;

///////////////////////
case '^'://N次方
for(int i= asExpression.Length();i>=0;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if (ach == '+' ||
ach == '-' ||
ach == '*' ||
ach == '/' ){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}
break;


//////////////////////////////////
case '>'://大于,小于,等于 和 不等于。
for(int i= asExpression.Length();i>=3;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if ((ach == 'n' && *(pTemp)== 'o' && *(pTemp + 1)== 't' && *(pTemp + 2)== '\x20' ) || //++操作后自动增加了1
(ach == 'a' && *(pTemp)== 'n' && *(pTemp + 1)== 'd' && *(pTemp + 2)== '\x20') ||
(ach == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '\x20')){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}

break;

///////////////////////////////////////////
case '!'://logic Not
for(int i= asExpression.Length();i>=3;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if ((ach == 'a' && *(pTemp)== 'n' && *(pTemp +1)== 'd' && *(pTemp + 2)== '\x20') || //++操作后自动增加了1
(ach == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '\x20')){

asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}

break;

///////////////////////////////////////////
case '&': //logic and
for(int i= asExpression.Length();i>=3;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if (ach == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '\x20'){ //++操作后自动增加了1
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}
break;

///////////////////////////////////
case '@'://数值的负号操作。大于一切。只比括号的级别小。如-(li_1+li_2),这个符号如果跟数字接壤,比较混淆。
for(int i= asExpression.Length();i>=0;i--){
ach = *(pTemp ++);
if (ach == '\"' || ach == '\'') return false; //字符串内不判断

//括号已经存在的检测。
if (ach == '('){
HasBracketcount ++;
continue;
}
if (ach == ')'){
HasBracketcount -- ;
}

if (HasBracketcount !=0) continue;

if (ach == '+' ||
ach == '-' ||
ach == '*' ||
ach == '/' ||
ach == '^'){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;

return true;
}
}
break;


//////////对逻辑表达式赋值时,加上括号,以免误解。/////////////
case 'T': //lbn=a and b and cor d时,把后面表达式括起来,只用于对左值赋值时。
for(int i= asExpression.Length();i>=3;i--){
ach = *(pTemp ++);

if ((ach == 'n' && *(pTemp)== 'o' && *(pTemp + 1)== 't' && *(pTemp + 2)== '\x20' ) || //++操作后自动增加了1
(ach == 'a' && *(pTemp)== 'n' && *(pTemp + 1)== 'd' && *(pTemp + 2)== '\x20') ||
(ach == 'o' && *(pTemp)== 'r' && *(pTemp + 1)== '\x20')){
asExpression = asBracketLEFT + asExpression + asBracketRIGHT;
return true;
}
}
break;
}

return false;
}

分享到:
评论

相关推荐

    二年级数学100以内数的加减混合运算练习题.doc

    接下来,我们通过几个具体的例子来进一步了解如何进行100以内的加减混合运算。 #### 示例1: 77 - 46 + 32 - **步骤1**: 首先进行减法运算,77 - 46 = 31。 - **步骤2**: 然后加上32,31 + 32 = 63。 - **结果**: ...

    部编版一年级数学上册加减混合运算(汇集).pdf

    混合运算中可能涉及运算的顺序问题,根据数学的优先级法则,通常是先做括号内的运算,然后依次执行乘法、除法,最后是加法和减法。 4. 认识数字和数轴:一年级的学生还会学习识别数字、数数以及数轴的概念,通过...

    二年级加减混合运算练习题.doc

    5. **连续运算**:在一个算式中,如果既有加法又有减法,需要按照从左到右的顺序进行计算,没有括号时不需要考虑运算优先级。 6. **简化计算**:对于某些复杂的算式,可以先做简单的加减来逐步简化问题,例如77+22-...

    四年级数学下册脱式计算练习题.doc

    混合运算包含了加法、减法、乘法和除法的组合,解题时应遵循“先乘除后加减”的原则,同时注意括号内的运算具有最高优先级。例如,当我们遇到一个包含括号和乘法的表达式时,必须先解决括号内的问题,再依次进行乘除...

    北师大版七年级数学上册专题训练题及答案3精选.doc

    9. 混合运算的步骤:在解决有理数混合运算题时,一般先进行括号内的运算,再处理乘除,最后处理加减。同时要注意运算的优先级,避免错误。 10. 解答过程中的化简:在计算过程中,经常需要对中间结果进行化简,例如 ...

    浙教版七年级数学上册练习题第25章分层作业2精选.doc

    - 混合运算是加、减、乘、除、乘方的组合,需要按照先乘除后加减,先括号内后括号外的顺序进行计算。 - 乘方运算优先级最高,接着是乘法和除法,最后是加法和减法。 7. **数轴上的距离与位置**: - 数轴上的点...

    20以内混合加减法.doc

    4. **顺序和优先级**:虽然20以内的混合运算没有涉及括号和复杂的运算规则,但它们可以帮助孩子们理解运算的顺序,即从左到右依次进行。 5. **零的概念**:在减法中,如果被减数小于减数,结果可能会是负数,但在这...

    沪教版四年级上正推和逆推教(学)案与练习.doc

    例如,给出一系列含有加减乘除和括号的混合运算题目,教师会引导学生明确运算的优先级和正确运用括号。通过逐步引导,学生能够理解并掌握递等式计算的要领,为接下来的逆推学习奠定基础。 逆推的学习则更为复杂,但...

    小学二年级数学(下册)竖式计算-二年级(下册)竖式验算.doc

    5. 混合运算:例如 `42÷7×6`,按照先乘除后加减的顺序,先计算 `42÷7` 得到6,然后将结果与6相乘,得到最终答案 `36`。 6. 四则运算结合律的应用:如 `(30+15)÷5`,先进行括号内的加法,得到45,再除以5,得到9...

    三年级上册计算单项检测试题.doc

    试题中的混合运算是对括号内运算的优先级处理能力的考验,学生需要掌握先乘除后加减,先括号内后括号外的计算顺序。 六、列式计算:逻辑思维的体现 列式计算题目要求学生根据实际问题列出正确的算式。这种题目考察...

    北师二年级下册数学总复习PPT学习教案.pptx

    在“混合运算”这一主题中,学生需要遵循运算的优先级,先乘除后加减,并且若出现括号,需先计算括号内的部分。掌握这些基本规则,对于解决实际问题至关重要。 数与运算的进一步拓展是“解决问题”的应用,例如“除...

Global site tag (gtag.js) - Google Analytics