Массив значений может вам облегчить работу с векторами и матрицами, так как обладает очень важным свойством — свойством простотой записи. Например, два массива можно умножить так :
ar3 = ar1 * ar2;
Достаточно простая запись, не правда ли? Кроме умножения, массивы значений также поддерживают все остальные арифметические операции: +, -, / и даже операцию — остаток от деления. По сути, массив значений — это одномерный массив, нумерация элементов которого, как и в обычных массивах, начинается с нуля. Чтобы воспользоваться массивом значений, достаточно подключить заголовочный файл — valarray:
#include <valarray>
Давайте рассмотрим пример использования массива значений в следующей программе:
#include <iostream>
#include <valarray> // заголовочный файл массивов значений
#include <cstdlib>
#include <iomanip>
using namespace std;
int main()
{
srand(time(NULL));
valarray<int> array1(15); // создаем массив значений размером - 15 элементов
valarray<int> array2(15); // создаем массив значений размером - 15 элементов
cout << setw(38) << left << "Первый массив: ";
for(int i = 0; i < array1.size(); i++) {
array1[i] = rand() % 10;
cout << setw(2) << array1[i] << " ";
}
cout << endl << setw(38) << "Второй массив: ";
for(int i = 0; i < array2.size(); i++) {
array2[i] = rand() % 10;
cout << setw(2) << array2[i] << " ";
}
cout << "\nСумма элементов массивов: ";
valarray<int> array3 = array1 + array2;
for(int i = 0; i < array3.size(); i++) {
cout << setw(2) << array3[i] << " ";
}
return 0;
}
Результат работы программы:
Первый массив: 5 3 0 0 1 6 5 3 4 7 1 7 0 0 9 Второй массив: 0 5 6 6 0 9 3 8 3 0 8 9 3 7 4 Сумма элементов массивов: 5 8 6 6 1 15 8 11 7 7 9 16 3 7 13
В строке 2 мы подключили заголовок массивов значений. Строки 10-11, это пример того, как нужно объявлять массивы значений. Ничего сложного в этом нет, как всегда, сначала указывается тип данных, в нашем случае — int. В круглых скобках указан размер одномерного массива — количество элементов. Строки 14-23 просто инициализируют и выводят на экран элементы массивов. Обратите внимание на строку 26, тут выполняется операция сложения одномерных массивов, эта запись вмещается всего в одну строку. Попробуйте сделать тоже самое с обычными массивами. Ничего у вас не получится, так как с обычными массивами придется использовать как минимум цикл, который будет перебирать каждый элемент всех трех массивов. С помощью массивов значений, это делается всего в одну строку:
valarray<int> array3 = array1 + array2;
Вот ради такого упрощения записей и стоит пользоваться этим классом — <valarray>. Давайте еще рассмотрим случай с обычным массивом, например, у нас есть одномерный массив:
int ar[5] = {1, 7, 34, 23, 56};
Мы можем создать объект массива значений используя массив ar. При объявлении массива значений достаточно в первом параметре указать имя массива, а во втором — размер массива, как показано в примере ниже:
valarray<int> array1(ar, sizeof(ar)/sizeof(ar[0]));
Таким образом мы получим, массив значений, инициализированный элементами статического массива С++. Еще необходимо запомнить такую вещь, если мы выполняем какие-то арифметические операции с массивами значений, их типы данных должны быть одинаковыми, в противном случае возникнет ошибка. Вот пример:
valarray<float> array(5); array = 4 * array; // ошибка
Как видно из фрагмента кода, в нем объявлен массив значений — array. После этого, во второй строке выполняется умножение, каждого элемента массива на значение 4. В результате компиляции будет ошибка:
Ошибка говорит о том, что тип данных у множимого — int, а у множителя — float. Типы данных различны, и по этой причине умножение не может выполняться. Поэтому, необходимо сделать так:
array = float(4) * array;
Даже, если бы вместо типа данных int был тип данных double, это все равно считается несоответствием типов данных. Помните об этом и не допускайте таких ошибок. Давайте вернемся к операторам сравнения. Как и в других контейнерах STL, в valarray операции отношений также перегружены, но возвращаемый ими результат в корне отличается. К примеру, рассмотрим следующий код:
#include <iostream>
#include <valarray> // заголовочный файл массивов значений
#include <cstdlib>
using namespace std;
int main()
{
srand(time(NULL));
// создаем два массива значений типа int на 5 элементов
valarray<int> array1(5);
valarray<int> array2(5);
cout << "Первый массив: ";
for(int i = 0; i < array1.size(); i++) {
cout << (array1[i] = rand() % 10) << " ";
}
array2 = rand() % 10; // всем элементам массива array2 присвоили случайное значение
cout << "\nВторой массив: ";
for(int i = 0; i < array2.size(); i++) {
cout << array2[i] << " ";
}
valarray<bool> res(5);
res = (array1 < array2); // в результате выполнения этой операции возвращается массив булевых значений
cout << "\nРезультат: ";
for(int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
return 0;
}
Посмотрите на строку 19, в ней мы присваиваем каждому элементу массива значений array2 случайное число, при этом мы воспользовались лишь операцией присваивания. Конечно же, гвоздем программы является код в строке 27. На первый взгляд может показаться, что результатом будет одно логическое значение: true или false. На самом деле это не так. На самом деле, эта строка:
res = (array1 < array2);
делает следующее:
res[0] = (array1[0] < array2[0]); res[1] = (array1[1] < array2[1]); res[2] = (array1[2] < array2[2]); . . . res[n] = (array1[n] < array2[n]);
где n — индекс последнего элемента массивов. Поэтому в результате выполнения сравнения мы получим массив булевых значений. Остальные операции отношения: >, ==, >=, <= действуют также. Результат работы предыдущей программы:
Первый массив: 5 7 4 2 2 Второй массив: 7 7 7 7 7 Результат: 1 0 1 1 1
Из результата видно, что второй элемент массива array1 не меньше второго элемента массива array2, поэтому в массиве res второй элемент — 0. Во всех остальных случаях результат сравнивания значений получился истинным.
Также вам полезно будет узнать о существовании таких функций как:
sum() — возвращает суму элементов одного множества;
max() — возвращает первое максимальное значение множества;
min() — возвращает первое минимальное значение множества;
На этом все, надеюсь все было понятно и интересно. Вопросы, пожалуйста, задавайте в комментариях или на форуме.
Комментарии
olegovich22
Даже, если бы вместо типа данных
intбыл тип данныхdouble, это все равно считается несоответствием типов данных.Возможно в данной ситуации имелось в виду не int, а float.
Sergrey
Классная статья. Все понятненко написано, не знал о таких возможностях. Обязательно буду использовать в будущем. Автору спасибо