- •Содержание Введение
- •Задача 1: Обнаружить учетку памяти
- •Задача 2. Составить тесты к программе
- •Задача 3: Напечатать все содержимое файла на экран.
- •Задача 3: Напечатать все содержимое файла на экран (оптимизация).
- •Задача 4. Удалить все нечетные элементы из массива
- •Задача4.Удалить все нечетные элементы из массива (оптимизация)
- •Задача 4. Удалить все нечетные элементы из массива (последующая оптимизация)
- •Задача 4. Удалить все нечетные элементы из массива (основа тестов)
- •Задача 5. В файле удалить все слова, которые начинаются и заканчиваются одной буквой
- •Задача 5. В файле удалить все слова, которые начинаются и заканчиваются одной буквой (без использования потоков и std::string)
- •Задача 6. Удалить строки, в которых есть два одинаковых элемента (без использования std::vector)
- •Задача 6. Удалить строки, в которых есть два одинаковых элемента (c использованием std::vector)
- •Задача 7. Отсортировать содержимое словаря
- •Задача 8. Реализовать сохранение и загрузку пользовательских структур данных с использованием fstream
- •Заключение Глоссарий
- •Список рекомендуемой литературы
Задача 4. Удалить все нечетные элементы из массива (последующая оптимизация)
Теперь необходимо отметить, что STL имеет множество готовых функций. Для работы с этими функциями необходимо подключить #include <algorithm>. Одна из этих функций – remove_if, которая возвращает итератор на элементы, которые подходят под условие. В нашем случае (когда вектор чисел) этот итератор будет иметь тип vector<int>::iterator
Для использования функции remove_if необходимо ввести функцию-предикат, которая будет указывать на необходимость удаления элемента
bool isOdd(int s) {
return s % 2 == 1;
}
При вызове функции необходимо указать диапазон вектора, который надо проверять. В нашем случае это весь вектор – от начала (vector.begin()) до конца (vector.end()). Так же необходимо указать функцию, которая будет указывать на необходимость удаления эдемента – в нашем случае это функция isOdd
Полученный итератор надо передать в функцию erase, указав окончание цепочки (оно совпадает с окончанием вектора, потому что проверяем весь вектор). Таким образом, главная функция обработки будет выглядить следующим образом:
void mainAction(vector<int> &data) {
vector<int>::iterator newEnd = remove_if(data.begin(),data.end(), isOdd);
data.erase(newEnd, data.end());
}
Следует отметить, что данную функцию в Visual C++ можно сократить, используя ключевое слово auto (полный аналог var в C# - автоопределяемые типы) и анонимные функции (для замены функции isOdd). Тогда главная функция примет следующий вид:
void mainAction(vector<int> &data) {
auto newEnd = remove_if(data.begin(), data.end(),
[](int s) {return s % 2 == 1; });
data.erase(newEnd, data.end());
}
Еще раз отметим, что эти преобразования будут работать только в Visual C++, поскольку auto в других компиляторах С++ имеет другой смысл. Поэтому такими оптимизациями мы пользоваться не будем.
Так же следует отметить, что с помощью итераторов можно сделать вывод вектора. Итератор указывает на элемент контейнера (вектора), поэтому для вывода значения элемента необходиом взять значение по адресу, на который указывает итератор. Поэтому операцию вывода можно так же реализовать следующим способом:
void printVector(char *caption, vector<int> &data) {
cout << caption << ": ";
for (vector<int>::iterator i = data.begin(); i != data.end(); ++i) {
cout << *i << " ";
}
cout << "\n";
}
Приведем полный код решения задачи:
#include <vector>
#include <time.h>
#include <conio.h>
#include <iostream>
#include <algorithm>
using namespace std;
bool isOdd(int s) {
return s % 2 == 1;
}
void mainAction(vector<int> &data) {
vector<int>::iterator newEnd = remove_if(data.begin(),
data.end(), isOdd);
data.erase(newEnd, data.end());
}
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;
}