Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 12.07.2017
Сообщений: 3

Объясните код создания аналога Excel на С++

14.07.2017, 22:36. Показов 2136. Ответов 0
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Мини Еxel. Реализовать простую электронную таблицу в виде программы, выполняющейся
из командной строки. Она должна уметь обрабатывать ячейки таблицы как и более
продвинутые аналоги, только с упрощенным синтаксисом выражений. Каждая ячейка
может содержать:
- Ничего
- Текстовые строки, которые начинаются с символа '
- Строки-выражения, которые начинаются с символа '=' и могут содержать
неотрицательные целые числа, ссылки на ячейки и простые арифметические
выражения. Скобки запрещены, у всех операций одинаковый приоритет. Поля содержащие выражения и числа
не содержат пробельных символов.
Ссылки на ячейки состоят из одной заглавной латинской буквы и следующей за ней
цифры.

Грамматика ячейки
expression ::= '=' term {operation}
term ::= cell_reference | nonnegative_number
cell_reference ::= [A-Z][1-9]
operation ::= '+' | '-' | '*' | '/'
text ::= ''' {любая последовательность печатных символов}
Процесс обработки:
- Все выражения должны быть заменены на вычисленный результат.
- Все вычисления выполняются с помощью целочисленной арифметики со знаком.
- Ячейки с текстом должны быть вычислены как соответствующий текст без
префикса '.
- Операции над строками текста запрещены.
- В случае любой ошибки вычисления формулы, вычисляемая ячейка должна содержать
слово-сообщение об ошибке, начинающееся с символа '#'. Используйте короткие,
ясные сообщения. Не надо предоставлять подробности об ошибках в выводе.
Программа должна использовать только стандартные библиотеки и классы и не должна
вызывать сторонние программы, библиотеки или системные компоненты.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <map> 
#include <string> 
#include <iostream> 
#include <set> 
#include <assert.h> 
#include <stdexcept>
using namespace std;
 
int parse_integer(const string& val) { 
return atoi(val.c_str()); 
} 
 
string toString(int i) { 
char buf[32]; 
return itoa(i, buf, 10); 
} 
 
struct Table { 
typedef string cell_addr_t; 
typedef map<cell_addr_t, string> cell_str_cont_t; 
typedef map<cell_addr_t, int> cell_num_cont_t; 
typedef set<cell_addr_t> cell_set_t; 
 
Table() : w(0), h(0) {} 
 
size_t w, h; 
cell_str_cont_t exprs, values; 
cell_num_cont_t num_values; 
cell_set_t evaluated, evaluating; 
 
cell_addr_t make_addr(size_t i, size_t j) { 
return char('A' + j) + toString(i + 1); 
} 
 
void input() { //ââîä
 
cin>>h>>w; 
for (size_t i = 0; i < h; ++i) 
for (size_t j = 0; j < w; ++j) { 
string val; 
cin>>val; 
if (!val.empty()) { 
exprs[make_addr(i, j)] = val; 
} 
} 
} 
 
enum cell_kinds { cell_empty, cell_str, cell_num, 
cell_expr, cell_error }; 
 
cell_kinds cell_kind(cell_addr_t addr) { 
if (exprs[addr].empty()) return cell_empty; 
if (exprs[addr][0] == '\'') return cell_str; 
if (exprs[addr][0] == '=') return cell_expr; 
 
//ýòî äîëæíî áûòü ÷èñëî êëåòîê, ïðîâåðèòü ýòî:
const char  *p = exprs[addr].c_str(); 
while (*p) { 
if (!isdigit(*p)) return cell_error; //ïðîâåðêà íà äåñÿòè÷íîå ÷èñëî(isdigit)
p++; 
} 
return cell_num; 
} 
 
void validate_addr(const cell_addr_t& addr) { 
int j = addr[0] - 'A' + 1; 
int i = addr[1] - '0'; 
 
if ((i >= 1) && (j >= 1) && (i <= h) && (j <= w)) return; 
else throw runtime_error("wrong cell address"); 
} 
 
int get_evald_num(cell_addr_t addr) { 
string strval = get_evald_str(addr); //pull evaluation 
 
cell_num_cont_t::iterator it = num_values.find(addr); 
if (it != num_values.end()) { 
return it->second; 
} else { 
if (!strval.empty() && strval[0] == '#') //it's an error 
throw runtime_error(strval.substr(1)); 
throw runtime_error("not a number"); 
} 
} 
 
int read_term(const char*&p) { 
if (isdigit(*p)) { 
int val = atoi(p); 
while (isdigit(*p)) ++p; 
return val; 
} else { 
cell_addr_t addr(p, 2); 
validate_addr(addr); 
p += 2; 
return get_evald_num(addr); 
} 
} 
 
int eval_expr_int(const char* p) { 
assert(p!=0&&*p!=0); 
 
int res = read_term(p); 
 
//read other terms (if any) and perform operation 
do { 
switch (*p) { 
case 0: break; 
case '+': res += read_term(++p);break; 
case '*': res *= read_term(++p);break; 
case '/': res /= read_term(++p);break; 
case '-': res -= read_term(++p);break; 
default: throw runtime_error("error in expression"); 
}; 
} while (*p); 
return res; 
} 
 
string make_error(const string& msg) { 
return "#" + msg; 
} 
 
string eval_expr(cell_addr_t addr) { 
evaluating.insert(addr); 
try { 
int val = eval_expr_int(exprs[addr].c_str() + 1); //skip = 
num_values[addr] = val; 
evaluating.erase(addr); 
return toString(val); 
} catch (runtime_error& e) { 
evaluating.erase(addr); 
return make_error(e.what()); 
} 
} 
 
string get_evald_str(cell_addr_t addr) { 
 
if (evaluated.count(addr)) { //if it's evaluated 
return values[addr]; 
//TODO: check if it's present, do not create empty cells 
} 
 
if (evaluating.count(addr)) { 
evaluating.erase(addr); 
evaluated.insert(addr);//we've evaluated that this is cicrular reference 
string val = make_error("Err"); 
values[addr] = val; 
return val; 
} 
 
string val; 
 
switch (cell_kind(addr)) { 
case cell_empty: break; 
case cell_str: val = exprs[addr].substr(1);break; //skip first char 
case cell_num: 
val = exprs[addr]; 
num_values[addr] = parse_integer(val); 
break; 
case cell_expr: val = eval_expr(addr);break; 
case cell_error: val = make_error("error in expression"); 
} 
evaluated.insert(addr); 
values[addr] = val; 
return val; 
}              
 
void output() { 
for (size_t i = 0; i < h; ++i) { 
for (size_t j = 0; j < w; ++j) { 
cout<<get_evald_str(make_addr(i, j)); 
if (j != w - 1)
cout<<"\t"; 
} 
cout<<endl; 
} 
}
}; 
int main() { 
Table t; 
t.input(); 
t.output(); 
return 0; 
}
Объясните работу функций, пожалуйста.
Миниатюры
Объясните код создания аналога Excel на С++  
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
14.07.2017, 22:36
Ответы с готовыми решениями:

Создание аналога поиска решений из Excel
Всем доброго времени суток. Хотелось бы узнать, возможно ли создать аналог надстройки &quot;Поиск решений&quot; из Excel на VB.NET? Если...

Какие Excel библиотеки необходимы для создания CreateObject('Excel.Application') ?
проблема в том что клиент не хочет пользоваться MS Excel. существуют ли возможность работы с Open Office, Star Office, MS Works. или может...

Объясните принцип создания многопоточности
Здраствуйте, объясните пожалйста как сделать программу многопоточной, у меня есть одна программа, в которой большая нагрузка идет на...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.07.2017, 22:36
Помогаю со студенческими работами здесь

Объясните, пожалуйста, строку создания переменной
input_str db str_len, ?, str_len dup ('$') Я понимаю что создается байтовый массив input_str из str_len символов. Что в этой строке...

Объясните алгоритм создания и сохранения скришота в OpenGL
Здравствуйте. :D Начал понемногу разбирать импорт / экспорт изображений в OpenGL. Для начала решил понять эти алгоритмы и написать простой...

объясните разницу между двумя видами создания объекта
1. объект создается с помощью инициализатора car = { wheels: 4, color: 'red' } 2. а как называется такая запись и...

Процедура создания окна через WinAPI. Объясните одну деталь
Прошу не закидывать помидорами - я только начал осваивать ASM. В чём суть. В одной из обучающих статей приведён пример создания окна в...

Объясните значение операций: дополнение ~lvalue, унарный плюс и минус, операция создания с размещением
Что такое дополнение ~lvalue, унарный плюс и минус и операция создания с размещением, или создания с размещением и инициализацией new...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru