• Coding
  • Exercise - Polish Calculator

Here's yet another classical problem in programming. This problem is not language specific, although I would strongly advice using C or C++.

Reverse Polish Notation

From Wikipedia:

"The Reverse Polish Notation (RPN) is a mathematical notation wherein ever operator follows all of its operands".

An example is often worth a thousand words. So there goes:

( 5 + ( ( 3 * 13 ) + 1 ) ) / 9

is equivalent to:

5 3 13 * 1 + + 9 /

And here are the steps to resolve this equation:

5 39 1 + + 9 /
5 40 + 9 /
45 9 /
5

Take a look at each step, and you'll understand how this notation works.

Exercise

Develop a RPN Calculator, a program that would take as an input a RPN string and would output the result.
Then use this program to give the result of:

23 76 66 + * 56 8 / - 13 12 * -
31 54 57 + 102 - * 76 12 3 + *
1 34 26 57 + - 49 + / 13 8 - 7 * 5 65 - -
rahmu, the last two equations have a missing operator (number of operators = number of entries - 1) and the last equation would give division by zero since 26 + 57 = 83 and 34 - 83 = -49 which would yield:

1 0 / 13 8 - 7 * 5 65 - -
|______ division by zero (1/0)

As for the code and the answer to the first equation:
clear all
clc

fid = fopen('RPN input.txt');     % Open file where input strings of
                                  % arithmetic equation are located
while ~feof(fid)                  % Read input strings until end of file
    numeric = [];
    C = {};
    n = 1;
    tline = fgetl(fid);           % Read current line
    while ~isempty(tline)         % Store data of input line as cell of strings
        k = 0;
        if (k+1 < size(tline,2))
            while ~isequal(tline(k+1),' ') 
                  k = k + 1;
            end
        else
            k = 1;
        end
        C{n} = tline(1:k); 
        n = n + 1;
        if (size(tline,2) > 1)
            tline = tline(k+2:end);
        else
            tline = [];
        end
    end
    for i = 1:size(C,2)           % Perform arithmetic operation
        if ~isnan(str2double(C{i}))
           numeric = horzcat(numeric,str2double(C{i}));
        else
           num1 = numeric(end-1); % First entry for arithmetic operation
           num2 = numeric(end);   % Second entry for arithmetic operation
           switch C{i}
                 case '+'
                      result = num1 + num2;
                 case '-'
                      result = num1 - num2;
                 case '*'
                      result = num1 * num2;
                 case '/'
                      result = num1/num2;
                 otherwise
                      error('Invalid arithmatic operation.')
           end
           numeric = numeric(1:end-1);
           numeric(end) = result;
        end
    end
    disp(strcat('The result of the arithmetic operation is:',num2str(numeric)));
end
status = fclose(fid);             % Close file
Answer: The result of the arithmetic operation is:3103

The second arithmetic operation would give the following result:
The result of the arithmetic operation is:279 1140
That's the point of the exercise. I am not repeating the same exercise three times. We're not at school :P

Your program should be able to catch those errors.
rahmu wroteThat's the point of the exercise. I am not repeating the same exercise three times. We're not at school :P

Your program should be able to catch those errors.
Fine, whatever, my work here is done then cause my program caught them:

The result of the arithmetic operation is:3103
The result of the arithmetic operation is:279 1140
Warning: Divide by zero.
??? Subscript indices must either be real positive integers or logicals.

Next...
Your second answer is incorrect: it should've returned "Missing operand".

Your third answer should return a warning more intelligible.

Both operations should exit gracefully.
clear all
clc

fid = fopen('RPN input.txt');     % Open file where input strings of
                                  % arithmetic equation are located
while ~feof(fid)                  % Read input strings until end of file
    numeric = [];
    C = {};
    n = 1;
    tline = fgetl(fid);           % Read current line
    while ~isempty(tline)         % Store data of input line as cell of strings
        k = 0;
        if (k+1 < size(tline,2))
            while ~isequal(tline(k+1),' ') 
                  k = k + 1;
            end
        else
            k = 1;
        end
        C{n} = tline(1:k); 
        n = n + 1;
        if (size(tline,2) > 1)
            tline = tline(k+2:end);
        else
            tline = [];
        end
    end
    for i = 1:size(C,2)           % Perform arithmetic operation
        if ~isnan(str2double(C{i}))
           numeric = horzcat(numeric,str2double(C{i}));
        else
           num1 = numeric(end-1); % First entry for arithmetic operation
           num2 = numeric(end);   % Second entry for arithmetic operation
           switch C{i}
                 case '+'
                      result = num1 + num2;
                 case '-'
                      result = num1 - num2;
                 case '*'
                      result = num1 * num2;
                 case '/'
                      if isinf(num1/num2)
                          break;
                      else
                          result = num1/num2;
                      end
                 otherwise
                      error('Invalid arithmatic operation.')
           end
           numeric = numeric(1:end-1);
           numeric(end) = result;
        end
    end
    if (size(numeric,2) == 2)
        disp('Missing 1 operand.');
    elseif (size(numeric,2) > 1)
        disp(strcat('Missing',' ',num2str(size(numeric,2)-1),' operands.'));
    else    
        disp(strcat('The result of the arithmetic operation is:',...
                    num2str(numeric)));
    end
end
status = fclose(fid);             % Close file
Answer:
The result of the arithmetic operation is:3103
Missing 1 operand.
Warning: Divide by zero.
Missing 1 operand.