Статические и динамические массивы

Лекция 8. Двумерные массивы

Задача 1. Дана матрица размером n строк и m столбцов (0<n<=20, 0< m<=30). Найти сумму положительных элементов каждой строки.

а) Матрица вводится по строкам (можно обойтись без массива).

#include <iostream>

#include <conio.h>

/* Сумма по строкам                 */

#define NMAX 20

#define MMAX 30

using namespace std;

main()

{ float x;

int i,j;

float s;

int n,m;

puts(“Введи n, m"); cin>>n>>m;

puts (“Введи матрицу по строкам");

for (i=0;i<n; i++)

{ s=0;

for(j=0;j<m;j++)

  { cin>>x;

     if (x>0) s=s+x;

  }

cout<<"\nСтрока"<<i<<"s= "<<s;

}

getch();

return 0;

}

б) Матрица вводится по столбцам (необходим массив).

#include <iostream>

#include <conio.h>

/* Сумма по строкам                 */

#define NMAX 20

#define MMAX 30

using namespace std;

main()

{ float x[NMAX][MMAX];

int i,j;

float s;

int n,m;

puts ("Введи n m"); cin>>n>>m;

puts ("Введи матрицу");

for (j=0;j<m; j++)

for(i=0;i<n;i++)

    cin>>x[i][j];

for (i=0;i<n;i++)

{ s=0;

for (j=0;j<m;j++)

    if (x[i][j]>0) s=s+x[i][j];

cout<<"\n Str "<<i<<"s= "<<s;

}

getch();

return 0;

}в) Матрица вводится по строкам, требуется вычислить сумму положительных элементов каждого столбца (необходим массив).

#include <iostream>

#include <conio.h>

/* Сумма по строкам                 */

#define NMAX 20

#define MMAX 30

using namespace std;

 

main()

{ float x[NMAX][MMAX];

int i,j;

float s;

int n,m;

puts("Vv n m"); cin>>n>>m;

puts ("Vv matrix");

for (i=0;i<n; i++)

for(j=0;j<m;j++)

    cin>>x[i][j];

for (j=0;j<m;j++)

{ s=0;

for (i=0;i<n;i++)

    if (x[i][j]>0) s=s+x[i][j];

cout<<"\n Stolbr " <<j<<" s= "<<s;

}

getch();

return 0;

}

Задача 2. Целочисленная квадратная матрица размера n*n (n£50) вводится по строкам. Составить программу определения номера столбца, имеющего максимальную сумму элементов, расположенных выше главной диагонали.

 

Решение.                                    Тест

Входная матрица:                               Результат:

(точками отмечены элементы,  Номер столбца с максимальной

не участвующие в задаче)         суммой равен 3

n=5

  0 1 2 3 4
0 . 6 1 3 -2
1 . . 4 -1 3
2 . . . 5 1
3 . . . . 2
4 . . . . .

Программа. Обработка матрицы                       

/*Поиск столбца с наибольшей суммой выше главной диагонали */

#include < iostream >

#define NMAX 50   /* Максимальный размер матрицы*/

void main (void)

{ int m[NMAX][NMAX]; /* Матрица                                    */

int n;                     /* Количество строк и столбцов       */

int i;                    /* Индекс текущей строки                       */

int j;                    /* Индекс текущего столбца          */

int jmax;                        /* Индекс столбца с максим. суммой */

int s, smax;          /* Сумма текущего столбца и максим. */

 

/* 1. Ввод матрицы m по строкам                                       */

cin>>n;

for (i=0; i<n; ++i)

    /* Ввод i-й строки                                                                     */

    for (j=0; j<n; ++j) cin>>m[i][j];

/* 2.Поиск столбца с максим.суммой выше главной диагонали */

jmax = 1; smax = m[0][1];

for (j=2; j<n; j++)          /* Перебор столбцов                 */

{ /* Вычисление суммы j-го столбца                                  */

   for (s=0, i=0; i<j; i++)

      s = s + m[i][j];

   if (s > smax) { smax=s; jmax=j; }

}

cout<< "\nНомер столбца с максим-й суммой = "<< jmax;

}

Задача 2 (дополн). Составить программу для решения следующей задачи. Заполнить квадратную матрицу А = {ai,j} (i, j = 0, ..., n-1) значениями, вычисленными по формуле ai,,j = i * j % 5 + i - j. Из матрицы получить вектор Х= {xi} (i = 1, ..., n). Элемент xi вычислять как скалярное произведение i-ой строки матрицы на столбец, содержащий первый по порядку максимальный элемент i-ой строки. Полученный вектор упорядочить по возрастанию методом последовательного нахождения минимума.

Программа. Обработка матрицы и вектора

#include < iostream >

#define N 10   /*максимальный размер матрицы               */

main()

{ int n;           /* размер матрицы                                      */

float a[N][N]; /* матрица                                                     */

float x[N];   /* вектор                                                       */

int i,j,k;       /* текущие индексы строк и столбцов     */

float m;

/*       Ввод матрицы                                                        */

cout<< "\nВведите размер массива\n";

cin>>n;

for (i=0; i< n; i++)

  for (j=0; j< n; j++)

     a[i][j] = i * j % 5 + i - j;

/*       Печать матрицы                                                             */

cout<< "\nПолученная матрица\n";

for (i=0; i< n; i++)

{ putchar('\n');

   for (j=0; j< n; j++) printf("%3.0f ",a[i][j]);

}

putchar('\n');

/*       Получение вектора из матрицы                            */

/* Определение номера столбца, содержащего                  */

/* первый по порядку максимальный элемент                    */

for (i=0; i< n; i++)

{ k=0;

   for (j=1; j< n; j++)

       if (a[i][j] > a[i][k]) k = j;

   /* вычисление скалярного произведения                                */

   /* i-й строки на k-й столбец                                           */

   x[i] = 0;

   for (j=0; j<n; j++)

       x[i] = x[i] + a[i][j] * a[j][k];

}

/* Печать вектора                                                               */

cout<< "\nПолученный из матрицы вектор\n";

for (i=0; i< n; i++)

   cout<< x[i];

putchar('\n');

/* Упорядочивание вектора                                               */

for (i=0; i<n; i++)

{ j = i; m = x[i];

  for (k=i+1; k<n; k++)

      if (x[k] < m) { j = k; m = x[k]; }

  x[j]=x[i]; x[i]=m;

}

/* Печать упорядоченного вектора                                     */

cout<< "\nУпорядоченный вектор\n";

for (i=0; i< n; i++)

cout<<x[i];

putchar('\n');

}

Результаты работы программы

Введите размер массива

6

Полученная матрица

0 -1 -2 -3 -4 -5

1 1 1 1 1 -4

2 3 4 0 1 -3

3 5 2 4 1 -2

4 7 5 3 1 -1

5 4 3 2 1 0

Полученный из матрицы вектор

-55 -10 11 27 36 20

Упорядоченный вектор

-55 -10 11 20 27 36

Статические и динамические массивы

При объявлении переменной типа массив размер массива должен быть задан целочисленной константой. Если количество элементов заранее не известно, то размер выбирается в расчете на максимально возможное для конкретной задачи количество элементов, что не всегда эффективно.

Память для массива распределяется статически на этапе трансляции (до выполнения программы), такие массивы называются статическими. В явном виде в языке С/С++ можно использовать только статические массивы.

Динамические массивы можно реализовать неявно, с помощью динамического распределения памяти.

Для создания динамического массива объявляется переменная типа указатель в следующем виде:

<тип> *<имя>, например int * adr,

тогда переменная adr – указатель (ссылка) на целочисленную величину.

На этапе трансляции память выделяется только для указателя (для хранения адреса, обычно четыре байта). Динамическое выделение памяти для массива обеспечивается в программе с помощью функций управления памятью.

В языке С++ можно динамически выделить память, выполнив операцию new с названием типа в качестве операнда. Если операция выполнилась успешно, результатом является адрес выделенной памяти, иначе - пустой указатель, поэтому результат операции необходимо проверять.

Пример создания динамического массива с помощью операции new:

int n;

float *z;                       // указатель (ссылка)

cin >> n;

z = new float [n];               // выделение памяти

if (z == NULL) { cout<< “No memory”; return 1;} // ошибка

for (int i = 0; i < n; i++)

cin >> z[i];

….

delete [] z;                          // освобождение памяти

return 0;                            // успешное завершение

Пояснения к фрагменту программы.

1. Объявляется целочисленная величина int n - количество элементов массива, значение которой будет введено во время выполнения программы: cin >> n;

2. Объявляется указатель на вещественную величину:  float *z;

3. Операция new выделяет память для n вещественных чисел и возвращает начальный адрес выделенной памяти, который присваивается указателю z. Результат операции проверяется: в случае получения пустого указателя программа завершается.

4. Доступ к элементам динамического массива такой же, как к элементам статического массива. Например, к элементу с номером i в массиве z можно обратиться как z[i] или с помощью указателей *(z + i) (к начальному адресу прибавлено смещение элемента c индексом i).

Другой способ динамического выделения и освобождения памяти – использование  стандартных функций управления памятью malloc и free (и их разновидностей).

Пример создания динамического массива с помощью функции malloc:

int n;                                               

int *z;                                                  // указатель (ссылка)  

cin >> n;                                         

z = (int *) malloc ( n * sizeof(int));     // выделение памяти

if (z == NULL) { cout<< “No memory”; return 1;} // ошибка            

for (int i = 0; i < n; i++)             

cin >> z[i];                                 

….

free (z);                              // освобождение памяти

return 0;                            // успешное завершение

Пояснения к фрагменту программы.

1. Функция malloc() выделяет участок памяти, размер которого в байтах задан в виде параметра, и возвращает в качестве значения указатель (адрес) на начало выделенного участка. Если не оказалось свободной памяти заданного размера, возвращает пустой указатель NULL.

2. Значение операции sizeof (тип) равно количеству байтов, необходимых для хранения величины указанного типа.

3. Перед вызовом функции malloc записана операция преобразования типа (int *). Функция malloc возвращает указатель типа void *, поэтому в примере требуется преобразование к типу указатель на целую величину.

Память, выделенная под динамический массив, должна быть освобождена перед завершением программы. Память, выделенная с помощью операции new [], освобождается оператором delete[], а память выделенная вызовом функции malloc()  - вызовом функции free().

Функция free освобождает участок памяти (выделенный ранее функцией malloc), указатель (адрес) которого является ее параметром.

delete[] z; free (m);

#include "stdafx.h"

#include <iostream>

#include <conio.h>

int main(int argc, char* argv[])

{

int n,i,j;

cin>>n;

int **d;

d=new int *[n];

for (i =0; i<n;i++)

         d[i]=new int[n];

for(i=0;i<n; i++)

         for(j=0;j<n;j++)

                  cin>>d[i][j];

for(i=0;i<n; i++){

         putchar('\n');

for(j=0;j<n;j++)

                  cout<<d[i][j];

}

getch();

return 0;

}


Дата добавления: 2018-09-23; просмотров: 119; Мы поможем в написании вашей работы!

Поделиться с друзьями:




Мы поможем в написании ваших работ!