Big Summa. Заданы две текстовые строки, состоящие исключительно из цифр и не более чем одной точки.
Предполагается, что строки задают представление чисел в q-ричной системе счисления. Построить строку, являющуюся их суммой.
q | A | B | A+B | Комментарий. |
10 | 126740 | 546.967 | 127286.967 | Тест пройден. |
8 | 2360 | 7521 | 12101 | Тест пройден. |
2 | 1011001 | 1101 | 100110 | Тест пройден. |
3 | 1210.012 | 1112.1 | 10022.112 | Тест пройден. |
10 | 4356.98 | 67.975 | 4424.955 | Тест пройден. |
Код программы (string):
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 |
#include <iostream> #include <string> using namespace std; unsigned int dot_position (const string &a, const string &b) { unsigned int dota=0, dotb=0; for (unsigned int i=0; a[i]; i++) { if (a[i]=='.') dota=i; } if (dota==0) dota=a.length(); for (unsigned int i=0; b[i]; i++) { if (b[i]=='.') dotb=i; } if (dotb==0) dotb=b.length(); return max (dota, dotb); } unsigned int length_before_dot (const string &a) { unsigned int i=0; for (; a[i]; i++) { if (a[i]=='.') break; } return i; } int length_after_dot (const string &a) { return a.length()-length_before_dot(a)-1; } int main() { const int d='0'; int q; cin >> q; string a, b, c; cin >> a >> b; if (length_after_dot(a)<0) a.insert(a.length(),"."); // Если число без точки, то условно ставим её. if (length_after_dot(b)<0) b.insert(b.length(),"."); if (length_after_dot(a)>length_after_dot(b)) { for (unsigned int i=a.length()-1; i>length_before_dot(a)+length_after_dot(b); i--) { c.insert(c.begin(),a[i]); } } else if (length_after_dot(a)<length_after_dot(b)) { for (unsigned int i=b.length()-1; i>length_before_dot(b)+length_after_dot(a); i--) { c.insert(c.begin(),b[i]); } } if (length_before_dot(a)<dot_position(a,b)) { a.insert(0,dot_position(a,b)-length_before_dot(a),'0'); } else if (length_before_dot(b)<dot_position(a,b)) { b.insert(0,dot_position(a,b)-length_before_dot(b),'0'); } int p=0; for (int i=min(a.length(),b.length())-1; i>=0; i--) { string k; if (a[i]=='.') { c.insert(0,"."); --i; } if (a[i]+b[i]-2*d+p-q<0) { k=to_string(a[i]+b[i]-2*d+p); p=0; } else { k=to_string(a[i]+b[i]-2*d+p-q); p=1; } c.insert(0,k); } if (p==1) { c.insert(0,"1"); } if (c.back()=='.') c.pop_back(); cout << c << endl; return 0; } |
Программа выполнена с помощью методов класса <string>. Для работы мне понадобилось написать несколько вспомогательных функций, задачей которых является дополнить числа нулями таким образом, чтобы точки чисел оказались на одинаковых позициях.
Функция dot_position. Эта функция находит места точек в обеих строках, а если таковых нет, то им присваивается значение длины строки. Возвращает функция наибольшую по значению позицию точки.
Функции length_before_dot и length_after_dot возвращают количество цифр до и после точки соответственно.
Затем начинается тело основной функции программы. Изначально пользователю предоставляется ввести систему счисления и 2 числа, которые программа считывает в виде строк. Для удобства вычислений программа дополняем строку, которая не содержит точку, ещё одним ранее названным символом. Затем мы выравниваем оба наших числа по точкам.
После этого программа готова вычислить сумму двух чисел. Сложность реализации алгоритма сложения состояла лишь в том, что записать в строку элемент типа int — невозможно, а следовательно, его нужно было преобразовать в строку. Для этого потребовалась функция to_string() из класса <string>. Но при этом элементы a[i] и b[i] воспринимались как коды символов, поэтому каждый из них нужно было уменьшить на ‘0’.
Ещё одна сложность — это десятки, которые мы держим «в уме», а в моём случае — во вспомогательной переменной p.
Код можно посмотреть здесь.
Код программы (cstring):
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 |
#include <iostream> #include <cstring> #include <stdio.h> using namespace std; unsigned int dot_position (const char *a, const char *b) { unsigned int dota=0, dotb=0; for (unsigned int i=0; a[i]; i++) { if (a[i]=='.') dota=i; } if (dota==0) dota=strlen(a); for (unsigned int i=0; b[i]; i++) { if (b[i]=='.') dotb=i; } if (dotb==0) dotb=strlen(b); return max (dota, dotb); } unsigned int length_before_dot (const char *a) { unsigned int i=0; for (; a[i]; i++) { if (a[i]=='.') break; } return i; } int length_after_dot (const char *a) { return strlen(a)-length_before_dot(a)-1; } void insert (char *a, size_t position, char c) { for (unsigned int i=strlen(a); i>position; i--) { a[i]=a[i-1]; } a[position]=c; } int main() { const int d='0'; int q; cin >> q; char *a; a = new char [100]; char *b; b = new char [100]; char *c; c = new char [101]; cin >> a >> b; if (length_after_dot(a)<0) insert(a,strlen(a),'.'); // Если число без точки, то условно ставим её. if (length_after_dot(b)<0) insert(b,strlen(b),'.'); if (length_after_dot(a)>length_after_dot(b)) { for (unsigned int i=strlen(a)-1; i>length_before_dot(a)+length_after_dot(b); i--) { insert(c,0,a[i]); } } else if (length_after_dot(a)<length_after_dot(b)) { for (unsigned int i=strlen(b)-1; i>length_before_dot(b)+length_after_dot(a); i--) { insert(c,0,b[i]); } } if (length_before_dot(a)<dot_position(a,b)) { for (unsigned int i=dot_position(a,b)-length_before_dot(a); i>0; i--) { insert(a,0,'0'); } } else if (length_before_dot(b)<dot_position(a,b)) { for (unsigned int i=dot_position(a,b)-length_before_dot(b); i>0; i--) { insert(b,0,'0'); } } int p=0; for (int i=min(strlen(a),strlen(b))-1; i>=0; i--) { char *k; k = new char [1]; if (a[i]=='.') { insert(c,0,'.'); --i; } if (a[i]+b[i]-2*d+p-q<0) { sprintf(k,"%d",a[i]+b[i]-2*d+p); p=0; } else { sprintf(k,"%d",a[i]+b[i]-2*d+p-q); p=1; } insert(c,0,k[0]); } if (p==1) { insert(c,0,'1'); } if (c[strlen(c)-1]=='.') c[strlen(c)-1]=''; cout << c << endl; return 0; } |
Из-за отсутствия функции insert() в классе <cstring> я была вынуждена написать её самостоятельно. В остальном работа заключалась лишь в «переводе» кода из одного класса в другой.
Код можно посмотреть здесь.
Если Вы описываете функции — значит они выполняют какую-то важную роль — т.е. нужно описать в отчете что каждая из них конкретно делает.
И вообще комментариев мало: например выражение if (a[i]+b[i]-d+p-q
Описала функцию в отчёте, пояснила момент с числом 48.
Также строки в функцию теперь передаются по указанной вами схеме.
Спасибо за замечание.
Я бы посоветовал использовать не число 48, а число ‘0’: const int d = ‘0’;
И пояснять уже нечего.
То, что программа работает действительно очень хорошо.
Только она «перетяжелена» избыточными сущностями. Мы ведь не складываем отдельно до точки, отдельно после. После того как числа выравнены по точке они складываются справа налево, а точка остаётся на своём месте. Дописывание незначащих нулей для выравнивания тоже излишний шаг. Мы ведь этого не делаем когда складываем числа столбиком? Кстати, insert() умеет вставлять много одинаковых символов сразу.
Заменила «магическое» число.
Добавила код программы с использованием методов класса cstring.
Исправила момент с функцией insert(), теперь она действительно использует все свои возможности.
Также теперь нули не дописываются в конце чисел.
Зачтено. Молодец!