Last active
December 25, 2015 06:09
-
-
Save zhezheng/6929850 to your computer and use it in GitHub Desktop.
Spreadsheet Calculator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*************************** | |
test case format: | |
3 2 | |
A2 | |
4 5 * | |
A1 | |
A1 B2 / 2 + | |
3 | |
39 B1 B2 * / | |
****************************/ | |
#include <iostream> | |
#include <string> | |
#include <stack> | |
#include <map> | |
#include <iomanip> | |
using namespace std; | |
void initsheet(map<int,string> &str_map, int &width, int &height); | |
double operaHelper(double first, double second, char opt); | |
double opera(int order, map<int,string> str_map, map<int,double> &num_map, map<int,bool> &num_flag, int width, int height); | |
int main() { | |
map<int,string> str_map; | |
map<int,double> num_map; | |
map<int,bool> num_flag; | |
int width,height; | |
initsheet(str_map,width,height); | |
for(int i=0;i<width*height;i++) { | |
if(num_flag[i] == false) { | |
num_map[i] = opera(i, str_map, num_map, num_flag, width, height); | |
} | |
} | |
cout << width << " " << height << endl; | |
for(int i=0;i<int(num_map.size());i++) { | |
cout << fixed; | |
cout << setprecision(5) << num_map[i] << endl; | |
} | |
return 0; | |
} | |
//initialize the spreadsheet, first line is width and height, then each cell A(1), A(2), B(1)....... | |
void initsheet(map<int,string> &str_map, int &width, int &height) { | |
string wh; | |
getline(cin,wh); | |
int num=0; | |
for(int i=0;i<int(wh.size());i++) { | |
if(wh[i]>='0' && wh[i]<='9'){ | |
num = num*10 + int(wh[i] - '0'); | |
} | |
else if(wh[i]==' ') { | |
width = num; | |
num = 0; | |
} | |
} | |
height = num; | |
for(int i=0;i<width*height;i++) { | |
string str_temp; | |
getline(cin,str_temp); | |
str_map[i] = str_temp; | |
} | |
} | |
//operator help function, deal with operator '+', '-', '*', '/' between two numbers | |
double operaHelper(double first, double second, char opt) { | |
if(opt == '+'){ | |
return first + second; | |
} | |
else if(opt == '-'){ | |
return first - second; | |
} | |
else if(opt == '*'){ | |
return first * second; | |
} | |
else{ | |
return first / second; | |
} | |
} | |
// Key function.... | |
// Scan the string from beginning | |
// If it's a number, push it to the stack | |
// If it's a operator, pop two numbers from the stack, after calculation, push the result to the stack | |
// If it's a symbol of cell, do the recursion | |
// After finding value of a cell, set its flag true | |
double opera(int order, map<int,string> str_map, map<int,double> &num_map, map<int,bool> &num_flag, int width, int height) { | |
stack<double> num_stk; | |
string str = str_map[order]; | |
double num_temp = 0; | |
bool hasNum = false; | |
for(int i=0; i<int(str.length());i++) { | |
if(str[i]>='A' && str[i]<='Z') { | |
int width_temp = 0; | |
int order_temp = int(str[i] - 'A')*width; | |
for(int j=i+1;j<int(str.length());j++) { | |
if(str[j] == ' ') { | |
break; | |
} | |
width_temp = 10*width_temp + int(str[j] - '0'); | |
i = j; | |
} | |
order_temp += width_temp - 1; | |
if(num_flag[order_temp]) { | |
num_stk.push(num_map[order_temp]); | |
} | |
else { | |
num_temp = opera(order_temp, str_map, num_map, num_flag, width, height); | |
num_stk.push(num_temp); | |
num_temp = 0; | |
} | |
} | |
else if(str[i]>='0' && str[i]<='9') { | |
num_temp = 10*num_temp + double(str[i] - '0'); | |
hasNum = true; | |
} | |
else if(str[i] == ' ') { | |
if(hasNum){ | |
num_stk.push(num_temp); | |
num_temp = 0; | |
hasNum = false; | |
} | |
} | |
else if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/') { | |
double second = num_stk.top(); | |
num_stk.pop(); | |
double first = num_stk.top(); | |
num_stk.pop(); | |
double result = operaHelper(first,second,str[i]); | |
num_stk.push(result); | |
} | |
} | |
if(hasNum) { | |
num_stk.push(num_temp); | |
hasNum = false; | |
} | |
num_map[order] = num_stk.top(); | |
num_flag[order] = true; | |
return num_stk.top(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment