Срезы — подмножества в массивах значений

Еще одним мощным инструментом для работы с массивами значений является инструмент выделения подмножеств, над которыми потом можно выполнять различные операции. Например, у нас есть массив значений: 1 6 3 6 7 9. С каждым вторым значением нужно совершить какую-то операцию, к примеру вычесть 1. То есть подмножеством данного массива значений будет: 6 6 9. Вот у этих элементов вычитаем 1, получаем такое подмножество: 5 5 8. Весь же массив значений, после вычитания 1, будет выглядеть так: 1 5 3 5 7 8. Для того, чтобы такие операции было достаточно просто выполнять, в заголовочном файле valarray придумали механизм работы с подмножествами. Далее вы убедитесь, что он очень простой в понимании.

Есть 4-ре способа определения подмножеств в массивах значений, вот они:

  1. срезы,
  2. обобщенные срезы,
  3. отбор по логическому признаку,
  4. перечисляемые подмножества.

В этой статье мы рассмотрим как можно выделять подмножества с помощью срезов. Итак, как же выглядит срез и как им пользоваться? Рассмотрим фрагмент кода:

slice(0, 10, 2)

slice() — это функция, которая задает подмножество, диапазон значений массива, которые будут обработаны тем или иным образом. У функции slice() есть три параметра:

  • первый — индекс элемента массива, с которого будет начинаться выборка, в примере индекс равен 0, значит выборка начнется с первого элемента массива.
  • второй — количество элементов в массиве, которые подлежат выборке
  • третий — шаг выборки, в примере шаг равен 2, а значит каждый второй элемент попадет в подмножество.

Также надо знать, что эту функцию надо вызывать внутри квадратных скобок, например так:

array[slice(0, 10, 2)] = 5;

То есть каждому элементу этого подмножества присвоили значение 5. Давайте рассмотрим пример программы для более подробного изучения срезов:

#include <iostream>
#include <valarray>     // заголовочный файл массивов значений

using namespace std;
int main()
{
    valarray<int> array(-1, 20);
    cout << "Массив: ";
    for(int i = 0; i < array.size(); i++) {
        cout << array[i] << " ";
    }

    array[slice(2, 5, 4)] = 5; // пяти элементам массива, начиная с индекса 2 с шагом в 4 элемента присвоить значение 5
    array[slice(0, 7, 3)] = 2; // семи элементам массива, начиная с индекса 0 с шагом в 3 элемента присвоить значение 2

    cout << "\nМассив после применения срезов: ";
    for(int i = 0; i < array.size(); i++) {
        cout << array[i] << " ";
    }

    // начиная с нулевого элемента, возвести 10 элементов в квадрат, с шагом - 2
    array[slice(0, 10, 2)] = pow(static_cast<valarray<int> >(array[slice(0, 10, 2)]), 2);

    cout << "\nМассив квадратов четных элементов: ";
    for(int i = 0; i < array.size(); i++) {
        cout << array[i] << " ";
    }
    return 0;
}

Обратите внимание на строки 13-14, в этих строках мы вызываем функцию  slice() для определения среза. В строке 13, мы присваиваем каждому четвертому элементу, начиная с элемента с индексом 2, значение 5, причем элементов, которым мы присвоим значение пять должно быть — пять, это указано во втором параметре. Аналогичную операцию мы проделываем и в строке 14, только на этот раз параметры среза немного другие. Выборка начинается с первого элемента массива, с шагом 3 и ограничивается семью элементами, им мы присваиваем значение 2. Результат этих операций вы можете посмотреть ниже:

CppStudio.com
Массив: -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
Массив после применения срезов: 2 -1 5 2 -1 -1 2 -1 -1 2 5 -1 2 -1 5 2 -1 -1 2 -1 
Массив квадратов четных элементов: 4 -1 1 2 25 -1 4 -1 1 2 1 -1 4 -1 1 2 1 -1 4 -1

В строке 22 мы еще раз воспользовались срезом. На этот раз каждый элемент подмножества мы возводим в квадрат с помощью функции pow(). Кстати заметьте, что такие стандартные математические функции как pow(), sqrt() и другие работают с массивами значений. Но нельзя не заметить, что в качестве параметра, функции pow() передается аргумент приведенный к типу данных valarray с помощью операции static_cast. К сожалению, почти всегда приходится делать явное преобразование подмножеств к типу valarray. Это связано с тем, что в стандартной библиотеке не указано, что подмножества поддерживают те же операции что и множества.

Автор: Marienko L.
Дата: 25.01.2014
Поделиться:

Комментарии

  1. blablabla

    В начале статьи написано про 4-е способа выборки из массивов, а по факту ссылка 3 = ссылке 4.

  2. NaikoN

    А разве 22 строка не должна быть такой:

    array[slice(0, 10, 2)] = pow(static_cast<valarray<int> >(array[slice(0, 10, 2)]), 2);

    Так симпотичнее :)

Оставить комментарий

Вы должны войти, чтобы оставить комментарий.