CSDN-CSDN社区-C++ Builder-基础类

收藏 怎样让"(2+3)*6"这个字符串生成结果,即结果为30[问题点数:50,结帖人:flyingkissw]

  • flyingkissw
  • (笨笨)
  • 等 级:
  • 结帖率:
楼主发表于:2008-07-31 11:40:09
例如:AnsiString  mystr="(2+3)*6" 
  把mystr变成程序直接调用。  mystr=(2+3)*6
回复次数:15
#1楼 得分:0回复于:2008-07-31 11:42:23
TTTT
#2楼 得分:0回复于:2008-07-31 11:46:18
int i = (2+3) * 6;
AnsiString  mystr=IntToStr(i);
#3楼 得分:0回复于:2008-07-31 12:04:44
搜索一下 表达式解析
能找到的
#4楼 得分:30回复于:2008-07-31 12:15:18
  • web_php用户头像
  • web_php
  • (风中的云)
  • 等 级:
#5楼 得分:0回复于:2008-07-31 12:22:27
AnsiString  mystr="(2+3)*6"  //是字符串,不是整性的计算啊
#6楼 得分:20回复于:2008-07-31 12:25:40
  • keiy用户头像
  • keiy
  • (keiy)
  • 等 级:
  • 5

    8

    5

#7楼 得分:0回复于:2008-07-31 12:59:17
用第三方控件(如rxLIB),我这里有一个用pas写的:
Delphi(Pascal) code
// Borland C++ Builder // Copyright (c) 1995, 2002 by Borland Software Corporation // All rights reserved // (DO NOT EDIT: machine generated header) 'cmpEvaluator.pas' rev: 6.00 #ifndef cmpEvaluatorHPP #define cmpEvaluatorHPP #pragma delphiheader begin #pragma option push -w- #pragma option push -Vx #include <Dialogs.hpp> // Pascal unit #include <Forms.hpp> // Pascal unit #include <Controls.hpp> // Pascal unit #include <Graphics.hpp> // Pascal unit #include <Classes.hpp> // Pascal unit #include <SysUtils.hpp> // Pascal unit #include <Messages.hpp> // Pascal unit #include <Windows.hpp> // Pascal unit #include <SysInit.hpp> // Pascal unit #include <System.hpp> // Pascal unit //-- user supplied ----------------------------------------------------------- namespace Cmpevaluator { //-- type declarations ------------------------------------------------------- class DELPHICLASS TExpressionEvaluator; class PASCALIMPLEMENTATION TExpressionEvaluator : public Classes::TComponent { typedef Classes::TComponent inherited; private: AnsiString fExpression; int pos; char ch; char __fastcall GetChar(void); char __fastcall GetNonWhitespace(void); void __fastcall SkipWhitespace(void); Extended __fastcall CalcAddition(void); Extended __fastcall CalcMultiplication(void); Extended __fastcall CalcPower(void); Extended __fastcall CalcSignedTerm(void); Extended __fastcall CalcTerm(void); Extended __fastcall CalcNumber(void); Extended __fastcall CalcExpressionInBrackets(void); public: Extended __fastcall Calculate(void); __property int Position = {read=pos, nodefault}; __published: __property AnsiString Expression = {read=fExpression, write=fExpression}; public: #pragma option push -w-inl /* TComponent.Create */ inline __fastcall virtual TExpressionEvaluator(Classes::TComponent* AOwner) : Classes::TComponent(AOwner) { } #pragma option pop #pragma option push -w-inl /* TComponent.Destroy */ inline __fastcall virtual ~TExpressionEvaluator(void) { } #pragma option pop }; //-- var, const, procedure --------------------------------------------------- extern PACKAGE void __fastcall Register(void); } /* namespace Cmpevaluator */ using namespace Cmpevaluator; #pragma option pop // -w- #pragma option pop // -Vx #pragma delphiheader end. //-- end unit ---------------------------------------------------------------- #endif // cmpEvaluator

使用时将该pas加入你的项目
...
#include "cmpEvaluator.hpp"
...
  TExpressionEvaluator *x=new TExpressionEvaluator(this);
  x->Expression="(2+3)*6" ;
  double y=x->Calculate();
  ShowMessage(y);
  • keiy用户头像
  • keiy
  • (keiy)
  • 等 级:
  • 5

    8

    5

#8楼 得分:0回复于:2008-07-31 13:00:29
程序贴错了,以下才是:
Delphi(Pascal) code
unit cmpEvaluator; // Copyright (c) Colin Wilson 1997. All rights reserved. // E-mail to woozle@compuserve.com interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TExpressionEvaluator = class(TComponent) private fExpression : string; pos : Integer; ch : char; function GetChar : char; function GetNonWhitespace : char; procedure SkipWhitespace; function CalcAddition : extended; function CalcMultiplication : extended; function CalcPower : extended; function CalcSignedTerm : extended; function CalcTerm : extended; function CalcNumber : extended; function CalcExpressionInBrackets : extended; protected public function Calculate : extended; property Position : Integer read pos; published property Expression : string read fExpression write fExpression; end; procedure Register; implementation function TExpressionEvaluator.GetChar : char; begin if pos < Length (Expression) then begin ch := Expression [pos + 1]; Inc (pos) end else ch := #0; result := ch; end; function TExpressionEvaluator.GetNonWhitespace : char; begin GetChar; SkipWhitespace; result := ch; end; procedure TExpressionEvaluator.SkipWhitespace; begin if ch in [' ', #9] then repeat GetChar until not (ch in [' ', #9]) end; function TExpressionEvaluator.CalcAddition : extended; begin result := CalcMultiplication; while True do case ch of '+' : result := result + CalcMultiplication; '-' : result := result - CalcMultiplication; else break end end; function TExpressionEvaluator.CalcMultiplication : extended; begin result := CalcPower; while True do case ch of '*' : result := result * CalcPower; '/' : result := result / CalcPower; else break end end; function TExpressionEvaluator.CalcPower : extended; begin result := CalcSignedTerm; while True do case ch of '^' : result := exp (ln (result) * CalcSignedTerm); else break end end; function TExpressionEvaluator.CalcSignedTerm : extended; begin case GetNonWhitespace of '+' : result := CalcSignedTerm; '-' : result := -CalcSignedTerm; else result := CalcTerm end end; function TExpressionEvaluator.CalcTerm : extended; begin case ch of '0'..'9' : result := CalcNumber; '(' : result := CalcExpressionInBrackets; else raise Exception.CreateFmt ('Syntax error in expression at position %d', [pos + 1]) end end; function TExpressionEvaluator.CalcNumber : extended; var s : string; begin result := 0; s := ''; while ch in ['0'..'9'] do begin s := s + ch; GetChar; if ch = '.' then begin repeat s := s + ch; GetChar until not (ch in ['0'..'9']); break end end; result := StrToFloat (s); SkipWhitespace end; function TExpressionEvaluator.CalcExpressionInBrackets : extended; begin result := CalcAddition; if ch = ')' then GetNonWhitespace else raise Exception.CreateFmt ('Mismatched parentheses at position %d', [pos + 1]) end; function TExpressionEvaluator.Calculate : extended; begin pos := 0; result := CalcAddition; if ch <> #0 then raise Exception.CreateFmt ('Unexpected end of expression at position %d', [pos + 1]); end; procedure Register; begin RegisterComponents('Samples', [TExpressionEvaluator]); end; end.
  • fbmsyu用户头像
  • fbmsyu
  • (Q6600 9600GT)
  • 等 级:
#9楼 得分:0回复于:2008-07-31 14:41:34
引用 4 楼 loveshell 的回复: http://download.csdn.net/source/315802


这个不错,就是有点bug.
抛出的异常不是标准的类型.
右括号不匹配的时候不能抛出异常.
不支持[ ,{ 括号.
  • BCBPLC用户头像
  • BCBPLC
  • ([明月夜])
  • 等 级:
#10楼 得分:0回复于:2008-07-31 15:01:44
Windows里有一个脚本.ocx就是计算表达式的
#11楼 得分:0回复于:2008-07-31 15:15:30
我第一个就用keiy的,可能是引用Delphi方法错误~~~好多多的错误~~^_^
keiy辛苦了,上次的DBGridEh列限制输入多亏了你~~要不我还要多摸好几天

4楼的很好使,直接下载用就可以~~o(∩_∩)o...哈哈
http://download.csdn.net/source/315802
#12楼 得分:0回复于:2008-07-31 15:19:54
.。。。。。
  加分加错了,keiy你的20分加到tangx100了
      !!@#@#¥
#13楼 得分:0回复于:2008-08-01 14:14:05
可以通过堆栈实现算数表达式解析
#14楼 得分:0回复于:2008-08-04 20:59:20
虽然结贴了,我还是说一下我的算法。

首先将正常的表达式(中缀),转换成后缀表达式

比如 "(2+3)*6"  转换为 " 2 3 + 6 * "
如果不清楚什么是后缀表达式,我就无语了。
得到后续表达式后,就是一个顺序压入堆栈执行的问题了
比如先获取第一个2入堆栈 ,然后是3入堆栈,然后发现是运算符+,这时执行运算符+,将2和3弹出,相加后入堆栈,然后是6,6入堆栈,然后是*,执行*,将堆栈中的两个数弹出执行,得到最后结果。


下面这部分代码是我刚刚写好的一个中缀到后缀的转换程序。这部分代码才是核心。


bool __fastcall IsOpertator(char aChar)
{
    switch(aChar)
    {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
        case ')':
            return true;
        default:
            return false;
    }
}

int __fastcall OperatorLevel(char Opt)
{
    switch(Opt)
    {
        case '*':
            return 2;
        case '/':
            return 2;
        case '(':
            return 99;
        case ')':
            return 0;
        case '+':
            return 1;
        case '-':
            return 1;
        default:
            return 0;
    }
}

AnsiString __fastcall InfixToPostFix(AnsiString inputString)
{
    vector <char> OperatorStack;
    AnsiString PostFixString;

    //½«±í´ïʽ¸ÄΪºó׺±í´ïʽ
    AnsiString tmpNumber;
    for(int i=0;i <inputString.Length();i++)
    {
        char tmpChar = inputString.c_str()[i];
        if(IsOpertator(tmpChar)) // Èç¹ûÊDzÙ×÷·û»òÀ¨ºÅ
        {
            if(tmpNumber.Length()>0) // Èç¹û»¹ÓÐÕýÔÚ´¦ÀíµÄÊý×Ö£¬Êý×Ö¶ÁÈ¡ÍêÕû£¬Èëºó׺¶ÓÁС£
                PostFixString += tmpNumber+" ";
            tmpNumber = "";

            if(tmpChar == ')') // Èç¹ûÊDZÕÀ¨ºÅ£¬ÐèÒªÒ»Ö±µ¯³öµ½¿ªÀ¨ºÅ
            {
                while(!OperatorStack.empty())
                {
                    char thePopOpt = OperatorStack.back();

                    if(thePopOpt == '(')
                    {
                        OperatorStack.pop_back();
                        break;
                    }
                    else
                    {
                        PostFixString += AnsiString(thePopOpt)+" ";
                        OperatorStack.pop_back();
                    }
                }
                continue; // continue for;
            }

            // ͬ²Ù×÷·û¶ÑÕ»Õ»¶¥ÔªËرȽϣ¬Èç¹ûÓÅÏȼ¶¸ß£¬¾ÍÈëÕ»£¬·ñÔòÖ±µ½µ¯³öËùÓÐÔªËØ
            while(!OperatorStack.empty())
            {
                char thePopOpt = OperatorStack.back();

                if(OperatorLevel(thePopOpt)>OperatorLevel(tmpChar))
                {
                    if(thePopOpt=='(')
                    {
                        OperatorStack.push_back(tmpChar);
                        tmpChar = '\0';
                        break;
                    }
                    else
                    {
                        OperatorStack.pop_back();
                        PostFixString += AnsiString(thePopOpt)+" ";
                    }
                }
                else if(OperatorLevel(thePopOpt)==OperatorLevel(tmpChar))
                {
                    OperatorStack.pop_back();
                    PostFixString += AnsiString(thePopOpt)+" ";

                    OperatorStack.push_back(tmpChar);
                    tmpChar = '\0';
                    break;
                }
                else
                {
                    OperatorStack.push_back(tmpChar);
                    tmpChar = '\0';
                    break; // break while
                }
            } // end while

            if(tmpChar!='\0')
                OperatorStack.push_back(tmpChar);
        }
        else    // Èç¹ûÊÇÊý×Ö
        {
            tmpNumber += AnsiString(tmpChar);

            if(i == inputString.Length()-1)
            {
                PostFixString += AnsiString(tmpNumber)+" ";
                break;
            }
        }
    }
    //----end for

    while(!OperatorStack.empty())
    {
        PostFixString += AnsiString(OperatorStack.back())+" ";
        OperatorStack.pop_back();
    }

    return PostFixString;
}
#15楼 得分:0回复于:2008-08-04 21:22:28
刚才注释乱码了,重贴一次

//---------------------------------------------------------------------------
bool __fastcall IsOpertator(char aChar)
{
    switch(aChar)
    {
        case '+':
        case '-':
        case '*':
        case '/':
        case '(':
        case ')':
            return true;
        default:
            return false;
    }
}

int __fastcall OperatorLevel(char Opt)
{
    switch(Opt)
    {
        case '*':
            return 2;
        case '/':
            return 2;
        case '(':
            return 99;
        case ')':
            return 0;
        case '+':
            return 1;
        case '-':
            return 1;
        default:
            return 0;
    }
}

AnsiString __fastcall InfixToPostFix(AnsiString inputString)
{
    vector <char> OperatorStack;
    AnsiString PostFixString;

    //将表达式改为后缀表达式
    AnsiString tmpNumber;
    for(int i=0;i <inputString.Length();i++)
    {
        char tmpChar = inputString.c_str()[i];
        if(IsOpertator(tmpChar)) // 如果是操作符或括号
        {
            if(tmpNumber.Length()>0) // 如果还有正在处理的数字,数字读取完整,入后缀队列。
                PostFixString += tmpNumber+" ";
            tmpNumber = "";

            if(tmpChar == ')') // 如果是闭括号,需要一直弹出到开括号
            {
                while(!OperatorStack.empty())
                {
                    char thePopOpt = OperatorStack.back();

                    if(thePopOpt == '(')
                    {
                        OperatorStack.pop_back();
                        break;
                    }
                    else
                    {
                        PostFixString += AnsiString(thePopOpt)+" ";
                        OperatorStack.pop_back();
                    }
                }
                continue; // continue for;
            }

            // 同操作符堆栈栈顶元素比较,如果优先级高,就入栈,否则直到弹出所有元素
            while(!OperatorStack.empty())
            {
                char thePopOpt = OperatorStack.back();

                if(OperatorLevel(thePopOpt)>OperatorLevel(tmpChar))
                {
                    if(thePopOpt=='(')
                    {
                        OperatorStack.push_back(tmpChar);
                        tmpChar = '\0';
                        break;
                    }
                    else
                    {
                        OperatorStack.pop_back();
                        PostFixString += AnsiString(thePopOpt)+" ";
                    }
                }
                else if(OperatorLevel(thePopOpt)==OperatorLevel(tmpChar))
                {
                    OperatorStack.pop_back();
                    PostFixString += AnsiString(thePopOpt)+" ";

                    OperatorStack.push_back(tmpChar);
                    tmpChar = '\0';
                    break;
                }
                else
                {
                    OperatorStack.push_back(tmpChar);
                    tmpChar = '\0';
                    break; // break while
                }
            } // end while

            if(tmpChar!='\0')
                OperatorStack.push_back(tmpChar);
        }
        else    // 如果是数字
        {
            tmpNumber += AnsiString(tmpChar);

            if(i == inputString.Length()-1)
            {
                PostFixString += AnsiString(tmpNumber)+" ";
                break;
            }
        }
    }
    //----end for

    while(!OperatorStack.empty())
    {
        PostFixString += AnsiString(OperatorStack.back())+" ";
        OperatorStack.pop_back();
    }

    return PostFixString;
}
相关问题
【一个疑问】---微软序列号生成和验证扩充话题/ 灌水乐园- CSDN社区 ...
冒泡排序大比拼---看看谁的算法最简单
前几天阿里巴巴的笔试题
這樣的一個數據結構,不用第歸可以實現樹形結構顯示嗎??可以用sql ...
请问如何将AnsiString型转换为char *(字符指针)型? C++ Builder ...
怎么在.aspx里面得到.cs里面定义的int[] p变量。 .NET技术/ ASP.NET ...
一道ACM题目:求超大数除以1-9的余数