Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Учебное пособие_С++2015

.pdf
Скачиваний:
179
Добавлен:
15.03.2016
Размер:
2.8 Mб
Скачать

Обработка матриц

Базовыми алгоритмами обработки матриц являются те же алгоритмы, которые используются при обработке одномерных массивов: организация

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

1.Алгоритмы реализуются для всех элементов матрицы (просмотр может быть с условием). Начальная установка искомых параметров выполняется перед двойным циклом. В этом случае запись операторов цикла для индексов i и j осуществляется последовательно друг за другом и имеет вид:

<начальная установка искомых параметров>

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

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

<тело цикла>;

2.Алгоритмы реализуются внутри каждой строки или каждого столбца матрицы. В этом случае начальная установка искомых параметров выполняется между операторами цикла, записанными для индексов i и j. Например, если алгоритм реализуется для каждой строки, то запись в

программе имеет следующий вид:

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

{

<начальная установка искомых параметров> for ( j = 0; j< n; j++)

<тело цикла>;

}

Ниже рассмотрены примеры программирования задач каждого типа.

Реализация алгоритмов задач первого типа

 

 

Задача 1. Дана

матрица

вещественных

чисел

А = {аij}4х6.

Вычислить значение Z = Р1/|Р2|, где Р1 и Р2 – произведения положительных и отрицательных элементов матрицы соответственно.

Решение

Эта задача относится к первому типу, так как для вычисления P1 и P2 следует просмотреть всю матрицу. В этой задаче инициализацию переменных P1 и P2 следует сделать один раз перед циклами по индексам элементов матрицы.

91

НАЧАЛО

Ввод матрицы А

P1=0 P2=0

i = 0, 3

J = 0, 5

Z=P1/|P2|

 

 

Да

Aij>0

Вывод Z

 

 

P1=P1 . Aij

Aij<0

Да

Конец

 

 

P2=P2 . Aij

Текст программы:

 

#include "stdafx.h"

 

#include<math.h>

 

int main()

 

{ float A [4][6] ;

// описание матрицы А

int i;

 

int j;

float P1, P2; float Z;

printf("Введите матрицу А\n"); for ( i =0; i<4; i++)

for ( j = 0;j<6; j++) scanf("%f",&A[i][j]);

P1=1; P2=1; // установка начальных значений произведений for ( i = 0; i<4; i++) //цикл по строкам

for ( j =0; j<6 ;j++) //цикл по столбцам

{

92

if (A[i][j]>0) P1= P1*A[i][j]; // произведение

+

if ( A[i][j]<0) P2 = P2*A[i][j];// произведение

-

}

 

Z=P1/abs(P2);

 

printf("Z=%10.2f \n",Z);

 

return 0;

 

}

 

Задача 2. В квадратной целочисленной матрице В= {bij}5х5 вычислить модуль разности между числом нулевых элементов, стоящих ниже главной диагонали, и числом нулевых элементов, стоящих выше главной диагонали.

Введем обозначения:

L1 – счетчик нулевых элементов ниже главной диагонали;

L2 – счетчик нулевых элементов выше главной диагонали; Требуется найти L = | L1 -L2 |.

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

НАЧАЛО

Ввод

матрицы

L1=0 L2=0

i = 0, 4

J = 0, 4

 

 

L = | L1 – L2 |

 

 

 

 

 

 

Да

 

 

 

 

 

 

 

 

 

 

Bij = 0

 

Да

Вывод L

 

 

 

 

 

 

 

 

 

i > j

L1 = L1 + 1

Конец

Да

i< j

L2 = L2 + 1

93

Текст программы:

 

#include "stdafx.h"

 

#include<math.h>

 

#include<stdlib.h>

 

#include<iostream>

 

int main()

 

{

 

int B[5][5] ;

// описание матрицы B

int i, j, L1, L2, L; for ( i = 0; i< 5; i++)

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

B[i][j]= floor(rand()/1000.0);

L1 = 0; // инициализация счетчиков L1 и L2

L2 = 0;

for ( i = 0; i< 5; i++) for (j = 0; j< 5; j++)

if (B[i][j]==0 )

// поиск элементов, равных нулю

{

 

 

if ( i>j)

L1=L1+1;

// выше главной диагонали

if ( i<j)

L2=L2+1;

// ниже главной диагонали

}

L = abs(L1 - L2); std::cout<<"L="<<L<<"\n"; return 0;

}

Реализация алгоритмов задач второго типа

Задача 1. В матрице X ={хij}3х6 вещественных чисел первый элемент каждой строки поменять местами с минимальным элементом этой строки. Вывести матрицу X после обмена. ( Для заполнения матрицы воспользуемся датчиком случайных чисел).

94

НАЧАЛО

Инициализация матрицы Х

Вывод Матрицы Х

i = 0, 3

min=106

 

Вывод

 

матрицы Х

 

 

 

 

Конец

J = 0, 6

 

 

 

Да

X[i][jmin]=X[i][0]

Х[i][j]<min

X[i][0]=min

 

min=X[i][j]

jmin=j

Текст программы:

 

#include "stdafx.h"

 

#include<math.h>

 

int main()

 

{

 

 

float X[3][6];

// описание матрицы X

int

i,j,jmin;

 

float

min;

 

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

for (j= 0; j<6;

j++)

X[i][j]=rand()/100; /* заполнение элемента матрицы случайным числом*/

printf(" матрица X\n");

for(i=0; i<3; i++) //вывод матрицы до перестановки

95

{

for (j=0; j<6; j++) printf("%8.2f",X[i][j]); printf("\n");

}

for(i=0; i<3; i++) //цикл по строкам

{

min=+1E6; // установка начального значения min

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

//цикл по столбцам

if (X[i][j]<min)

// поиск минимума

{

 

min=X[i][j];

 

jmin=j;

 

}

 

X[i][jmin]=X[i][0];// перестановка первого элемента

X[i][0]=min;

// матрицы с наименьшим

}

for(i=0; i<3; i++) //вывод матрицы после перестановки

{

for (j=0; j<6; j++) printf("%8.2f",X[i][j]); printf("\n");

}

return 0;

}

Задача 2. Дана матрица вещественных чисел С = {сij}8х4. Вычислить среднее арифметическое каждого столбца. Результат оформить в виде одномерного массива S = {sj};j = 1,4 .

Данная задача

#include "stdafx.h" int main()

{float C[8][4]; float S[4]; int i, j;

printf("Введите матрицу С:\n"); for(i=0; i<8; i++)

for (j= 0; j<4; j++) scanf("%f",&C[i][j]);

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

{

S[j]=0; //начальная установка элемента массива для сумм

96

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

S[j]= S[j] + C[i][j]; //накопление суммы j-го столбца S[j]=S[j]/8; //вычисление среднего значения суммы j-го столбца

}

for (j= 0; j<4; j++) printf("%8.2f",S[j]); // вывод всех сумм

printf("\n"); return 0;

}

В приведенной выше программе для вычисления каждого элемента S[j] организован двойной цикл, в котором индекс j является внешним параметром цикла, а индекс i - внутренним.

Приведем вариант программы без использования одномерного массива S.

#include "stdafx.h"

#include <iostream> using namespace std; int main()

{float C[8][4]; float S;

int i, j;

printf("Введите матрицу С:\n"); for(i=0; i<8; i++)

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

scanf("%f",&C[i][j]); for (j= 0; j<4; j++)

{

S=0;

for(i=0; i<8; i++) S= S + C[i][j];

S = S/8;

cout<<"Среднее арифметическое "<<j<<" столбца="<<S<<endln;

}

return 0;

}

2.11. Подпрограммы Структура сложной программы

Любая программа на языке высокого уровня может быть разбита на ряд логически завершенных программных единиц - подпрограмм. Такое разделение вызвано двумя причинами.

97

1.Экономия памяти. Каждая подпрограмма записывается в программе один раз, в то время как обращаться к ней можно многократно из разных точек программы.

2.Структурирование программы. Алгоритм решения задачи может быть достаточно сложным, поэтому целесообразно выделить самостоятельные смысловые части алгоритма и оформить их в виде подпрограмм.

Вязыке С++ существует один вид подпрограмм, который называется функция.

Функция – это именованная последовательность описаний и операторов, выполняющая какое-то законченное задание, как например, стандартная

функция sin(…) из математической библиотеки предназначена и используется для вычисления синуса указанного в ее скобках аргумента.

Каждая программа на языке С++ должна иметь главную функцию (main), которая служит точкой входа в программу. Кроме главной функции в программе может быть оформлено произвольное число подпрограмм-функций. Создаваемая подпрограмма-функция должна иметь следующую структуру:

ЗАГОЛОВОК

{

Тело функции

}

Заголовок функции называется ее объявлением, а тело функции называется ее описанием. Любая подпрограмма-функция должна быть объявлена и определена.

Заголовок подпрограммы-функции должен иметь следующую структуру:

тип имя_функции ( [ список параметров])

Рассмотрим составные части заголовка.

Тип – это тип возвращаемого функцией значения. Он может быть любым(int, float, char, указатель на массив или другую функцию). Если функция не должна возвращать никакого значения, указывается тип void (пусто). Если никакой тип не указан, по умолчанию считается тип int.

Список параметров определяет величины, которые следует передать в функцию при ее вызове. Элементы списка параметров разделяются запятыми. Для каждого параметра указывается его тип и имя. Квадратные скобки около списка параметров в заголовке обозначают, что список может отсутствовать, то есть быть пустым.

Имя функции – это произвольная последовательность символов, придуманная разработчиком этой функции.

98

Объявление и описание подпрограммы-функции само по себе никаких действий не вызывает. При запуске программы выполнение начинается с операторов главной функции main(). Чтобы выполнить подпрограмму, в нужной точке главной функции main или любой другой функции, входящей в состав программы, необходимо записать обращение к подпрограмме-функции по ее имени. Для того чтобы функция могла быть вызвана, т.е. была доступна, необходимо, чтобы до ее вызова о ней было известно компилятору. Это значит, что либо мы текст функции должны поместить до функции, из которой она вызывается (например, перед main()), , либо перед main() записать прототип функции.

Ниже схематично приведены две возможные структуры программы, в которой объявлена и описана подпрограмма-функция.

#include "stdafx.h"

ЗАГОЛОВОК

{

тело функции

}

main()//начало главной функции

{…

имя-функции (параметр1, параметр2,…);

/*обращение к подпрограмме-функции */

} //конец главной функции

Многоточие перед main обозначает, что там могут содержаться объявления и описания других функций.

Прототип функции по форме аналогичен заголовку функции, но в конце которого ставится ";". Второй вариант компоновки программы, содержащей подпрограмму-функцию, будет выглядеть так:

#include "stdafx.h"

ЗАГОЛОВОК;

main() //начало главной функции

{…

имя-функции (параметр1, параметр2,…);

/*обращение к подпрограмме-функции */

} //конец главной функции

99

ЗАГОЛОВОК

{

тело функции

}

Функции

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

Общий вид описания функции

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

Тип Имя_функции(список формальных параметров)

{

Описание локальных переменных; Операторы тела функции; return результат;

}

Тип, указываемый в заголовке функции, определяет тип результата ее работы, который будет возвращаться в точку вызова. Если тип не указан, то по умолчанию подразумевается int (целый). Для возврата значения в теле функции должен быть оператор return. В дальнейшем будем называть такую функцию типизированной.

Если функция не должна возвращать результат, то она считается нетипизированной, что задается ключевым словом void, стоящим в заголовке на месте типа. В этом случае оператор return в функции не требуется.

void имя_функции(список формальных параметров)

{

Описание локальных переменных; Операторы тела функции;

}

Рассмотрим пример оформления программы, содержащей текст типизированной функции maximum для нахождения максимального значения из двух заданных целых чисел.

#include "stdafx.h"

int maximum(int a, int b) //заголовок функции maximum

{

100