Алгоритмизация. Введение в язык программирования C++

Массивы

Показывать лекцию целиком

Массив – это пронумерованный набор однотипных элементов.

Массивы бывают статическими и динамическими. У статического массива количество элементов известно заранее и не может быть изменено. У динамического массива количество элементов заранее неизвестно и определяется в процессе выполнения программы.

Также массивы различаются по размерности: одномерные, двумерные, трехмерные и т.д. Примером одномерного массива может послужить вектор $$а\{1, 4, 3.5\}$$. Примером двухмерного массива может послужить матрица. Примером трехмерного массива может послужить набор высот местности.

Массивы различают по типу элементов. Бывают целочисленные, вещественные (состоящие из дробных чисел), символьные массивы.

Примеры массивов:

  • вектор $$а\{1, -4, 3.5\}$$ – одномерный вещественный массив из трех элементов;
  • матрица $$A=\left(\begin{matrix}123\\456\end{matrix}\right)$$ – двумерный целочисленный массив из шести элементов;
  • $$\{"x", "3", "\%"\}$$ – одномерный символьный массив;
  • $$\{"x", -3.34, "\%"\}$$ – не является массивом, т.к. часть элементов символы, часть элементов числа.
  • Мы будем рассматривать только статические одномерные и двумерные численные массивы.

    Занятие 1. Одномерные массивы

    Индекс – это номер элемента в массиве.

    У одномерного массива один индекс, обычно он обозначается $$i$$.

    Чтобы использовать одномерный массив в программе, необходимо:

  • объявить массив в функции main():
    тип_данных имя_массива[количество элементов];
    double a[3];   //статический массив а из трех дробных чисел
    int b[7];   //статический массив b из семи целых чисел
  • проинициализировать массив, т.е. задать каждому элементу конкретное числовое значение;
  • провести вычисления, исследования.
  • Примечание. Индексация в массиве начинается с 0, т.е. индекс у самого первого элемента в массиве $$i=0$$. Индексация в массиве $$а(7)=\{-10; 0,2; 3; -4,7; 0,5; -8; 11\}$$ указана на рис. 6.1.

    (рис 6.1) Индексация одномерного массива

    Способы инициализации одномерного массива представлены в табл. 6.1. Обратим внимание на то, что число $$n$$ известно заранее и в программе фигурировать не будет.

    Способы инициализации одномерного массива a[n]
    Часть блок-схемы Часть программы
    1. инициализация числами
    double a[4]={0.5, -2,856, 1};
    2. с клавиатуры:
    double a[n];
    int i;
    for(i=0; i<n; i=i+1){
    	cout<<"a["<<i<<"]=";
    	cin>>a[i];
    }
    3. из файла:
    double a[n];
    int i;
    fstream file;
    file.open("1.txt", ios::in);
    for(i=0; i<n; i=i+1){
    	file>>a[i];
    }
    file.close();
    4. по заданной формуле
    double a[n];
    int i;
    for(i=0; i<n; i=i+1){
    	a[i]=f(i);
    }

    Примечание. Более подробно работа с файлами будет рассмотрена позже.

    Вывод одномерного массива на экран представлен в табл. 6.2.

    Вывод одномерного массива на экран
    Часть блок-схемы Часть программы
    for(i=0; i<n; i=i+1){
    	cout<<"a["<<i<<"]="<<a[i]<<endl;
    }
    				

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

    Принципы исследования одномерного массива
    Часть блок-схемы Часть программы
    1. нахождение суммы:
    s=0;
    for(i=0; i<n; i=i+1){
    	s=s+a[i];
    }
    cout<<"s="<<s<<endl;
    2. нахождение произведения:
    p=1;
    for(i=0; i<n; i=i+1){
    	p=p*a[i];
    }
    cout<<"p="<<p<<endl;
    3. нахождение среднего арифметического и количества элементов:
    s=0, k=0;
    for(i=0; i<n; i=i+1){
    	s=s+a[i];
    	k=k+1;
    }
    s=s/k;
    cout<<"s="<<s<<endl;
    cout<<"k="<<k<<endl;
    4. нахождение максимального элемента:
    max=-10E10;
    imax=0;
    for(i=0; i<n; i=i+1){
    	if(a[i]>max){
    		max=a[i];
    		imax=i;
    	}
    }
    cout<<"max="<<max<<" imax="<<imax<<endl;
    5. нахождение минимального элемента:
    min=10E10;
    imin=0;
    for(i=0; i<n; i=i+1){
    	if(a[i]<min){
    		min=a[i];
    		imin=i;
    		}
    	}
    cout<<"min="<<min<<" imin="<<imin<<endl;
    6. поменять местами элементы с индексами
    tmp=a[i1];
    a[i1]=a[i2];
    a[i2]=tmp;
    7. вычисление формулы $$S=\sum^{n=1}_{i=0}f(a[i],i)$$ :
    s=0;
    for(i=0; i<n; i=i+1){
    	s=s+f(a[i],i);
    }
    cout<<"s="<<s<<endl;

    Пример 1. Даны четыре одномерных массива: $$а(8)=\{1,2,3,4,5,6,7,8\}, b(8)$$ вводится с клавиатуры, $$с(8)$$ вычисляется по формуле $$с_i=2i, d(8)$$ вычисляется по формуле $$d_i=a_i+b_i+c_i$$. Построить таблицу значений массивов.

    Решение. Сначала необходимо проинициализировать массивы согласно условию задачи.

    Массив $$а$$ задан числами (первый способ инициализации), поэтому он будет проинициализирован при объявлении.

    В цикле по переменной $$i (0\le i<8)$$ введем $$b$$ с клавиатуры (второй способ инициализации), массивы $$c$$ и $$d$$ рассчитаем по формулам (четвертый способ инициализации).

    Далее организуем еще один цикл по переменной $$i (0\le i<8)$$, в котором выведем все проинициализированные массивы на экран.

    Вывод таблицы на экран нельзя делать в первом цикле, т.к. в каждой итерации будет идти запрос очередного элемента $$b$$, тогда таблица со значениями массивов будет смешана с запросом элемента $$b$$.

    Блок-схема представлена на рис. 6.2.

    (рис 6.2) Блок-схема для примера 1

    Код программы (Visual Studio) с оператором for:

    // proga27.cpp: определяет точку входа для консольного приложения.
    //
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    using namespace std;
    int main()
    {
    	double a[8]={1,2,3,4,5,6,7,8};
    	double b[8], c[8], d[8];
    	int i;
    	for(i=0; i<8; i=i+1){
    		cout<<"b["<<i<<"]=";
    		cin>>b[i];
    		c[i]=2.0*i;
    		d[i]=a[i]+b[i]+c[i];
    	}
    	cout<<setw(2)<<"i"<<setw(5)<<"a"<<setw(5)<<"b"<<setw(5)<<"c"<<setw(5)<<"d"<<endl;
    	for(i=0; i<8; i=i+1){
    		cout<<setw(2)<<i<<setw(5)<<a[i]<<setw(5)<<b[i]<<setw(5)<<c[i]<< setw(5)<<d[i]<<endl;
    	}
    	return 0;
    }

    Результат выполнения программы:

    Пример 2. Массив $$а(10)$$ задан формулой $$а_i=3i-5$$. Вычислить сумму положительных элементов массива и поменять местами первый и последний элементы.

    Решение.

    Обозначим за $$S$$ сумму положительных элементов массива. При расчете $$S$$ требуется дополнительное условие: "$$a_i>0$$". Первый элемент массива имеет индекс 0, последний элемент имеет индекс 9, поэтому будем менять местами $$а_0$$ и $$а_9$$. Из-за перемены мест элементов массив изменится, поэтому выведем его еще раз.

    Блок-схема представлена на рис. 6.3.

    (рис 6.3) Блок-схема для примера 2

    Код программы (Visual Studio) с оператором for:

    // proga28.cpp: определяет точку входа для консольного приложения.
    //
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    using namespace std;
    int main(){
    	double S, tmp, a[10];
    	int i;
    	S=0;
    	for(i=0; i<10; i=i+1){
    		a[i]=3.0*i-5.0;
    		cout<<setw(3)<<a[i];
    		if(a[i]>0){
    			S=S+a[i];
    		}
    	}
    	cout<<endl;
    	cout<<"S="<<S<<endl;
    	tmp=a[0];
    	a[0]=a[9];
    	a[9]=tmp;
    	for(i=0; i<10; i=i+1){ cout<<setw(3)<<a[i]; }
    	cout<<endl;
    	return 0;}

    Результат выполнения программы:

    Ручной счет:

    при i=0	a(0)=3i-5=3·0-5=-5;
    при i=1	a(1)=3i-5=3·1-5=-2;
    при i=2	a(2)=3i-5=3·2-5=1;
    при i=3	a(3)=3i-5=3·3-5=4;
    при i=4	a(4)=3i-5=3·4-5=7;
    при i=5	a(5)=3i-5=3·5-5=10;
    при i=6	a(6)=3i-5=3·6-5=13;
    при i=7	a(7)=3i-5=3·7-5=16;
    при i=8	a(8)=3i-5=3·8-5=19;
    при i=9	a(9)=3i-5=3·9-5=22;
    сумма положительных элементов S=1+4+7+10+13+16+19+22=92.·

    Занятие 2. Двумерные массивы

    У двумерного массива имеется два индекса: $$i$$ – номер строки, $$j$$ – номер столбца.

    Индексация двумерного массива представлена на рис. 6.4.

    (рис 6.4) Индексация двумерного массива

    Для использования двумерного массива в программе необходимо:

  • Объявить массив в функции main():
    тип_данных имя_массива [количество строк][количество столбцов];
    double a[5][9];   // двумерный массив из 5 строк, 9 столбцов
  • Проинициализировать массив;
  • Провести вычисления, исследования.
  • Способы инициализации двумерного массива $$a[n][m]$$ представлены в таблице 6.4. Обратим внимание на то, что числа $$n$$ и $$m$$ известны заранее и в программе фигурировать не будут.

    Способы инициализации двумерного массива a[n][m]
    Часть блок-схемы Часть программы
    1. из файла:
    double a[n][m];
    int i,j;
    fstream file;
    file.open("1.txt", ios::in);
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		file>>a[i][j];
    	}
    }
    file.close();
    2. по заданной формуле $$a[i][j]=f(i,j)$$:
    double a[n][m];
    int i,j;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		a[i][j]=f(i,j);
    }
    }

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

    Вывод двумерного массива на экран представлен в табл. 6.5.

    Вывод двумерного массива на экран
    Часть блок-схемы Часть программы
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		cout<<setw(6)<<a[i][j];
    	}
    	cout<<endl;
    }

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

    Принципы исследования двумерного массива
    Часть блок-схемы Часть программы
    1. нахождение суммы:
    s=0;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		s=s+a[i][j];
    	}
    }
    cout<<"s="<<s<<endl;
    2. нахождение произведения:
    p=1;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		p=p*a[i][j];
    	}
    }
    cout<<"p="<<p<<endl;
    3. нахождение среднего арифметического и количества элементов:
    s=0, k=0;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		s=s+a[i][j];
    		k=k+1;
    	}
    }
    s=s/k;
    cout<<"s="<<s<<endl;
    cout<<"k="<<k<<endl;
    4. нахождение максимального элемента:
    max=-10E10;
    imax=0; jmax=0;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		if(a[i][j]>max){
    			max=a[i][j];
    			imax=i;
    			jmax=j;
    		}
    	}
    }
    cout<<"max="<<max<<endl;
    cout<<"imax="<<imax<<endl;
    cout<<"jmax="<<jmax<<endl;
    5. нахождение минимального элемента:
    min=10E10;
    imin=0; jmin=0;
    for(i=0; i<n; i=i+1){
    	for(j=0; j<m; j=j+1){
    		if(a[i][j]<min){
    			min=a[i][j];
    			imin=i;
    			jmin=j;
    		}
    	}
    }
    cout<<"min="<<min<<endl;
    cout<<"imin="<<imin<<endl;
    cout<<"jmin="<<jmin<<endl;
    				
    6. поменять элементы $$i1, j1$$ и $$i2, j2$$ местами:
    tmp=a[i1][j1];
    a[i1][j1]=a[i2][j2];
    a[i2][j2]=tmp;
    7. поменять местами строки $$i1$$ и $$i2$$:
    for(j=0; j<m; j=j+1){
    	tmp=a[i1][j];
    	a[i1][j]=a[i2][j];
    	a[i2][j]=tmp;
    }
    8. поменять местами столбцы $$j1$$ и $$j2$$:
    for(i=0; i<n; i=i+1){
    	tmp=a[i][j1];
    	a[i][j1]=a[i][j2];
    	a[i][j2]=tmp;
    }
    9. вычисление формулы $$s=\sum^{n=1}_{i=0}f(a[i][j],i,j)$$:
    s=0;
    for(i=0; i<n; i=i+1){
    	s=s+f(a[i][j],i,j);
    }
    cout<<"s="<<s<<endl;

    Условия для исследования квадратной матрицы (количество строк и столбцов совпадает):

  • для элементов на главной диагонали: $$i=j$$;
  • для элементов над главной диагональю: $$i<j$$;
  • для элементов под главной диагональю: $$i>j$$;
  • для элементов на побочной диагонали: $$i+j=n-1$$;
  • для элементов над побочной диагональю: $$i+j<n-1$$;
  • для элементов под побочной диагональю: $$i+j>n-1$$.
  • Примечание. Если требуется определить, например, сумму элементов, находящихся над главной диагональю, то задаем двумерный цикл по $$i, j$$ и в теле цикла ставим дополнительное условие "$$i<j$$"

    Пример 3. Массив $$а(6, 8)$$ задан формулой $$а_{i,j}=3i-5j$$. Найти сумму элементов во второй строке, поменять местами первую и третью строки, найти произведение по формуле $$P=\prod^2_{i=0}(a_{i,1}-a_{i,0})$$.

    Решение. Данную задачу можно разбить на несколько этапов:

  • задать массив по формуле и вывести его на экран;
  • найти сумму элементов во второй строке и вывести ее на экран;
  • поменять местами первую и третью строки;
  • вывести на экран измененный массив;
  • найти произведение по формуле и вывести его на экран.
  • Каждый указанный этап решается с помощью циклов. Все циклы целесообразно использовать с предусловием (в программе – оператор for). На первом этапе следует организовать двумерный цикл по $$i$$, по $$j$$, т.к. необходимо задать значениями и вывести на экран весь массив. На втором этапе перед циклом необходимо задать $$S=0$$, а в теле цикла по $$j$$ насчитывать значение $$S$$. Индекс $$i$$ задаем как 1, что соответствует второй строке. Следует отметить, что нельзя считать сумму по какой-то определенной строке (столбце, диагонали) внутри двумерного цикла, т.к. в этом случае $$S$$ будет больше в разы (зависит от количества строк/столбцов).На третьем этапе индексы строк берем $$i=0$$ – для первой строки, $$i=2$$ – для третьей строки. Замена строк организуется в одномерном цикле по $$j$$. На четвертом этапе матрица а должна быть отображена на экране. Нам требуется показать, что замена строк выполнена верно.На пятом этапе перед циклом следует задать $$P=1$$, а в теле цикла насчитывать произведение. Цикл организуем одномерный по $$i$$ от 0 до 2 включительно, т.к. согласно формуле изменяется только $$i$$.

    Блок-схема для примера 3 приведена на рис. 6.5.

    (рис 6.5) Блок-схема для примера 3

    Код программы (Visual Studio) с оператором for:

    // proga29.cpp: определяет точку входа для консольного приложения.
    //
    #include "stdafx.h"
    #include <iostream>
    #include <iomanip>
    using namespace std;
    int main()
    {
    	double a[6][8];
    	double S, tmp, P;
    	int i, j;
    	cout<<"Massiv a:"<<endl;
    	for(i=0; i<6; i=i+1){
    		for(j=0; j<8; j=j+1){
    			a[i][j]=3.0*i-5.0*j;
    			cout<<setw(5)<<a[i][j];
    		}
    		cout<<endl;
    	}
    	S=0;
    	for(j=0; j<8; j=j+1){
    		S=S+a[1][j];
    	}
    	cout<<"S="<<S<<endl;
    	for(j=0; j<8; j=j+1){
    		tmp=a[0][j];
    		a[0][j]=a[2][j];
    		a[2][j]=tmp;
    	}
    	for(i=0; i<6; i=i+1){
    		for(j=0; j<8; j=j+1){
    			cout<<setw(5)<<a[i][j];
    		}
    		cout<<endl;
    	}
    	P=1;
    	for(i=0; i<=2; i=i+1){
    		P=P*(a[i][1]-a[i][0]);
    	}
    	cout<<"P="<<P<<endl;
    	return 0;
    }
    Результат выполнения программы:

    Краткие итоги

    Самыми распространенными видами массивов являются одномерные и двумерные массивы. Статические массивы легко задавать и использовать в программе. Циклы делают работу с массивами удобной и доступной.

    Вопросы

  • Что такое массив?
  • Перечислите виды массивов.
  • Что такое индекс?
  • Как добиться отображения массива на экране в виде ровной таблицы?
  • Упражнения

  • Одномерный массив $$Х(8)$$ задать в программе. Найти максимальный из отрицательных элементов и поменять его местами с последним.
  • Одномерный массив $$Х(10)$$ задать с клавиатуры. Найти сумму отрицательных, количество положительных и произведение ненулевых элементов.
  • Одномерный массив $$Х(15)$$ задать числами. Найти среднее арифметическое элементов, удовлетворяющих условию $$\cos(x_i)<0$$.
  • Одномерный массив $$Х(12)$$ задать по формуле $$X[i]=\ln(i+0,1)$$. Найти количество элементов, удовлетворяющих условию $$-0,5<\sin(x_i)\le 0$$, минимальный элемент.
  • Матрицу $$А(5,5)$$ задать по формуле $$A[i,j]=4\sin(7,1i+j)$$. Найти новый одномерный массив $$С$$ из произведений элементов каждой строки матрицы $$А$$. Найти максимальный элемент среди положительных элементов матрицы $$А$$. Заменить третий элемент в первой строке матрицы $$А$$ на найденный максимальный элемент.
  • Матрицу $$А(7,7)$$ задать по формуле $$А[i,j]=\sin(0,1j+i)$$. Найти сумму положительных элементов над главной диагональю матрицы. Найти максимальный элемент среди отрицательных элементов 4-ой строки. Заменить найденный максимальный элемент значением суммы.
  • Матрицу $$А(5,3)$$ задать по формуле $$А[i,j]=\sin(i+0,4)+\cos(j+0,2)$$. Поменять местами первую и последнюю строки матрицы. Подсчитать $$S_i$$ для элементов каждой строки матрицы по формуле: $$S_i=5+\sum^2_{j=0}\frac{1-a_{1j}+a^2_{1j}}{6}$$, где $$i$$ – номер строки.
  • Вернуться к учебному плану