Posting code? Use the [code] or [php] tags.
I don't care, I'm still free. You can't take the sky from me.
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-
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.Code:set smartindent set tabstop=4 set shiftwidth=4 set expandtab
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.
my messy c++ code that works for rpn:
output: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 answer = 0; 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) { answer = arguments[arg_count-2] + arguments[arg_count-1]; arguments[arg_count-2] = answer; arg_count--; } else if(arg_count <= 1) { answer += arguments[arg_count-1]; arg_count--; } } else if(char_temp == 37) // % operator { if(arg_count > 1) { answer = static_cast<int>(arguments[arg_count-2]) % static_cast<int>(arguments[arg_count-1]); arguments[arg_count-2] = answer; arg_count--; } else if(arg_count <= 1) { answer = static_cast<int>(arguments[arg_count-1]) % static_cast<int>(answer); arg_count--; } } else if(char_temp == 42) // * operator { if(arg_count > 1) { answer = arguments[arg_count-2] * arguments[arg_count-1]; arguments[arg_count-2] = answer; arg_count--; } else if(arg_count <= 1) { answer *= arguments[arg_count-1]; arg_count--; } } else if(char_temp == 45) // - operator { if(arg_count > 1) { answer = arguments[arg_count-2] - arguments[arg_count-1]; arguments[arg_count-2] = answer; arg_count--; } else if(arg_count <= 1) { answer -= arguments[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 { answer = arguments[arg_count-2] / arguments[arg_count-1]; arguments[arg_count-2] = answer; arg_count--; } } else if(arg_count <= 1) { if(arguments[arg_count-1] == 0) { cout << "Dividing by zero!" << endl; error = true; index = in.size(); } else { answer /= arguments[arg_count-1]; arg_count--; } } } else if(char_temp == 94) // ^ operator { if(arg_count > 1) { answer = pow(arguments[arg_count-2], arguments[arg_count-1]); arguments[arg_count-2] = answer; arg_count--; } else if(arg_count <= 1) { answer = pow(arguments[arg_count-1], answer); arg_count--; } } else { cout << "Unrecognized token." << endl; error = true; index = in.size(); } index++; }while(index < in.size()); if(arg_count == 1 && !error) { cout << answer << endl; } 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; }
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.
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
rpn.hCode:#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; }
and rpn.cppCode:#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
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
tyvm, will edit my code.
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 function
int 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 string
double 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.
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
computer-howto
Linux is not windows
Fluxbox & Flux menu how to
Programming is an art. Learn it, Live it, Love it!
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).
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.
Bookmarks