Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- struct Polinom {
- int pow;
- float cof;
- Polinom* next;
- };
- Polinom* Summ(Polinom* P, Polinom* Q);
- int read(const char* filePath, Polinom** P);
- void write(const char* filePath, Polinom* R);
- int main() {
- Polinom* P, * Q, * R; // Объявление полиномов P, Q, R
- R = nullptr; // Каждый из них по умолчанию nulltpr, т.к. если файлы с P и/или Q пусты,
- P = nullptr; // то при инициализации через new Polinom их поля заполнятся какой-то
- Q = nullptr;
- if (!read("1.txt", &P)) // 1.txt - файл с полиномом P в формате a b, a - степень, b - коэффициент
- return 1;
- if (!read("2.txt", &Q)) // 2.txt - файл с полиномом Q
- return 1;
- R = Summ(P, Q); // Вычисление R
- write("result.txt", R);
- // p.s если ругается на unicode, надо удалить смешную шутку на 17 строке
- return 0;
- }
- Polinom* Summ(Polinom* P, Polinom* Q) {
- // Сначала читать комментарии к read (или нет)
- /* Общая схема такая же, как в read. Самое главное - понимать, почему temp необходим.
- Нам нужно, чтобы "последний элемент"->next был nullptr. Первое, что приходит в голову - это
- current->next = nullptr;
- current = current->next;
- И если current не последний, то на следующей итерации цикла
- current = new Polinom;
- Это не сработает, т.к. current до этой строчки и current после нее - это два разных указателя, соответственно элемент R, копией которого являлся current,
- остался равным nullptr, т.о. R будет состоять из одного элемента, а остальные будут разбросанными по памяти и никак не связаны с R
- Использование temp позволяет current всегда быть не nullptr, а current->next всегда nullptr
- */
- Polinom* temp = nullptr;
- Polinom* current = nullptr;
- Polinom* R = nullptr;
- while (P || Q) { // Если в P или в Q есть элементы
- temp = new Polinom;
- temp->next = nullptr; // Тут все ясно
- if (P && Q) { // Если элементы присутствуют в обоих списках
- if (Q->pow == P->pow) { // степени равны, возможны 2 случая: коэффициенты не противоположны и коэффициенты противоположны
- if (P->cof != -(Q->cof)) { // Не противоположны
- temp->pow = P->pow;
- temp->cof = P->cof + Q->cof;
- }
- else
- temp = nullptr; // До этого temp был равен new Polinom и его значения были случайны.
- P = P->next;
- Q = Q->next; // Все понятно
- }
- else { // 2 случая: степень P > Q или степень Q > P
- if (P->pow > Q->pow) {
- temp->pow = P->pow;
- temp->cof = P->cof;
- P = P->next;
- }
- else if (Q->pow > P->pow) {
- temp->pow = Q->pow;
- temp->cof = Q->cof;
- Q = Q->next;
- }
- }
- }
- else { // Остался лишь один не просмотренный список
- P = P ? P : Q; // Это уловный тернарный оператор. Что-то типо if(P) { P = P; } else { P = Q; }
- if (P) { // Не факт что есть хотя бы один не просмотренный список
- temp->pow = P->pow;
- temp->cof = P->cof;
- P = P->next;
- }
- }
- if (temp) {
- if (!R) { // Тут все также как в read
- R = new Polinom;
- R = temp;
- current = R;
- }
- else {
- current->next = temp;
- current = current->next;
- }
- }
- }
- return R;
- // P.S переделал это, теперь оно функция как она и просила.
- }
- int read(const char* filePath, Polinom** P) {
- FILE* file;
- errno_t error = fopen_s(&file, filePath, "r"); // Попытка отрыть файл, если не удалось, error = 1
- if (error) {
- printf("Failed to open the file \"%s\".", filePath); // Если error = 1, то функция возвращает 0, что завершает выполнение main с кодом 1
- return 0;
- }
- /* Всего понадобится 3 полинома: *P - указатель на голову списка
- current - текущее считываемое слагаемое (всегда не nullptr!)
- temp - вспомогательное звено полинома, необходимое, чтобы у последнего элемента из P следующий всегда был равен nullptr
- */
- Polinom* current = nullptr; // Почти всегда
- Polinom* temp = new Polinom;
- // Проверяем является ли текущая строка файла последней, попутно записывая её значения в соответствующие поля temp
- while (fscanf_s(file, "%d%f", &temp->pow, &temp->cof) != EOF) {
- temp->next = nullptr;
- if (!(*P)) { // Это условие выполнится единожды, на первой строке файла.
- *P = new Polinom; // Мы уже знаем что файл не пустой и инициализируем *P
- *P = temp; // Тута все понятно
- current = *P; // И здеся тоже
- }
- else { // Это условие выполняется после считывания каждой строки кроме первой
- current->next = temp;
- current = current->next; // В результате current->next, а соответственно и (*P)->next равны nullptr (т.к. temp->next = nullptr)
- }
- temp = new Polinom; // иначе 1) содержимое P и current будут меняться 2) список станет циклическим
- }
- delete temp;
- fclose(file);
- return 1;
- }
- void write(const char* filePath, Polinom* R) {
- FILE* file;
- errno_t error = fopen_s(&file, filePath, "w+");
- if (error) {
- printf("Failed to open the file \"%s\".", filePath); // Аналогично функции read
- return;
- }
- while (R) { // Поскольку у последнего элемента R next = nullptr, данный список просматривает все содержимое R
- fprintf(file, "%d %.3f\n", R->pow, R->cof);
- R = R->next;
- }
- fclose(file);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement