Results 1 to 15 of 15

Thread: String Formula to Integer

  1. #1

    Thread Starter
    New Member
    Join Date
    Sep 2002
    Posts
    12

    String Formula to Integer

    Hello, does anyone have information or a link to a place where I can learn how to take an entire formula written as a string, and convert it into an integer?

    For example a function called Convert that takes works something like...

    CString formula = "5 + 3*6 - (2+6)^5";
    int x = Convert(formula);

    And Convert() evaluates the entire string and returns a value.

    Any help would be greatly appreciated, thanks.

  2. #2
    Fanatic Member twanvl's Avatar
    Join Date
    Dec 2001
    Posts
    771
    1. Look for the operator with the LOWEST precedence in the string, not inside parenthesis (keep a variable with the nesting level, if '(' level++, if ')' level--)
    2. Run the Convert function on everything before the operator, and everything after the operator, preform the operation on those two results.
    3. If there is no operator found at step 1 you either have a expression in parenthesis, remove the parenthesis, and call Convert on that string.
    If there are no parenthesis you have a number (or if you want to extend your parser later on, a named variable) you can convert it to an int (std::stringstream, boost::lexical_cast, atio)

    This is not the fastest way to do it, but it is the easiest. (You could also write a function that uses no recursion, and keeps a stack of partialy evaluated values. Such an algorithm will be 10 times as long and complex)

  3. #3

    Thread Starter
    New Member
    Join Date
    Sep 2002
    Posts
    12
    The only problem with such a method would be... what if I have multiple operators? How do I handle it then?

    Referring to the example I posted, there are 5 operations being performed, how would I keep track of the algorythm handling the brackets first, then exponentiating the bracket, then multiplying and then adding? What about brackets within brackets and so on...

  4. #4
    Fanatic Member twanvl's Avatar
    Join Date
    Dec 2001
    Posts
    771
    The algorithm would work something like:
    Code:
    Covert("5 + 3*6 - (2+6)^5")
        step 1-> the '+' at position 2, split into "5" and "3*6 - (2+6)^5".
        a=Convert("5")
            returns 5
        b=Convert("3*6 - (2+6)^5")
            lowest precedence: '-' at position 4
            a=Convert(3*6)
                lowest precedence: '*' at pos 1
                a=Convert("3")
                    returns 3
                b=Convert("6")
                    returns 6
                returns a*b  (which is 18)
            b=Convert("(2+6)^5)")
                lowest precedence: '^' at pos 5
                a=Convert("(2+6)")
                    in parenthesis, remove
                    returns Convert("2+6")
                        lowest precedence: '+' at pos 1
                        a=Convert("2")
                            returns 2
                        b=Convert("6")
                            returns 2
                        returns a+b (which is 8)
                b=Convert(5)
                    returns 5
                returns a^b (which is 32768)
            returns a-b (which is -32750)
        returns a+b (which is -32745)
    The key is that the functions is recursive, it calls itself to calculate sub-expressions

  5. #5

    Thread Starter
    New Member
    Join Date
    Sep 2002
    Posts
    12
    That pseudocode should be very... very helpful.

    I'll try and implementing it into my scripting language, thanks a lot.

  6. #6

    Thread Starter
    New Member
    Join Date
    Sep 2002
    Posts
    12
    Well I got to work on it, and it does have one BEDMAS problem.

    Since the algorythm splits formulas into 2 sections, and then splits the right section of the formula again into 2 sections, and keeps on repeating until no sections are left, what happens is it messes up subtraction and addition.

    For example, a string like "5 - 1 + 5" should work out to 9 using BEDMAS, but what the algorythm seems to be doing is:

    Code:
    convert(5 - 1 + 5)
    
               split into "5" and "1 + 5"
               a = convert("5")
                      returns 5
               b = convert("1 + 5")
                           split into "1" and "5"
                           a = convert("1")
                                  returns 1
                           b = convert("5")
                                  returns 5
                      returns (a + b) which is 6
              returns (a - b) which is -1

  7. #7
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Build an expression tree. Leaf nodes contain values, non-leaves contain operators. Use an in-order traversal to evaluate.

    Z.

  8. #8
    Fanatic Member twanvl's Avatar
    Join Date
    Dec 2001
    Posts
    771
    If you take the last operator with the lowest precedence (+ and - have equal precedence), instead of the first, it should work.

  9. #9
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    have two stacks, an operand and an operator stack. traverse the string from left to right. push operands on the stack, push operators on the operator stack, when encountering operators with lower precedence, a close parentesis or the end of the string, pop the operator and the amount of operands it requires and push them alltogether onto the operand stack until precedence is equal or higher, respective a start parentesis is found, as well as the start of the string. Ex:
    1+2*(3+4)+5
    [1][]0
    [1][+]1
    [1,2][+]1
    [1,2][+,*]2
    [1,2][+,*,(]0
    [1,2,3][+,*,(]0
    [1,2,3][+,*,(,+]1
    [1,2,3,4][+,*,(,+]1
    [1,2,4 3 +][+,*]2 (right parentesis found)
    [1,3 4 + 2 *][+]1 (lower precedence)
    [3 4 + 2 *1 +][]1 (end of string)
    The evaluation can be done at these stages, but if you're writing a script and need variables, using postfix notations reduce the runtime load
    3 4 + 2 *1 + is a postfix expression and is evaluated easily using a single operand stack, as precedence and parentesis are irrelevant.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  10. #10
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    But infix is more intuitive for the user.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  11. #11
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Depends. Some people are used to stack-based calculators.

    Although they're usually older people though
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  12. #12
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    I'd say it depends how you're taught, it would be unintuitive but "real" oop would 3+4 be math.aritmethic.plus(math.aritmethic.three,math.aritmethic.four)
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  13. #13
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    We're not talking real OOP here, we're talking about practical uses (or did I miss something?)
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  14. #14
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    I know, but I like to do that sort of comments on OOP anyway
    If people were taught postfix math in school they'd find infix very hard to comprehend, with precedence and parentesis and everything.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  15. #15
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    But infix is the way we talk, and it's not going to change.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width