#c
#c
Вопрос:
Я пытаюсь создать программу, которая принимает меньшие значения диагонали и сохраняет их в одномерном массиве, а затем просто распечатывает его.
Ввод:
1 0 0
2 3 0
4 5 6
ожидаемый результат
1 0 0
2 3 0
4 5 6
текущий вывод
2 0 0
2 4 0
4 5 6
обратите внимание, что я уже указал размер 3
.
код:
#include <bits/stdc .h>
using namespace std;
class matrix
{
int size;
int *a;
public:
matrix(int size) //Matrix class
{
this->size = size;
a = new int[(size * (size 1) / 2)]; //creating 1-D array to store values
}
void set(int i, int j, int val) //Function to set values in array "a".
{
if (i >= j)
a[((i * (i - 1)) / 2) (j - 1)] = val;
}
void display() //function to display values
{
for (int i = 0; i < size; i )
{
for (int j = 0; j < size; j )
{
if (i >= j)
cout << a[((i * (i - 1)) / 2) (j - 1)] << " ";
else
cout << "0 ";
}
cout << endl;
}
}
};
int main()
{
int n = 3; //dimension of matrix
matrix a(n);
for (int i = 0; i < n; i ) //entering the values
{
int val;
for (int j = 0; j < n; j )
{
cin >> val;
a.set(i, j, val);
}
}
a.display();
return 0;
}
Прилагаемый компилятор: https://onlinegdb.com/IrzmB04dB
Комментарии:
1. Очевидно
cout << a[((i * (i - 1)) / 2) (j - 1)] << " ";
, это неправильно. Вы можете увидеть, вычисляете ли вы дляi = 0
иj = 0
. Вы не можете получить доступa[-1]
. В массиве естьsize * (size - 1) / 2
элементы, но вложенный циклdisplay
повторяетсяsize * size
раз.2. В вашем коде, ИМХО, слишком много ошибок. Способы вычисления размера и индексов вашего
a
массива совершенно неверны.3. Я мог бы опубликовать «исправленную» версию вашей программы. Но, поскольку это, вероятно, проблема домашней работы, я не думаю, что это, в конечном счете, было бы полезно.
4. Но подумайте об этом. Если есть только
size * (size - 1) / 2
возможные индексы, но вы пытаетесь получить доступsize * size
к разным элементам, вам нужно выйти за пределы или вам придется обращаться к одним и тем же элементам несколько раз.5. Нет, если
size
5
вы сохраняете10
элементы.5 * (5 - 1) / 2 == 10
. Еслиsize
3
вы сохраняете3
элементы:3 * (3 - 1) / 2 == 3
.
Ответ №1:
Ваша формула для поиска элемента матрицы i,j
в представлении плоского массива (которое вы вызываете a
в своем коде) указанной матрицы a[((i * (i - 1)) / 2) (j - 1)]
верна только в том случае, если индексы i,j
начинают отсчет с 1
, как в Fortran, а не с 0
, как в C .
Кроме того, размер нижней треугольной матрицы должен включать основную диагональ в вашем соглашении, поэтому он должен быть (size * (size - 1) / 2) size
добавлен size
в конструктор.
Учитывая это, ваш код становится:
#include <iostream>
using namespace std;
class matrix
{
int size;
int *a;
public:
//Matrix class, ADD ' size' TO a
matrix(int input_size): size(input_size), a(new int[size * (size 1) / 2] size) {}
void set(int i, int j, int val) //Function to set values in array "a".
{
if (i >= j) {
//i ; j ; // !!HERE!! START i,j AT 1
//a[((i * (i - 1)) / 2) (j - 1)] = val;
// OR, EQUIVALENTLY
a[((i * (i 1)) / 2) j] = val;
}
}
void display() //function to display values
{
for (int i = 1; i <= size; i ) // START i AT 1
{
for (int j = 1; j <= size; j ) // START j AT 1
{
if (i >= j)
cout << a[((i * (i - 1)) / 2) (j - 1)] << " ";
else
cout << "0 ";
}
cout << endl;
}
}
};
int main()
{
int n = 3; //dimension of matrix
matrix a(n);
for (int i = 0; i < n; i ) //entering the values
{
int val;
for (int j = 0; j < n; j )
{
cin >> val;
a.set(i, j, val);
}
}
a.display();
return 0;
}
Результирующий вывод:
1
0
0
2
3
0
4
5
6
1 0 0
2 3 0
4 5 6
Комментарии:
1. Вы правы, это будет читаться лучше. Также
this->size
в конструкторе не слишком хорошо работает. Можно было бы вызвать входной параметр каким-либо другим способом, скажемinput_size
, и установитьsize = input_size
.2. Да, в списке инициализатора. Я обновлю свой ответ.
3. В качестве последнего шага вы могли бы заменить циклы на основе 1 циклами на
cout << a[((i * (i - 1)) / 2) (j - 1)] << " ";
основе 0 иcout << a[i * (i 1) / 2 j] << " ";
4. Я хочу оставить
i,j = 1
исправление очевидным, чтобы оператору было легче видеть, что нужно изменить, а также чтобы код больше соответствовал тексту моего ответа. Трудно передать идею о том, что все зависит от начальных значенийdisplay()
, если я изменю формулу.set()
С другой стороны, внутри функции было проще представить оба подхода.