Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Результат_2012_02_09.docx
Скачиваний:
6
Добавлен:
20.04.2015
Размер:
593.36 Кб
Скачать

Задача4.Удалить все нечетные элементы из массива (оптимизация)

Следует отметить, что в С++ существует Standart Type Library (STL). В ней существует множество готовых классов и функций, которые можно использовать.

Название

Реализуемыя структура

bitset

Битовый массив

deque

Очередь с двухсторонним доступом

list

Двухсвязанный список

map

Ассоциативный массив

multimap

Мультиотображение

queue

Односторонная очередь(контейнер-адаптор)

set

Множество

stack

Стек (контейнер-адаптор)

vector

Динамический массив

В этой таблице некоторые строки отмечены как контейнеры-адапторы. Это означает, что это «обертка» над другим классом, но этот тип структур реализован на чем-то ином (для примера, queue реализован на list).

Одним из готовых классов является класс vector, для работы с которым надо подключить #include <vector>. Следует отметить, что он является шаблонным. Для его использования (для работы с целыми числами) надо написать std::vector<int>. Он обладает множеством полезных методов. Поэтому предыдущий вариант решения можно оптимизировать.

  1. При вводе вектора, с учетом того, что известено количество вводимых данных, желательно зарезервировать нужные количество элементов, что бы избежать лишних перевыделейний памяти. Каждый новый элемент данных необходимо добавлять в конец вектора (это можно сделать с помощью операции push_back). Таким образом, функция ввода будет выглядить следующим образом:

void fillVector(vector<int> &data, int size) {

data.reserve(size);

for (int i = 0; i < size; i++) {

data.push_back(getRandValue(-5, 10));

}

}

  1. При выводе вектора можно воспользоваться функцией size() для получения использованного количества элементов. Функция вывода будет иметь следующий вид:

void printVector(char *caption, vector<int> &data) {

cout << caption << ": ";

for (int i = 0; i < data.size(); i++) {

cout << data[i] << " ";

}

cout << "\n";

}

Отдельно следует отметить наличие ссылки (&) при передаче vector<int> в аргументах функции. С точки зрения логики она не нужна. Однако, если её не будет, то при вызове функции будет передаваться копия вектора. А операция создания копии вектора может быть весьма затратной, поэтому для увеличения скорости работы добавление ссылки обосновано.

  1. Для следующей оптимизации необходимо учесть, что vector имеет функцию erase для удаления цепочки элементов. Цепочка характеризуется позицией начала и позицией конца. При этом удаляются все элементы в диапазоне [начало, конец). Так же следует отметить, что начало цепочки указывается от начала вектора, которое можно получить с помощью функции вектора begin(). C учетом этого главная функция обработки будет выглядить следующим образом:

void mainAction(vector<int> &data) {

for (int i = data.size() - 1; i >= 0; i--) {

if (data[i] % 2 == 1) {

data.erase(data.begin() + i, data.begin() + i + 1);

}

}

}

  1. Приведем таблицу наиболее часто встречающихся функций класса vector

Название метода

Выполняемые действия

  1. Приведем полный код решения:

#include <vector>

#include <time.h>

#include <conio.h>

#include <iostream>

using namespace std;

void mainAction(vector<int> &data) {

for (int i = data.size() - 1; i >= 0; i--) {

if (data[i] % 2 == 1) {

data.erase(data.begin() + i, data.begin() + i + 1);

}

}

}

int getCorrectValue() {

while (true) {

int size;

if (!(cin >> size)) {

cin.clear();

while(std::cin.get()!= '\n');

continue;

}

return size;

}

}

void printVector(char *caption, vector<int> &data) {

cout << caption << ": ";

for (int i = 0; i < data.size(); i++) {

cout << data[i] << " ";

}

cout << "\n";

}

int getRandValue(int max, int min) {

return (((double)rand())/RAND_MAX)*(max - min) + min;

}

void fillVector(vector<int> &data, int size) {

data.reserve(size);

for (int i = 0; i < size; i++) {

data.push_back(getRandValue(-5, 10));

}

}

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

srand(time(NULL));

cout << "enter array size: ";

int size = getCorrectValue();

if (size < 0) {

cout << "array size can not be negative number";

_getch();

return 1;

}

vector<int> data;

fillVector(data, size);

printVector("before process", data);

mainAction(data);

printVector("after process", data);

_getch();

return 0;

}