LINUX.ORG.RU

Как сделать размерность матрицы вводом с клавиатуры

 , ,


0

1

Есть задание, помогите разобраться. Собственно, вопрос в том, как сделать мерность массива (тобиш размерность матрицы) вводом с клавиатуры? Остальное +- понял как прикрутить. https://ibb.co/qsRdX8Q

std::vector<std::vector<int>> matrix;

rumgot ★★★★★
()

Одномерный вектор тебе вполне подойдет vector<int> matrix. Если W - максимальное значение x, то индексироваться по массиву можешь так: matrix[y * W + x]

Aswed ★★★★★
()
Ответ на: комментарий от Aswed

а как это реализовать именно в коде? гайдов на русском по вектору я не нашел, а как именно работает вектор я так и не понял

PURGEN143
() автор топика
Ответ на: комментарий от PURGEN143

Напиши псевдокодом решение, которое ты видишь, а мы поможем переложить его на STL-ные контейнеры

XMs ★★★★★
()
Ответ на: комментарий от thunar

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

PURGEN143
() автор топика

К слову, ты говоришь не про размерность матрицы, а про её размер

Сделать матрицу переменной размерности тоже можно, но это потребует чуть больше усилий:)

Crocodoom ★★★★★
()
std::cout << "введите число столбцов-> ";
int col;
std::cin >> col;

std::cout << "введите число строк-> ";
int row;
std::cin >> row;

std::array<std::array<int, row>> matrix; // это твоя матрица

                   Лиза 
anonymous
()
Ответ на: комментарий от XMs

https://pastebin.ubuntu.com/p/vGT8mrZZHB/ пока что попытался сделать матрицу m x n с рандомными m и n, а так же попытался числа массива так же сделать рандомными, но не вышло, икскод говорит https://ibb.co/vdVSR1y

PURGEN143
() автор топика
Ответ на: комментарий от anonymous

Ой, ошибочка.

std::cout << "введите число столбцов-> ";
int col;
std::cin >> col;

std::cout << "введите число строк-> ";
int row;
std::cin >> row;

std::array<std::array<int, row> col> matrix; // это твоя матрица

                   Лиза 
anonymous
()
Ответ на: комментарий от PURGEN143

Для начала, следует открыть документацию на std::array и убедиться что он для этого не подходит.

thunar ★★★★★
()
Ответ на: комментарий от PURGEN143

Не, константами, компилятор должен знать сколько памяти выделить. Это я тупанула.

сделай так 

std::vector<std::vector<int>> matrix;

for (int i = 0; i<col; i++)
for (int j = 0; j <raw; j++) 

сначала пишешь с помощью push_back 0 встроку, затем всю строку в матрицу

на выходе матрица нужного размера
anonymous
()

Я бы сделал гораздо проще. Сделать матрицу 50x50, но при расчётах учитывать только заполненную часть. Там же есть ограничение размера сверху. А 50x50 это для современного компьютера ничтожно мало.

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 2)
Ответ на: комментарий от XMs

https://pastebin.ubuntu.com/p/ggQ4YRnNWq/ нашел в тырьнете рабочее решение, только вот матрица получается квадратной. в размере только одну цифру можно. например 2 тогда матрица 2х2. надо чтобы и строки и столбцы можно было редактировать по размеру.

PURGEN143
() автор топика
Ответ на: комментарий от PURGEN143

Да какие варианты-то? Объявляешь массив максимально возможного размера. В каких-то переменных хранишь размер матрицы. Дальше такой же точно код, как для массива фиксированного размера.

А у как транспонировать матрицу ты сам должен знать.

Xenius ★★★★★
()
Ответ на: комментарий от PURGEN143

cin>>n>>m

Дальше сам догадайся. Пример ты норм нашел, как тебе в первом посте советовали. Ты сути не понимаешь, как динамически создать, а тебе о std шаблонах пишут. Начни с малого.

Можно, даже, сначала на Си взглянуть, там только вместо new malloc. Код совсем простой будет.

А можно тупо размер матрицы с запасом сразу создать, как советуют. Но тебе же разобраться нужно как работает и как правильно, так что не лучший вариант.

Stack77
()
Последнее исправление: Stack77 (всего исправлений: 1)
Ответ на: комментарий от PURGEN143

Хорошо. На данный момент имеем:

  • Отсутствие проверки пользовательского ввода;
  • Мешанину из C и C++;
  • Заполнение матрицы набором из неправильного диапазона;
  • Отсутствие транспонирования.

Первое, полагаю, ты знаешь, как сделать, поэтому заострять внимание не буду. Массивы, если уж делаешь на плюсах, стоит объявить так:

--- int matrix [n][m];
+++ std::array<std::array<int, m>, n> matrix;
Для генерации случайных чисел в правильном диапазоне и средствами STL стоит сделать вот так (и добавить заголовочный файл random):
+++ std::random_device rd;
+++ std::mt19937 gen(rd());
+++ std::uniform_int_distribution<> distrib(0, 200);
    for (int i=0; i<n; i++)
+++   {
    	for (int j=0; j<m; j++)
--- 		matrix [i][j] = rand ();
+++ 		matrix[i][j] = distrib(gen);
+++   }

Транспонирование сделай самостоятельно хотя бы псевдокодом.

// Если в начале main() написать using namespace std;, то писать std:: в примерах выше будет не нужно

XMs ★★★★★
()
Последнее исправление: XMs (всего исправлений: 1)
Ответ на: комментарий от Stack77

разбивал уже. отдельно делал син для н и м, все равно. вроде принимает второе значение, но матрица все равно квадрат

PURGEN143
() автор топика
Ответ на: комментарий от PURGEN143

Посмотри на вложенный цикл (1 и 2), i до чего и j до чего? Что нужно поменять?

Пример ты норм нашел, как тебе в первом посте советовали

В смысле во втором комментарии (о динамических массивах). Видимо спать пора :)

Stack77
()
Последнее исправление: Stack77 (всего исправлений: 1)

Пример C++17

#include <iostream>
#include <vector>

int main() {
  using namespace std;

  // Создание и заполнение нулями
  vector matrix(20, vector(40, 0));

  // Вывод значений
  for (auto row = matrix.begin(); row != matrix.end(); ++row) {
    // Проверочка на всякий случай
    if (!row->empty()) {
      for (auto col = row->begin(); col != row->end(); ++col) {
        cout << *col << " ";
      }
      cout << endl;
    }
  }

  cout << "--------------------" << endl;

  // Пример обращения к элементу
  matrix[10][15] = 3;

  // Вывод значений по индексам
  for (auto row = 0ul; row < matrix.size(); ++row) {
    // Проверочка на всякий случай
    if (!matrix[row].empty()) {
      for (auto col = 0ul; col < matrix[row].size(); ++col) {
        cout << matrix[row][col] << " ";
      }
      cout << endl;
    }
  }

  return 0;
}
rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 2)
Ответ на: комментарий от PURGEN143

Если очень примерно, то пойдёт. Только:

  • Внутренний цикл получился бесконечным, нужно, конечно же,
    −−− for (int j=0; j= cols; j++)
    +++ for (size_t j = 0; j < cols; j++)
    
  • В присвоении ты теряешь значение matrix[i][j]. Нужно делать так:
    −−− matrix [i][j] = matrix =[j][i]
    +++ int temp = matrix[i][j];
    +++ matrix[i][j] = matrix[j][i];
    +++ matrix[j][i] = temp;
    
  • Если у тебя матрица не квадратная, получается ситуация, что ты в матрице размером N×M пишешь в несуществующие строки. Тебе надо сперва расширить матрицу до std::max(N, M), а потом, после преобразования, сократить размеры строк
XMs ★★★★★
()
Последнее исправление: XMs (всего исправлений: 2)
Ответ на: комментарий от PURGEN143

гайдов на русском по вектору я не нашел

Серьезно? А ты сколько минут секунд искал?

rumgot ★★★★★
()

Как я часто пишу: данная тема не возникла бы, прочти ты одну книгу по основам C++.

rumgot ★★★★★
()
Ответ на: комментарий от PURGEN143

Тогда тебе в Job. Потому что прогуливать пары не хорошо ;)

Norgat ★★★★★
()
Ответ на: комментарий от rumgot

Интересе ради, почему 0ul? size_t же не обязан им быть, а компилятор один черт правильно приведет константы.

Norgat ★★★★★
()
Ответ на: комментарий от Norgat

не обязан им быть

Но является им на всех распространенных платформах.

компилятор один черт правильно приведет константы

Не приведет.

#include <cstddef>
#include <type_traits>

int main() {
    constexpr std::size_t n = 0;
    for (auto i = 0; i < n; i++) {
        static_assert(!std::is_same_v<decltype(i), decltype(n)>);
        static_assert(std::is_same_v<int, decltype(i)>);
    }
}

https://godbolt.org/z/f5v468

Хотя это не имеет значения для лаб, тип лучше прописывать корректно.

for (decltype(matrix[row])::size_type i = 0; i < matrix[row].size(); i++) {
    // ...
}
Siborgium ★★★★★
()
Ответ на: комментарий от XMs

Для генерации случайных чисел в правильном диапазоне и средствами STL

Зачем? rand() % 200 ничем не хуже для этой задачи.

Массивы, если уж делаешь на плюсах, стоит объявить так:

Что ты несешь? Выше дважды написали, почему это не сработает, но ты продолжаешь писать чушь.

Siborgium ★★★★★
()
Ответ на: комментарий от XMs

Первое, полагаю, ты знаешь, как сделать

На самом деле именно это должен быть самый нетривиальный вопрос в этой программе.

peregrine ★★★★★
()
Ответ на: комментарий от Siborgium

Что ты несешь? Выше дважды написали, почему это не сработает, но ты продолжаешь писать чушь.

Ща бы троечникам готовые рабочие решения скидывать.

anonymous
()
Ответ на: комментарий от Xenius

Сделать матрицу 50x50, но при расчётах учитывать только заполненную часть

А я при запуске введу 51х51. Писатели ёпт...

deep-purple ★★★★★
()
Ответ на: комментарий от deep-purple

А я при запуске введу 51х51. Писатели ёпт...

А ты задачу прочитал? Там размер матрицы указан максимум 50. Введёшь 51, программа скажет, Matrices of 50×50 dimensions are supported at most.

Причём проверка на размер должна быть даже при динамическом выделении памяти.

Но при таких малых размерах с точки зрения производительности выгоднее выделить 50×50×8 байт оперативки статически. От 20 kb в своп программа не свалится.

Xenius ★★★★★
()
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Norgat

Разумеется лучше через проверку типа возврата у size(), а это такой ленивый вариант. Не люблю предупреждения игнорировать.

rumgot ★★★★★
()

Я вот не пойму, про какую матрицу 50х50 вы всё время рассуждаете? Когда в задании написано максимум 2х50.

По факту зависит от того — ты эту программу роботу на проверку сдавать будешь или человеку.

Если роботу, то нужно знать какие критерии при проверке важны, например, то же создание динамического массива.

Если человеку, тогда делаешь так. Вначале выводишь подсказку про размер матрицы NxM. Потом проверяешь введённые данные. Если (N < 1) или (N > 2) или (M < 1) или (M > 50), то делаешь аборт этому криворукому дятлу за клавиатурой, всенепременно сообщив ему об этом. И вообще ничего не считаешь.

Если всё нормально, то создаёшь ДВЕ матрицы сразу одну размером 2х50, вторую 50х2. Заполняешь нужными данными первую матрицу до размеров NxM. Делаешь полное транспонирование полной первой матрицы ПОЛНОСТЬЮ во вторую. Потом показываешь вторую матрицу на экран или полностью или частично в размере MxN. Если у человека проверяющего появятся вопросы, почему массивы не динамические, то просто в лоб спрашиваешь, что он знает про преждевременную эякоптимизацию и предсказуемое время выполнения задачи. Ну и после согласования проекта на исследование всех аспектов данной задачи, ты готов взяться за оптимизацию за отдельные деньги конечно же (вот это и есть промышленный подход).

justAmoment ★★★★★
()
Ответ на: комментарий от justAmoment

Лучше взять vector и не заморачиваться.

rumgot ★★★★★
()
Ответ на: комментарий от Siborgium

Мда, видимо я тоже каким-то не тем местом прочитал. Теперь понятно про 50х50.

Тогда нужно создать две матрицы фиксированного размера 50х50 и работать с ними.

justAmoment ★★★★★
()
Последнее исправление: justAmoment (всего исправлений: 1)

как сделать мерность массива (тобиш размерность матрицы) вводом с клавиатуры

Сначала вводишь с клавиатуры, потом создаешь массив, передав в качестве размерности введенные значения.

Zhbert ★★★★★
()
Ответ на: комментарий от Zhbert

В смысле так?:

int main() {
    int i;
    cin >> i;
    int a[i];   
}

Если что, это не стандартный код C++. Gcc и Clang его скомпилируют. А вот MSVC даст ошибку. Это называется VLA - Variable-length array и это расширение компилятора (https://ru.stackoverflow.com/questions/814027/Зачем-нужны-динамические-массивы-в-c).

Это конечно удобно, но я бы таким не пользовался, чтобы не входило в привычку и потом случайно не написать такое в коммерческом кроссплатформенном проекте и через некоторое время обнаружить, что под определенным компилятором это не компилируется.

rumgot ★★★★★
()
Последнее исправление: rumgot (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.