Язык С. Написать функцию сложения полиномов

Не могу найти ошибку в алгоритме проверки степени и записи ее в sum_arr

Я заполняю с клавиатуры два полинома в виде двумерных дин. массивов, где записываю коэффициент и степень каждого члена. Функция сложения объединяет два массива в sum_arr, по пути складывая члены с одинаковыми степенями.

Первый полином: 3x^5 + 7x^3 - 2x + 10, где 3, 7, -2, 10 - коэффициенты, 5, 3, 1, 0 - степени, 3x^5 - первый член полинома.

Второй полином: 4x^8 + x^5 - 3x^2 Складывая полиномы почленно, члены с одинаковыми степенями: 3x^5 + x^5 → 4x^5. То есть функция сложения должна проверять степени на сходство. Если совпало, то записывает в результат степень 5 этого члена (степень не изменится) и сумму коэффициентов 4.

Доп. требования: Мне нужно использовать двумерные динамические массивы malloc.

Вот функция main

#include <stdio.h>
#include <malloc.h>

int main()
{
    // считываем 1 полином ---------------------------------------------------------
    int rows1 = 4;
    int cols1 = 2;
    system("chcp 1251");
    system("cls");
    printf("Input elements of a first polinom \n");
    printf("Quantity of monomials for a polinom: %d \n", rows1);
    int** arr1 = (int**)malloc(sizeof(int*) * rows1);

    // создаем вложенный массив 
    for (int i = 0; i < rows1; i++)
    {
        arr1[i] = new int[cols1];
    }

    // тут вносим числа в массив
    for (int i = 0; i < rows1; i++)
    {
        for (int j = 0; j < cols1; j++)
        {
            printf("arr1[%d][%d] = ", i, j);
            scanf_s("%d", &arr1[i][j]);
        }
    }

    // тут выводим массив
    for (int i = 0; i < rows1; i++)
    {
        for (int j = 0; j < cols1; j++)
        {
            printf("%d \t", arr1[i][j]);
        }
        printf("\n");
    }

    // считываем 2 полином ---------------------------------------------------------
    int rows2 = 3;
    int cols2 = 2;
    printf("\n Input elements of a second polinom \n");
    printf("Quantity of monomials for a polinom: %d \n", rows2);
    int** arr2 = (int**)malloc(sizeof(int*) * rows2);

    // создаем вложенный массив 
    for (int i = 0; i < rows2; i++)
    {
        arr2[i] = new int[cols2];
    }

    // тут вносим числа в массив
    for (int i = 0; i < rows2; i++)
    {
        for (int j = 0; j < cols2; j++)
        {
            printf("arr1[%d][%d] = ", i, j);
            scanf_s("%d", &arr2[i][j]);
        }
    }

    // тут выводим массив
    for (int i = 0; i < rows2; i++)
    {
        for (int j = 0; j < cols2; j++)
        {
            printf("%d \t", arr2[i][j]);
        }
        printf("\n");
    }

    // sum_polinoms ---------------------------------------------------------

    sum_polinoms(arr1, arr2, rows1, rows2);

    // очистка памяти от cols и rows соответственно -------------------------
    for (int i = 0; i < rows1; i++)
    {
        delete[] arr1[i];
    }
    for (int i = 0; i < rows2; i++)
    {
        delete[] arr2[i];
    }
    free(arr1);
    arr1 = NULL;
    free(arr2);
    arr2 = NULL;

    return 0;
}

Вот функция сложения, параметры: массив полинома 1, массив полинома 2, и их размеры соотв.

void sum_polinoms(int** plnm1, int** plnm2, int size_plnm1, int size_plnm2)
{
    int rows = 7;
    int cols = 2;
    int** sum_arr = (int**)malloc(sizeof(int*) * rows);

    // создаем вложенный массив --------------------------------------------
    for (int i = 0; i < rows; i++)
    {
        sum_arr[i] = new int[cols];
    }

    // алгоритм проверки степени и запись полиномов в sum_arr --------------
    int temp;
    for (int i = 0; i < size_plnm1 - 1; i++)
    {
        temp = plnm1[i][1];
        for (int m = 0; m < size_plnm2 - 1; m++)
        {
            if (plnm2[m][1] == temp)
            {
                plnm1[i][0] = plnm2[m][0] + plnm1[i][0];
                sum_arr[i] = plnm1[i];
            }
            else sum_arr[i] = plnm1[i];
        }
    }

    for (int i = 0; i < size_plnm2 - 1; i++)
    {
        temp = plnm2[i][1];
        for (int m = 0; m < size_plnm1 - 1; m++)
        {
            if (temp != sum_arr[m][1])
            {
                sum_arr[m + size_plnm1] = plnm2[i];
            }
        }
    }
    
    // тут выводим массив -------------------------------------------------
    printf("Sum of two polinoms is \n");
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < cols; j++)
        {
            printf("%d \t", sum_arr[i][j]);
        }
        printf("\n");
    }

    // очистка памяти от cols --------------------------------------------
    for (int i = 0; i < rows; i++)
    {
        delete[] sum_arr[i];
    }

    // очиcтка памяти от rows --------------------------------------------
    free(sum_arr);
    sum_arr = NULL;
}

Про логику алгоритма проверки степени: Берем степень первого члена

Сравниваем с степенями всех членов второго массива

Если ни разу не совпало, так и записываем этот элемент в sum_arr

Если совпало, до записываем в sum_arr степень этого члена (степень не изменится) и сумму коэффициентов

И в конце проверяем каждый член второго многочлена, если степень рассматриваемого члена отсутствует в sum_arr, то записываем этот член тоже в sum_arr

Результат на терминале такой:

Input elements of a first polinom
Quantity of monomials for a polinom: 4
arr1[0][0] = 3
arr1[0][1] = 5
arr1[1][0] = 7
arr1[1][1] = 3
arr1[2][0] = -2
arr1[2][1] = 1
arr1[3][0] = 10
arr1[3][1] = 0
3       5
7       3
-2      1
10      0

Input elements of a second polinom
Quantity of monomials for a polinom: 3
arr1[0][0] = 4
arr1[0][1] = 8
arr1[1][0] = 1
arr1[1][1] = 5
arr1[2][0] = -3
arr1[2][1] = 2
4       8
1       5
-3      2
Sum of two polinoms is
4       5
7       3
-2      1
-842150451      -842150451
4       8
1       5
1       5

Хотя должно быть так:

4       8
4       5
7       3
-3      2
-2      1
10      0

Ответы (1 шт):

Автор решения: Damir Hakimof

Видно, я изрядно опоздал, но может кому и понадобится:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

/*
Вы просили код на Си. Без примесей С++,
поэтому готовьтесь страдать :)
*/

// Проверка на NULL
#define CORRECT_MEM(x) if (x == NULL) { return NULL; }
#define COLS 2

// Аллокация памяти
int** alloc(int rows) {
  int** arr = (int**)malloc(sizeof(int*) * rows);
  CORRECT_MEM(arr);
  for (int i = 0; i < rows; ++i) {
    arr[i] = (int*)malloc(sizeof(int) * COLS);
    CORRECT_MEM(arr[i]);
  }
  return arr;
}

// Деаллокация памяти
void dealloc(int*** arr, int rows) {
  if (*arr != NULL) {
    for (int i = 0; i < rows; ++i) {
      free((*arr)[i]);
    }
    free(*arr);
    *arr = NULL;
  }
}

// Ввести массив
void input(int** arr, int rows) {
  for (int i = 0; i < rows; ++i) {
    for (int j = 0; j < COLS; ++j) {
      printf("arr[%d][%d] = ", i, j);
      scanf("%d", &arr[i][j]); // Используем scanf!
    }
  }
}

// Вывести массив
void output(int** arr, int rows) {
  for (int i = 0; i < rows; ++i) {
    for (int j = 0; j < COLS; ++j) {
      printf("%d \t", arr[i][j]);
    }
    printf("\n");
  }
}

bool sum_polinoms(int** plnm1, int** plnm2, int size_plnm1, int size_plnm2) {
  int rows = size_plnm1 + size_plnm2; // Максимально возможное количество членов
  int** sum_arr = alloc(rows); // Здесь безопасно
  if (sum_arr == NULL) {
    printf("Memory allocation failed for sum array.\n");
    return false;
  }

  // Инициализация массива суммы
  for (int i = 0; i < rows; ++i) {
    sum_arr[i][0] = 0; // Коэффициенты
    sum_arr[i][1] = -1; // Степени (-1 будет обозначать, что степень не назначена)
  }

  int sum_index = 0;

  // Обработка первого полинома
  for (int i = 0; i < size_plnm1; ++i) {
    int coeff1 = plnm1[i][0];
    int degree1 = plnm1[i][1];

    bool found = false;
    for (int j = 0; j < sum_index; ++j) {
      if (sum_arr[j][1] == degree1) {
        sum_arr[j][0] += coeff1;
        found = true;
        break;
      }
    }
    if (!found) {
      sum_arr[sum_index][0] = coeff1;
      sum_arr[sum_index][1] = degree1;
      ++sum_index;
    }
  }

  // Обработка второго полинома
  for (int i = 0; i < size_plnm2; ++i) {
    int coeff2 = plnm2[i][0];
    int degree2 = plnm2[i][1];

    bool found = false;
    for (int j = 0; j < sum_index; ++j) {
      if (sum_arr[j][1] == degree2) {
        sum_arr[j][0] += coeff2;
        found = true;
        break;
      }
    }
    if (!found) {
      sum_arr[sum_index][0] = coeff2;
      sum_arr[sum_index][1] = degree2;
      ++sum_index;
    }
  }

  // Теперь необходимо обрезать массив до фактического количества членов
  int** final_sum_arr = alloc(sum_index);
  if (final_sum_arr == NULL) {
    printf("Memory allocation failed for final sum array.\n");
    dealloc(&sum_arr, rows);
    return false;
  }

  for (int i = 0; i < sum_index; ++i) {
    final_sum_arr[i][0] = sum_arr[i][0];
    final_sum_arr[i][1] = sum_arr[i][1];
  }

  printf("Sum of two polinoms is:\n");
  output(final_sum_arr, sum_index);

  dealloc(&sum_arr, rows);
  dealloc(&final_sum_arr, sum_index);

  return true;
}

int main() {
  int** arr1 = NULL;
  int** arr2 = NULL;
  const int rows1 = 4;
  const int rows2 = 3;

  // считываем 1 полином ---------------------------------------------------------
  printf("Input elements of a first polinom \n");
  printf("Quantity of monomials for a polinom: %d \n", rows1);

  arr1 = alloc(rows1);
  if (arr1 == NULL) {
    printf("Memory allocation failed for first polynomial.\n");
    return EXIT_FAILURE;
  }
  
  input(arr1, rows1);
  output(arr1, rows1);

  // считываем 2 полином ---------------------------------------------------------
  printf("\nInput elements of a second polinom \n");
  printf("Quantity of monomials for a polinom: %d \n", rows2);

  arr2 = alloc(rows2);
  if (arr2 == NULL) {
    printf("Memory allocation failed for second polynomial.\n");
    dealloc(&arr1, rows1);
    return EXIT_FAILURE;
  }

  input(arr2, rows2);
  output(arr2, rows2);

  // Суммируем полиномы
  if (!sum_polinoms(arr1, arr2, rows1, rows2)) {
    dealloc(&arr1, rows1);
    dealloc(&arr2, rows2);
    return EXIT_FAILURE;
  }

  dealloc(&arr1, rows1);
  dealloc(&arr2, rows2);

  return EXIT_SUCCESS;
}

``
→ Ссылка