Skip to content

Instantly share code, notes, and snippets.

@frp
Created July 3, 2015 15:45
Show Gist options
  • Select an option

  • Save frp/616c62dd73d25dc60c9d to your computer and use it in GitHub Desktop.

Select an option

Save frp/616c62dd73d25dc60c9d to your computer and use it in GitHub Desktop.
#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;
}
#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