Оператор матричного класса C++* возвращает неверный ответC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Оператор матричного класса C++* возвращает неверный ответ

Сообщение Anonymous »

Мне было поручено написать довольно простой код, который реализует матричный класс с типичным набором матричных операций, например умножением матриц с записями, взятыми по модулю 1000. Я придумал следующее решение:

Код: Выделить всё

matrix operator*(const matrix &A, const matrix &B)
{
if (A.m1 != B.n1)
throw runtime_error("MULTIPLY");

matrix C(A.n1, B.m1);
matrix Bt(B.m1, B.n1);
for (int i = 0; i < B.n1; ++i)
for (int j = 0; j < B.m1; ++j)
Bt.tab[j][i] = B.tab[i][j];

for (int i = 0; i < A.n1; ++i)
{
int *rowA = A.tab[i];
int *rowC = C.tab[i];

for (int j = 0; j < B.m1; ++j)
{
const int *rowB = Bt.tab[j];
long long sum = 0;
for (int k = 0; k < A.m1; ++k)
sum += (long long)rowA[k] * rowB[k];
rowC[j] = sum%1000;
}
}
return C;
}
Система оценок моего университета выдает ошибку неправильного ответа в определенном тестовом примере, который проверяет именно указанный выше оператор. Тестовый пример скрыт, но с помощью простого обратного проектирования я смог определить, что это происходит для некоторых довольно больших матриц (сумма измерений +/- 2000). Некоторые примечания:
  • Я проверил, что проблем с обработкой ошибок нет.
  • Использование Bt необходимо в целях оптимизации.
  • Нет проблем с получением суммы %1000. Во-первых, он не будет возвращать отрицательные значения, поскольку предполагается, что записи неотрицательные, во-вторых, я подсчитал, что вероятность переполнения отсутствует.
Вот некоторые другие соответствующие блоки кода:

Код: Выделить всё

class matrix
{
int n1, m1;
int **tab;

public:
matrix(int rows=0, int cols=0);
matrix(const matrix &A);
~matrix();
void operator=(const matrix &A);
long long determinant();
friend matrix operator+(const matrix &A, const matrix &B);
friend matrix operator*(const matrix &A, const matrix &B);
friend matrix operator^(const matrix &A, int k);
friend ostream& operator(istream &is, matrix &A);
};

Код: Выделить всё

matrix::matrix(int rows, int cols) : n1(rows), m1(cols)
{
if (n1 == 0 || m1 == 0)
{
tab = nullptr;
return;
}
tab = new int*[n1];
for (int i = 0; i < n1; i++)
{
tab[i] = new int[m1]();
}
}

Код: Выделить всё

oid op_multiply() {
int n1, m1;
cin >> n1 >> m1;
matrix A(n1,m1);
cin >> A;
int n2, m2;
cin >> n2 >> m2;
matrix B(n2,m2);
cin >> B;
try
{
cout > op;
ops[op]();
}
return 0;
}
Буду очень благодарен, если укажете здесь на ошибку. Я застрял в отладке этого оператора в течение 5 часов и не понимаю, в чем дело.
РЕДАКТИРОВАТЬ: Моя попытка MRE:

Код: Выделить всё

#include 
#include 
#include 
using namespace std;

class matrix
{
int n1, m1;
int **tab;

public:
matrix(int rows=0, int cols=0);
matrix(const matrix &A);
~matrix();
friend matrix operator*(const matrix &A, const matrix &B);
friend ostream& operator(istream &is, matrix &A);
};

matrix::matrix(int rows, int cols) : n1(rows), m1(cols)
{
if (n1 == 0 || m1 == 0)
{
tab = nullptr;
return;
}
tab = new int*[n1];
for (int i = 0; i < n1; i++)
{
tab[i] = new int[m1]();
}
}

matrix::matrix(const matrix &A) : n1(A.n1), m1(A.m1)
{
if (n1 == 0 || m1 == 0)
{
tab = nullptr;
return;
}
tab = new int*[n1];
for (int i = 0; i < n1; i++)
{
tab[i] = new int[m1];
for (int j = 0; j < m1; j++)
tab[i][j] = A.tab[i][j];
}
}

matrix::~matrix()
{
if (!tab) return;
for (int i = 0; i < n1; i++)
delete[] tab[i];
delete[] tab;
}

matrix operator*(const matrix &A, const matrix &B)
{
if (A.m1 != B.n1)
throw runtime_error("MULTIPLY");

matrix C(A.n1, B.m1);

matrix Bt(B.m1, B.n1);
for (int i = 0; i < B.n1; ++i)
for (int j = 0; j < B.m1; ++j)
Bt.tab[j][i] = B.tab[i][j];

for (int i = 0; i < A.n1; ++i)
{
int *rowA = A.tab[i];
int *rowC = C.tab[i];

for (int j = 0; j < B.m1; ++j)
{
const int *rowB = Bt.tab[j];
long long sum = 0;
for (int k = 0; k < A.m1; ++k)
sum += (long long)rowA[k] * rowB[k];
rowC[j] = sum%1000;
if (rowC[j] < 0)
rowC[j] = -rowC[j];
}
}
return C;
}

ostream& operator> n1 >> m1;
matrix A(n1,m1);
cin >> A;

int n2, m2;
cin >> n2 >> m2;
matrix B(n2,m2);
cin >> B;

try
{
cout 

Подробнее здесь: [url]https://stackoverflow.com/questions/79804288/c-matrix-class-operator-returns-wrong-answer[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»