# Thread: Beginner Programming Challenge #11

1. ## Re: Beginner Programming Challenge #11

Originally Posted by tooatw
i see that you modified it
so tell us exactly what happens
if the result is an integer only display one digit after the dot (why?) otherwise display 10?
why cant it be standard one digit after the , or standard 10
Yes I did modify it, sorry. I wanted to clarify that division should be true division - that means 10 3 / should be 3.333..., not 3.0. You should cast to a float before you do the division, not after.

2. Dark Roasted Ubuntu
Join Date
Jun 2009
Beans
1,043

## Re: Beginner Programming Challenge #11

Just a quick fyi that would help all of us studying code posted here- edit your text editor's config files to enter spaces instead of tab characters when the tab key is pressed. For example- in my .vimrc I have these lines-
Code:
```set smartindent
set tabstop=4
set shiftwidth=4
set expandtab```
I don't recall exactly what each line does- I copied it off of some website with VIM information. All that matters is that when I press the tab key - I get four spaces instead of a tab character.

I copied and pasted the above code into vim, and I've got a huge mess to clean up before I can run or study it.

BM

edit- nevermind- I think I figured out what my problem was...
Last edited by blur xc; March 29th, 2010 at 10:21 PM.

3. ## Re: Beginner Programming Challenge #11

my messy c++ code that works for rpn:

Code:
```#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>
#include <cmath>
#include <iomanip>

using namespace std;

void rpn(const vector<string>& in)
{
string out, temp;
double arguments[20] = {0};
int arg_count = 0;
unsigned int index = 0;
bool error = false;

do{
temp = in[index];
int int_temp = atoi(temp.c_str());	//used to check if word is a number
char char_temp = temp[0];		//used to check if word is an operator

if(int_temp > 0) 			//word is a non-zero number
{
arguments[arg_count] = int_temp;
arg_count ++;
}
else if(char_temp == 48) 		//word is zero
{
arguments[arg_count] = 0;
arg_count ++;
}
else if(index <= 1)		//encountered an operator/gibberish before having 2 arguments
{
error = true;
index = in.size();
cout << "Error in input." << endl;
}
else if(char_temp == 43) 		// + operator
{
if(arg_count > 1)
{
arg_count--;
}
else if(arg_count <= 1)
{
arg_count--;
}
}
else if(char_temp == 37) 		// % operator
{
if(arg_count > 1)
{
arg_count--;
}
else if(arg_count <= 1)
{
arg_count--;
}

}
else if(char_temp == 42)		 // * operator
{
if(arg_count > 1)
{
arg_count--;
}
else if(arg_count <= 1)
{
arg_count--;
}
}
else if(char_temp == 45) 		// - operator
{
if(arg_count > 1)
{
arg_count--;
}
else if(arg_count <= 1)
{
arg_count--;
}
}
else if(char_temp == 47) 		// / operator
{
if(arg_count > 1)
{
if(arguments[arg_count-1] == 0)
{
cout << "Dividing by zero!" << endl;
error = true;
index = in.size();
}
else
{
arg_count--;
}
}
else if(arg_count <= 1)
{
if(arguments[arg_count-1] == 0)
{
cout << "Dividing by zero!" << endl;
error = true;
index = in.size();
}
else
{
arg_count--;
}
}
}
else if(char_temp == 94) 		// ^ operator
{
if(arg_count > 1)
{
arg_count--;
}
else if(arg_count <= 1)
{
arg_count--;
}
}
else
{
cout << "Unrecognized token." << endl;
error = true;
index = in.size();
}

index++;

}while(index < in.size());

if(arg_count == 1 && !error)
{
}
else if(!error)
{
cout << "Error in input." << endl;
}
}

int main(int argc, char* argv[])

{
if(argc != 2)
{
cout << "Must enter a file to evaluate at the command line." << endl;
}

fstream in;
in.open(argv[1], ios::in);
string line, word;
cout.precision(10);

if(in.good())
{
while(getline(in, line))  //get lines
{
vector<string> words;
cout << "> " << line << endl;

while(line != "") //while line is non-empty, parse line into words
{
size_t found = 0;				//find space char
found = line.find_first_of(" ");
if(found < line.size())
{
word = line.substr(0,found);		//create word based on substring of line
words.push_back(word);			//add word to the vector
line = line.substr(found+1);		//remove word from line
}
else  						//no more whitespace - add last word
{
words.push_back(line);
line = "";
}
}

rpn(words);		//call rpn to process the words
//cout << endl;
}
}
else
{
cout << "Error opening file." << endl;
}
in.close();

return 0;

}```
output:
Code:
```chris@chris-desktop:~/Code/Projects/Challenge 11\$ ./driver test
> 3 4 +
7
> 10 3 /
3.333333333
> 2 5 ^
32
> 10 2 %
0
> 24 12 3 + 4 % / 6 - 4 * 3 ^
512
> 10 2 2 % /
Dividing by zero!
> 10 + 10
Error in input.
> aw4ojghsiu5esrgs56u7ikdyjdt drthisu 5 hrtgh 5 5 +
Error in input.
> 45 6 + / & 4
Unrecognized token.```

4. ## Re: Beginner Programming Challenge #11

Here is a little cleaner implementation. rpn is a class now, and now the user has a choice to open a file or enter a rpn string of their own.

driver.cpp
Code:
```#include "rpn.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>

using namespace std;

int main(int argc, char* argv[])

{
string choose = "q";
string rpn_eval = "";
string filename = "";

do{
cout << "(O)pen a file, (E)nter a string, or (Q)uit: ";
getline (cin, choose);

if(choose == "O" || choose == "o")
{
cout << "Enter the name of the file to open: ";
getline (cin, filename);
fstream in;
in.open(filename.c_str(), ios::in);
if(in.good())
{
string line;
while(getline(in, line))  //get lines
{
cout << "> " << line << endl;
rpn one(line);
cout << one << endl;
}
in.close();
}
else
{
cout << "Error opening file." << endl;
}
}

else if(choose == "E" || choose == "e")
{
cout << "Enter a RPN string to be evaluated: ";
getline (cin, rpn_eval);
rpn one(rpn_eval);
cout << one << endl;
}
}while(choose != "Q" && choose !="q");

return 0;

}```
rpn.h
Code:
```#ifndef RPN_H
#define RPN_H
#include <string>
#include <vector>

class rpn

{
private:
std::string s_out;
const std::string double_to_string(const double& input) const;

public:

rpn(std::string& line);
friend std::ostream& operator<<(std::ostream& out, const rpn& show) {return out << show.s_out;}

};
#endif```
and rpn.cpp
Code:
```#include "rpn.h"
#include <string>
#include <vector>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <sstream>
using namespace std;

const string rpn::double_to_string(const double& input) const
{
ostringstream oss;
oss << input;
return oss.str();
}

rpn::rpn(string& line)
{
string word;
vector<string> words;

if(line == "")
{
s_out = "Empty string sent for evaluation!";
return;
}

while(line != "") //while line is non-empty, p**** line into words
{
size_t found = 0;				//find space char
found = line.find_first_of(" ");
if(found < line.size())
{
word = line.substr(0,found);		//create word based on substring of line
words.push_back(word);			//add word to the vector
line = line.substr(found+1);		//remove word from line
}
else  						//no more whitespace - add last word
{
words.push_back(line);
line = "";
}
}

string temp;
double arguments[20] = {0};
int arg_count = 0;
unsigned int index = 0;
bool error = false;

do{
temp = words[index];
int int_temp = atoi(temp.c_str());	//used to check if word is a number
char char_temp = temp[0];		//used to check if word is an operator

if(int_temp > 0) 			//word is a non-zero number
{
arguments[arg_count] = int_temp;
arg_count ++;
}
else if(char_temp == 48) 		//word is zero
{
arguments[arg_count] = 0;
arg_count ++;
}
else if(index <= 1)		//encountered an operator/gibberish before having 2 arguments
{
error = true;
index = words.size();
if(char_temp == 43 || char_temp == 37 || char_temp == 42 || char_temp == 45 || char_temp == 47 || char_temp == 94)
s_out = "Encountered an operator before having at least two arguments.";
else
s_out = "Unrecognized token.";
}
else if(char_temp == 43) 		// + operator
{
arguments[arg_count-2] = arguments[arg_count-2] + arguments[arg_count-1];
arg_count--;

}
else if(char_temp == 37) 		// % operator
{
arguments[arg_count-2] = static_cast<int>(arguments[arg_count-2]) % static_cast<int>(arguments[arg_count-1]);
arg_count--;
}
else if(char_temp == 42)		 // * operator
{
arguments[arg_count-2] = arguments[arg_count-2] * arguments[arg_count-1];
arg_count--;
}
else if(char_temp == 45) 		// - operator
{
arguments[arg_count-2] = arguments[arg_count-2] - arguments[arg_count-1];
arg_count--;
}
else if(char_temp == 47) 		// / operator
{
if(arguments[arg_count-1] == 0)
{
s_out = "Divided by zero.";
error = true;
index = words.size();
}
else
{
arguments[arg_count-2] = arguments[arg_count-2] / arguments[arg_count-1];
arg_count--;
}
}
else if(char_temp == 94) 		// ^ operator
{
arguments[arg_count-2] = pow(arguments[arg_count-2], arguments[arg_count-1]);
arg_count--;
}
else
{
s_out = "Unrecognized token.";
error = true;
index = words.size();
}

index++;

}while(index < words.size());

if(arg_count == 1 && !error)
{
s_out = double_to_string(arguments[arg_count-1]);
}
else if(!error)
{
s_out = "Incorrect number of arguments/operators.";
}
}```
Last edited by WillFerrellLuva; March 31st, 2010 at 03:51 PM. Reason: More changes to my code

5. ## Re: Beginner Programming Challenge #11

Originally Posted by WillFerrellLuva
I have an issue though. I dont want to open the std namespace in rpn.h, however every time i try to compile without it i get the following error:
Code:
`rpn.h:14: error: ISO C++ forbids declaration of ‘vector’ with no type`
Anybody know how I can correctly declare that vector?
Just like anything else from the STL, prepend it with std::

Code:
`rpn(const std::vector<std::string>& words);`

6. ## Re: Beginner Programming Challenge #11

tyvm, will edit my code.

7. 5 Cups of Ubuntu
Join Date
Mar 2010
Beans
31
Distro
Ubuntu 9.10 Karmic Koala

## Re: Beginner Programming Challenge #11

Code:
```alexander@amd64:~/1\$ ./rpn
> 3 4 +
7.0
> 10 3 /
3.3333333333
> 2 5 ^
32.0
> 10 2 %
0.0
> 24 12 3 + 4 % / 6 - 4 * 3 ^
512.0
> 10 2 2 % /
Divided by Zero
> 10 + 10
Not enough operands
> 10 10 10 +
Too many operands
>
> aw4ojghsiu5esrgs56u7ikdyjdt drthisu 5 hrtgh 5 5 +
Unrecognized token
> 45 6 + / & 4
Unrecognized token
> exit
alexander@amd64:~/1\$```
PHP Code:
``` // Beginner Programming Challenge #11#include <stdio.h> //standard for i/o#include <stdlib.h> // standard again#include <string.h> // string library#include <math.h> // for the power functionint i,true=2,k[99],is,is2,w,iv,si,temp1,temp2,dubios,nc,zero,neo;/* i is standard true is something that is always true since i don't know the c version of "while true" is is the empty spaces in the string counter is2 is the 'how much till the end' counter w is like a secondary i si counts how many words are between two spaces since operators can only use one space dubios seeks dubious behaviour nc is the number counter number is the temporary number zero alerts if someone wants to divide by 0 neo is the not enough operators counter num is the number array  */char x[100];//the stringdouble number,num[99];int main(){    while (true){        for (i=0;i<99;++i) num[i]=k[i]=0; // reset the arrays        i=is=is2=w=iv=si=dubios=nc=zero=neo=number=0; // reset the variables        printf("> ");        gets(x);        if (strcmp(x,"exit")== 0) break;        for (i=0;i<strlen(x);++i){ //find empty spaces and keep track of them in k            if (x[i]==' ') {                    k[is] = i;                     ++is;            }        }        if (k[is] != strlen(x)) {k[is]=strlen(x);++is;} // add to the counter the last element        iv=0;// needed later on        for (w=0;w<is;++w){  // for all the empty spaces            is2=k[w]-iv; //how many characters does the string fragment have            number=0; //reset the number            for (i=iv;i<k[w];++i){ //figure out what the number is                si=is2;                switch(x[i]){                    case '0'...'9': number += ((x[i] - '0') * pow( 10.0 , is2-1));                                    --is2 ;                                    if (is2==0) { //when is reaches 0 save the number                                         num[nc]=number;                                        ++nc;                                    }                                    break;                        case  '+':    if (si==1){                                     if(nc>1){                                         num[nc-2]=num[nc-2]+num[nc-1];                                         num[nc-1]=num[nc];                                        --nc;                                    }                                     else ++neo;                                }                                 else ++dubios;break;                    case  '-':    if (si==1){                                     if(nc>1){                                         num[nc-2]=num[nc-2]-num[nc-1];                                         num[nc-1]=num[nc];                                        --nc;                                    }                                     else ++neo;                                }                                 else ++dubios;break;                    case  '/':    if (si==1){                                     if(nc>1){                                         if (num[nc-1]!=0){                                             num[nc-2]=num[nc-2]/num[nc-1];                                             num[nc-1]=num[nc];                                             --nc;                                        }                                         else ++zero;                                    }                                      else ++neo;                                }                                 else ++dubios;break;                    case  '*':    if (si==1){                                     if(nc>1){                                         num[nc-2]=num[nc-2]*num[nc-1];                                         num[nc-1]=num[nc];                                         --nc;                                    }                                     else ++neo;                                }                                 else ++dubios;break;                    case  '^':    if (si==1){                                     if(nc>1){                                         num[nc-2]=pow(num[nc-2],num[nc-1]);                                         num[nc-1]=num[nc];                                         --nc;                                    }                                     else ++neo;                                }                                 else ++dubios;break;                    case  '%':    if (si==1){                                     if(nc>1){                                         temp1=num[nc-2];                                        temp2=num[nc-1];                                        num[nc-2]=temp1%temp2;                                         num[nc-1]=num[nc];                                         --nc;                                    }                                     else ++neo;                                }                                 else ++dubios;break;                    //for all cases of operands if the string fragment is wider than 1 caracter mark it as dubious behavior and if you dont have at least 2 operands mark it down                    default: ++dubios;break;                    //anything else goes to dubious behaviour                }            }            iv=k[w];//we need this to find out the word size            ++iv;        }    if (dubios==0){//if nothing is dubious ... this should be obvious        if (zero!=0) printf("Divided by Zero\n");         else if (neo>0) printf("Not enough operands\n");        else if (neo==0 &&nc>1) printf("Too many operands\n");        else if (nc==0); //if empty string        else {            temp1=num[nc-1];            if (temp1==num[nc-1])printf("%.1f\n",num[nc-1]);            else printf("%.10f\n",num[nc-1]);        }        }// if everything goes to plan print the number     else printf("Unrecognized token\n");    }return 0;}  ```
Last edited by tooatw; March 30th, 2010 at 09:54 AM.

8. ## Re: Beginner Programming Challenge #11

Originally Posted by lavinog
Is it just me, or are these Beginner challenges more likely suited for the intermediate challenges?
I think the very fact that you have to ask that means that your correct. Whilst these are supposed to be challenges, a beginner should be able to accomplish them. By beginner, I mean someone who started coding a few weeks ago, not someone who has been coding a while but does not consider themselves very good.

I would like to remind all OP's of these challenges to please bear in mind the skillset of your audience. We do not want to alienate the very new programmers.

I would also like to remind beginners that although this task may seem way too difficult, it is not. With some research of rpn and algorithms, along with some active discussion, I believe anyone could accomplish this. If you need help, remember that the sponsors of these challenges are more then happy to give you a hand, we are on irc.freenode.net in #ubuntu-beginners-dev

Bodsda

9. ## Re: Beginner Programming Challenge #11

edited my code a few posts up. rpn now takes a string and writes a string with an overloaded << operator (parsing the string is now handled by rpn).

10. Just Give Me the Beans!
Join Date
Aug 2007
Beans
46

## Re: Beginner Programming Challenge #11

This is really limited, without using even standard input or implementing any error checking. Just for fun, a bit of scheme:

Code:
```;I don't know how to easily do standard input, so please just change
;the inp list to represent the equation you want to test it with.
(define inp '(3 4 * 9.2 /))

;Immedialty call helper function with an empty stack
(define (pol expr) (pol-helper '() expr))

;Helper function. As you can see only +, -, *, and / have been defined.
(define (pol-helper stack expr) (
if(eqv? expr '()) (car stack)
(cond ((eqv? (car expr) '+)
(pol-helper
(cons (+ (cadr stack) (car stack)) (cddr stack)) (cdr expr)))
((eqv? (car expr) '-)
(pol-helper
(cons (- (cadr stack) (car stack)) (cddr stack)) (cdr expr)))
((eqv? (car expr) '*)
(pol-helper
(cons (* (cadr stack) (car stack)) (cddr stack)) (cdr expr)))
((eqv? (car expr) '/)
(pol-helper
(cons (/ (cadr stack) (car stack)) (cddr stack)) (cdr expr)))
(else
(pol-helper
(cons (car expr) stack) (cdr expr))))))

;Call the polish expression evaluator with the input. Display result.
(display (pol inp))
(newline)```
Last edited by Coward; March 30th, 2010 at 08:07 PM.

#### Posting Permissions

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