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

Задача 6. Удалить строки, в которых есть два одинаковых элемента (c использованием std::vector)

Теперь решим эту задачу с использованием STL.

  1. Логика программы «глобально» при оптимизации не изменится. В отличие от массива, у std::vector есть функция size(), которая возвращает размер вектора. Поэтому переменная size в классе MatrixString больше не нужна. С учетом этого содержимое файла MatrixString.h станет следующим:

#include <vector>

class MatrixString {

private:

std::vector<int> data;

int getRandValue(int max, int min);

int getCount(int element);

public:

MatrixString(int size_);

~MatrixString();

void print();

bool needDelete();

};

  1. Следует отметить, что в конструкторе мы знаем размер вектора, который в конечном счете сформируется. Поэтому желательно зарезервировать необходимое количество элементов в векторе, что бы избежать лишних перевыделений памяти во время заполнения вектора. И это необходимо сделать в конструкторе.

MatrixString::MatrixString(int size) {

data.reserve(size);

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

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

}

}

  1. Все остальные функции в MatrixString так же почти не изменятся, за исключением того, что везде size заменится на data.size().

  2. Теперь рассмотрим изменение класса Matrix. По полной аналогии заменим MatrixString ** на std::vector<MatrixString *> и избавимся от переменной size. Теперь обратим внимание на то, что в MatrixString не осталось операторов new и new []. Поэтому у нас не будет проблем с динамической памятью. И теперь не надо контролировать вызов создания строки матрицы и можно заменить std::vector<MatrixString *> на std::vector<MatrixString> и таким образом избавится от операторов new, new[], delete, delete[]. С учетом этого содержимое файлов Matrix.h и Matrix.cpp станет следующим:

Содержимое файла Matrix.h:

Содержимое

#include <vector>

#include "MatrixString.h"

class Matrix {

private:

std::vector<MatrixString>strings;

void delByIndex(int index);

public:

Matrix(int sizeX, int sizeY);

void print();

void process();

};

СодержимоефайлаMatrix.cpp

#include "MatrixString.h"

#include "Matrix.h"

#include <stdio.h>

void Matrix::delByIndex(int index) {

strings.erase(strings.begin() + index, strings.begin() + index + 1);

}

Matrix::Matrix(int sizeX, int sizeY) {

strings.reserve(sizeY);

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

strings.push_back(MatrixString(sizeX));

}

}

void Matrix::print() {

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

strings[i].print();

}

printf("\n");

}

void Matrix::process() {

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

if (strings[i].needDelete()) {

delByIndex(i);

}

}

}

  1. Содержимое lab2_1.cpp не изменится

Задача 7. Отсортировать содержимое словаря

Задача: в файле «in.txt» находится словарь. Каждая строка словаря содержит только одно слово. Необходимо в файл «out.txt» записать слова, отсортированные по алфавиту.

  1. Логично предположить, что данная задача представима в виде последовательности трех действий:

    1. Считывание строк из файла in.txt

    2. Сортировка строк

    3. Сохранение результатов в файл out.txt.

  2. Первая подзадача уже разбиралась в 3й задаче, поэтому подробно на ней останавливаться не будем. Приведем код функции, которая отвечает за чтение всех строк из файла (обратите внимание на подключение fstream для работы с ifstream – input file stream):

#include <conio.h>

#include <iostream>

#include <fstream>

#include <vector>

#include <algorithm>

#include <string>

using namespace std;

int readFromFile(std::string dictionary_name, std::vector<string> &words) {

ifstream ifs(dictionary_name);

if (!ifs.is_open()) {

cout << "Could not open file: " << dictionary_name << endl;

return 1;

}

//пока не дошли до конца файла

while (ifs.eof() == false) {

string curLine;

getline(ifs, curLine);

words.push_back(curLine);

}

ifs.close();

return 0;

}

  1. Теперь необходимо отсортировать список. Следует отметить, что данную задачу можно реализовать с помощью стандартных алгоритмов STL.

sort(words.begin(), words.end());

Естественно возникает вопрос о том, какие еще стандартные алгоритмы доступны в модуле alogorithm. Их можно разделить на четыре категории:

  1. Неизменяющие алгоритмы над последовательностями

    1. for_each – приминяет фунцию к каждому элементу

    2. find – выполняет линейный поиск

    3. find_first_of – выполняет линейный поиск любого из множества значений

    4. adjacent_find – выполняет линейный поиск смежных равных элементов

    5. count – подсчитывает количество элементов с данным значением

    6. mismatch – сканирует две последовательности в поисках первой позиции, где они различны

    7. equal - сканирует две последовательности для проверки их поэлементной эквивалентности

    8. search – сканирует последовательность в поисках друго подпоследовательности

    9. search_n – сканирует последовательность в поисках ряда идентичных элементов с данным значением

    10. find_end – сканирует последовательность в поисках последнего совпадения с другой последовательностью

  2. Изменяющие алгоритмы над последовательностями

    1. copy – копирует элементы в другоую последовательность

    2. swap – обменивает элементы одной последовательности с элементами другой

    3. transform – замещает каждый элемент значением, возвращаемым после применения переденной в качестве параметра функции к элементу

    4. replace ­­– замещает каждый эдемент, равный некоторому значению копией другого заданного значения

    5. fill – замещает каждый элемент копией другого заданного значения

    6. generate – замещает каждый элемент значением, возвращаемым вызовом функции

    7. remove – удаляет элементы, равные заданному значению

    8. unique – удаляет последовательные равные элементы

    9. reverse – обращает относительный порядок элементов

    10. rotate – выполняет циклический сдвиг элементов

    11. random_shuffle – псевдослучайно переупорядочивает элементы

    12. partition – переупорядочивает элементы таким образом, что элементы, удовлетворяющие указанному предикату, предшествуют элементам, не удовлетворяющим ему.

  3. Алгоритмы, связанные с сортировкой

    1. sort, stable_sort, partial_sort – переставляют элементы последоватьльности в порядке возрастания

    2. nth_element – находит N-й наименьший элемент последовательности

    3. binary_search, lower_bound, upper_bound, equal_range – выполняют поиск в отсортировнной последовальности методом деления пополам

    4. megre – сливает дву отсортировнные последовательности в одну

    5. includes, set_union, set_intersection, set_difference, set_symmetric_difference –выполняют теоретико-множественные операции над отсортированными структурами

    6. push_heap, pop_heap, make_heap, sort_heap -выполняют операции по упорядочиванию последоватьности, лрганизованной в виде пирамиды

    7. min, max, min_element, max_element находят минимальный или максимальный элемент пары или последовательности

    8. lexicographical_compare – лексикографически сравнивает две последовательности

    9. next_permutation, prev_permutation – генерируют перестановки последовательности, основываясь на лексикографическом упорядочении множества всех перестановок

  4. Обобщенные числовые алгоритмы

    1. accumulate – вычисляет сумму элементов последовательности

    2. inner_product – вычисляет сумму произведение соответствующих элементов последовательностей

    3. partial_sum – вычисляет частичные суммы элементов последовательности и сохраняет их в другой (или той же) последовательности

    4. adjacent_difference – вычисляет разности смежных элементов и сохраняет их в другой (или той же) последовательности.

  1. Запись в выходной файл так же не представляет из себя сложностей:

int writeToFile(std::string fileName, std::vector<string> &words){

ofstream ofs(fileName);

if (!ofs.is_open()) {

cout << "Could not open file: " << fileName << endl;

return 1;

}

for (vector<string>::iterator i = words.begin(); i != words.end(); ++i) {

ofs << *i << "\n";

}

ofs.close();

return 0;

}

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

#include <conio.h>

#include <iostream>

#include <fstream>

#include <vector>

#include <algorithm>

#include <string>

using namespace std;

int readFromFile(string dictionaryName, vector<string> &words) {

ifstream ifs(dictionaryName);

if (!ifs.is_open()) {

cout << "Could not open file: " << dictionaryName << endl;

return 1;

}

while (ifs.eof() == false) {

string curLine;

getline(ifs, curLine);

words.push_back(curLine);

}

ifs.close();

return 0;

}

int writeToFile(string fileName, vector<string> &words) {

ofstream ofs(fileName);

if (!ofs.is_open()) {

cout << "Could not open file: " << fileName << endl;

return 1;

}

for (vector<string>::iterator i = words.begin(); i != words.end(); ++i) {

ofs << *i << "\n";

}

ofs.close();

return 0;

}

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

vector<string> words;

readFromFile("in.txt", words);

sort(words.begin(), words.end(), less<string>());

writeToFile("out.txt", words);

//_getch();

return 0;

}