Created
July 3, 2015 15:45
-
-
Save frp/616c62dd73d25dc60c9d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| #include "stdafx.h" | |
| #include <iostream> | |
| #include "Spreadsheet.h" | |
| #include <cassert> | |
| #include <cstring> | |
| #include <string> | |
| #include "SpreadsheetCell.h" | |
| #include <set> | |
| using namespace std; | |
| //Initialization vector | |
| Spreadsheet::Spreadsheet(int height, int widht) | |
| : cells(height, vector<SpreadsheetCell>(widht)) | |
| { | |
| } | |
| //�onverting a numerical index alpha | |
| int Spreadsheet::index(char letterindex) | |
| { | |
| return letterindex - 'A'; | |
| } | |
| //bold numerical index of the cell address | |
| int Spreadsheet::allindex(string index) | |
| { | |
| string address = ""; | |
| int a; | |
| for (int i = 1; i < index.length(); i++) | |
| { | |
| address = address + index[i]; | |
| } | |
| return stoi(address) - 1; | |
| } | |
| //function input | |
| void Spreadsheet::filling() | |
| { | |
| string cell; | |
| for (int i = 0; i < cells.size(); i++) | |
| { | |
| for (int j = 0; j < cells[i].size(); j++) | |
| { | |
| cin >> cell; | |
| cells[i][j].setString(cell); | |
| } | |
| } | |
| } | |
| //function output | |
| void Spreadsheet::outlet() | |
| { | |
| for (int i = 0; i < cells.size(); i++) | |
| { | |
| for (int j = 0; j < cells[i].size(); j++) | |
| { | |
| cout << cells[i][j].getString() << " "; | |
| } | |
| cout << endl; | |
| } | |
| } | |
| //recording function in the cell result | |
| void Spreadsheet::calculation() | |
| { | |
| set<pair<int, int> > calculated; | |
| for (int i = 0; i < cells.size(); i++) | |
| { | |
| for (int j = 0; j < cells[i].size(); j++) | |
| { | |
| if (cells[i][j].getString()[0] == '=')cells[i][j].setString(calc(i, j, calculated)); | |
| assert(calculated.size() == 0); | |
| } | |
| } | |
| } | |
| //Check correct number | |
| static bool validateNumber(string str) | |
| { | |
| if (str[0] == '-') | |
| str = str.substr(1); | |
| if (str.length() == 0) return false; | |
| for (auto& c : str) | |
| if (!isdigit(c)) | |
| return false; | |
| return true; | |
| } | |
| //Check correctness address | |
| static bool validateAddress(string str) | |
| { | |
| return isalpha(str[0]) && validateNumber(str.substr(1)); | |
| } | |
| //Calculation of the cell content | |
| int Spreadsheet::ApplyOperation(int arithmeticoperation, int result, string operand) | |
| { | |
| if (arithmeticoperation == '*') return result * stoi(operand); | |
| else if (arithmeticoperation == '/') return result / stoi(operand); | |
| else if (arithmeticoperation == '-') return result - stoi(operand); | |
| else if (arithmeticoperation == '+') return result + stoi(operand); | |
| else assert(false); | |
| } | |
| static string selectOperand(const string& cell, int& g) | |
| { | |
| string operand; | |
| while (cell[g] != '*' && cell[g] != '/' && cell[g] != '-' && cell[g] != '+' && cell[g] != '\0') | |
| { | |
| operand += cell[g]; | |
| g++; | |
| } | |
| return operand; | |
| } | |
| class CalculatedGuard | |
| { | |
| private: | |
| set<pair<int, int>>& theSet; | |
| int m_i, m_j; | |
| public: | |
| CalculatedGuard(set<pair<int,int>>& calculated, int i, int j): theSet(calculated), m_i(i), m_j(j) { theSet.insert(make_pair(i, j)); } | |
| ~CalculatedGuard() { theSet.erase(make_pair(m_i, m_j)); } | |
| }; | |
| static const string errorValue = "#IncorrectData", infiniteRecursion = "#InfiniteRecursion"; | |
| string Spreadsheet::calculateOperandValue(string operand, set<pair<int, int>> &calculated) | |
| { | |
| if (validateNumber(operand)) | |
| return operand; | |
| else if (validateAddress(operand)) | |
| return calc(allindex(operand), index(operand[0]), calculated); | |
| else | |
| return errorValue; | |
| } | |
| static bool validateOperation(char op) | |
| { | |
| return op == '+' || op == '-' || op == '*' || op == '/'; | |
| } | |
| //calculation function | |
| string Spreadsheet::calc(int i, int j, set<pair<int, int>>& calculated) | |
| { | |
| if (calculated.find(make_pair(i, j)) != calculated.end()) | |
| return infiniteRecursion; | |
| CalculatedGuard guard(calculated, i, j); | |
| int g = 1; | |
| string cell = cells[i][j].getString(); | |
| if (cell[0] == '#') | |
| { | |
| calculated.erase(make_pair(i, j)); | |
| return cell; | |
| } | |
| if (cell[0] == '=') | |
| { | |
| string operand = calculateOperandValue(selectOperand(cell, g), calculated); | |
| if (operand[0] == '#') // error happened | |
| return operand; | |
| if (!validateNumber(operand)) | |
| return errorValue; | |
| int result = stoi(operand); | |
| while (g < cell.size()) | |
| { | |
| char operation = cell[g++]; | |
| if (!validateOperation(operation)) | |
| return errorValue; | |
| operand = calculateOperandValue(selectOperand(cell, g), calculated); | |
| if (operand[0] == '#') // error happened | |
| return operand; | |
| if (!validateNumber(operand)) | |
| return errorValue; | |
| result = ApplyOperation(operation, result, operand); | |
| } | |
| return to_string(result); | |
| } | |
| else | |
| return cell; | |
| } |
This file contains hidden or 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
| #pragma once | |
| #include <vector> | |
| #include "SpreadsheetCell.h" | |
| #include <set> | |
| class Spreadsheet | |
| { | |
| private: | |
| vector<vector<SpreadsheetCell> > cells; | |
| string calculateOperandValue(string operand, set<pair<int, int>>& calculated); | |
| public: | |
| Spreadsheet(int height, int widht); | |
| int index(char letterindex); | |
| int allindex(string index); | |
| void calculation(); | |
| string calc(int i, int j, set<pair<int, int>>& calculated); | |
| void filling(); | |
| void outlet(); | |
| int ApplyOperation(int arithmeticoperation, int result, string operand); | |
| //~Spreadsheet(); | |
| }; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment