лаба5 3й семестр
.docxСт. Новичонок М.С. Гр. ІНФ-15-1
Лабораторная работа №5
Тема: «Алгоритмы стандартной библиотеки С++»
Вариант №6
Необходимые задачи таковы:
1. обеспечить для контейнера возможность чтения из файла и записи в файл с использованием итераторов потоков.
2. обеспечить для контейнера сортировку по названию книги (это должна быть сортировка по умолчанию), а также сортировку по числу авторов.
3. вынести в отдельный вектор все книги, начиная с книги, первый автор которой написал более 4 книг
4. сохранить все имена авторов из вектора шага 3 в новом векторе.
5. найти число авторов с именами идущими по алфавиту за заданным в векторе, полученном на шаге 4.
6. найти среднее число авторов для всех книг с использованием accumulate()
7. проверить, входит ли вектор, полученный на шаге 3, в исходный вектор как подпоследовательность.
Main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "book.hpp"
#include <fstream>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <numeric>
struct TitleComparator
{
bool operator()(Book const & _lhs, Book const & _rhs) const
{
return _lhs.getTitle() > _rhs.getTitle();
}
};
struct AuthorAmountComparator
{
bool operator()(Book const & _lhs, Book const & _rhs) const
{
return _lhs.getAuthorsAmount() > _rhs.getAuthorsAmount();
}
};
int main()
{
Topic topics[3];
Author authors[8];
std::vector<Book> books;
int tindex = 0,
aindex = 0;
std::ifstream file("file.txt");
std::ofstream out("outfile.txt");
std::vector<std::string> v;
std::copy(
std::istream_iterator<std::string>(file),
std::istream_iterator<std::string>(),
std::back_inserter(v));//итератор вставки
auto it = v.begin();
while (it != v.end())
{
if (*it == "Topic")
{
topics[tindex].m_name = *(++it);
char tCode[10];
strcpy(tCode, (++it)->c_str());
topics[tindex].m_code = atoi(tCode);
tindex++;
}
if (*it == "Author")
{
authors[aindex].m_name = *(++it);
authors[aindex].m_surname = *(++it);
char booksNumber[10];
strcpy(booksNumber, (++it)->c_str());
authors[aindex].m_nWrittenBooks = atoi(booksNumber);
char index[100];
strcpy(index, (++it)->c_str());
authors[aindex].m_favouriteTopic = topics[atoi(index)];
aindex++;
}
if (*it == "Book")
{
std::string tempTitle;
tempTitle = *(++it);
char bindex[10];
strcpy(bindex, (++it)->c_str());
int topicIndex = atoi(bindex);
Book tempBook(tempTitle,topics[topicIndex]);
while (*(it + 1) != "Book" && *(it + 1) != "END")
{
char authorIndex[10];
strcpy(authorIndex, (++it)->c_str());
tempBook.addAuthor(authors[atoi(authorIndex)]);
}
books.push_back(tempBook);
}
it++;}
out << "UNSORTED : " << std::endl;
for (auto const & book : books)
out << book << std::endl;
std::sort(books.begin(),books.end(),TitleComparator());//алгоритм сортировки
out << "SORTED BY TITLE : " << std::endl;
for (auto const & book : books)
out << book << std::endl;
std::sort(books.begin(), books.end(), AuthorAmountComparator());
out << "SORTED BY AUTHOR AMOUNT : " << std::endl;
for (auto const & book : books)
out << book << std::endl;
auto it1 = std::find_if(
books.begin(),
books.end(),
[&](Book const & _b)
{
if (_b.getAuthor(0).m_nWrittenBooks > 4)
return true;});
std::vector<Book> newBooks(it1,books.end());
out << "BOOK WHICH 1 AUTHOR WROTE MORE THEN 4 BOOKS : " << std::endl;
for (auto const & book : newBooks)
out << book << std::endl;
std::vector<std::string> a;
std::for_each( //алгоритм, требующий функциональный объект в качестве параметра
newBooks.begin(),
newBooks.end(),
[&](Book const & _b)
{
for (int i = 0; i < _b.getAuthorsAmount(); i++)
a.push_back(_b.getAuthor(i).m_name + " " + _b.getAuthor(i).m_surname);} );
out << "AUTHORS NAMES FROM PREVIOUS BOOK SET : " << std::endl;
for (auto const & author : a)
out << author << std::endl;
int nSortedNamesCount = 0;
std::string prev = "";
for (int i = 0; i < a.size() - 1; i++)
{
if (a[i] < a[i + 1])
{
if (prev != a[i])
nSortedNamesCount += 2;
else if (prev == a[i])
nSortedNamesCount++;
prev = a[i + 1];
}
}
out << "AUTHORS WHO IS IN ALPHABET ORDER : " << nSortedNamesCount << std::endl;
float averageNumberOfAuthors = std::accumulate(
books.begin(),
books.end(),
0.0,
[&](float _accumulator, Book const & _b)/*арифм.алгоритм накопление элементов*/)
{
_accumulator += _b.getAuthorsAmount();
return _accumulator;
}
) / books.size();
out << "AN AVERAGE NUMBER OF AUTHORS : " << averageNumberOfAuthors << std::endl;
auto it2 = std::search(books.begin(), books.end(), newBooks.begin(), newBooks.end());
if (it2 != books.end())
out << "IS A SUBSEQUENCE" << std::endl;
else
out << "ISN'T A SUBSEQUENCE" << std::endl;
return 0;}
BOOK.CPP
#include "book.hpp"
#include <algorithm>
std::ostream & operator <<(std::ostream& _s, Book const & _b)
{
_s << "Book title : " << _b.m_title << std::endl;
_s << "The topic of the book:" << std::endl <<" Name "
<< _b.m_topic.m_name << std::endl
<< " Code " << _b.m_topic.m_code << std::endl;
_s << "Authors:" << std::endl;
for (auto const & author : _b.m_authors)
_s << author.m_name << " " << author.m_surname << " "
<< author.m_favouriteTopic.m_name << " " << author.m_favouriteTopic.m_code << " "
<< author.m_nWrittenBooks << std::endl;
return _s;
}
Book::Book(
std::string const & _title,
Topic const & _topic
)
: m_title(_title)
, m_topic(_topic)
{}
Book const & Book::operator=(Book const & _b)
{
return Book(_b);
}
bool Book::isAuthorWroteBook(Author const & _a) const
{
for (auto const & author : m_authors)
if (author.m_name == _a.m_name && author.m_surname == _a.m_surname)
return true;
return false;
}
int Book::getAuthorsAverageAmountOfWrittenBooks() const
{
int totalBooks = 0;
for (auto const & author : m_authors)
totalBooks += author.m_nWrittenBooks;
return totalBooks / m_authors.size();
}
void Book::addAuthor(Author const & _a)
{
m_authors.push_back(_a);
}
void Book::removeAuthor(Author const & _a)
{
auto it = std::find_if(
m_authors.begin(),
m_authors.end(),
[&](Author const & _author)
{
return _a.m_name == _author.m_name
&& _a.m_surname == _author.m_surname;
}
);
if (it == m_authors.end())
std::cout << "Hasn't got this author." << std::endl;
m_authors.erase(it);
}
int Book::getAuthorMaxWrittenBooks() const
{
int maxWrittenBooks = 0;
for (auto const & author : m_authors)
if (author.m_nWrittenBooks > maxWrittenBooks)
maxWrittenBooks = author.m_nWrittenBooks;
return maxWrittenBooks;}
int Book::getAuthorsWhoHasTheSameTopic() const
{
int nAuthorWithTheSameTopic = 0;
for (auto const & author : m_authors)
if (author.m_favouriteTopic.m_code == m_topic.m_code)
nAuthorWithTheSameTopic++;
return nAuthorWithTheSameTopic;
}
BOOK.HPP
#ifndef BOOK_HPP
#define BOOK_HPP
#include <conio.h>
#include <iostream>
#include <string>
#include <vector>
struct Topic
{
std::string m_name;
int m_code;
};
struct Author
{
std::string m_name;
std::string m_surname;
Topic m_favouriteTopic;
int m_nWrittenBooks;
};
class Book
{
public:
Book(
std::string const & _title,
Topic const & _topic );
~Book() = default;
Book(Book const &) = default;
Book const & operator=(Book const &);
friend std::ostream & operator <<(std::ostream& _s, Book const & _b);
bool operator == (Book const & _b) const;
Topic const getTopic() const;
std::string const getTitle() const;
void addAuthor(Author const & _a);
void removeAuthor(Author const & _a);
bool isAuthorWroteBook(Author const & _a) const;
int getAuthorsAverageAmountOfWrittenBooks() const;
int getAuthorMaxWrittenBooks() const;
int getAuthorsWhoHasTheSameTopic() const;
int getAuthorsAmount() const;
Author getAuthor(int _index) const;
private:
std::vector<Author> m_authors;
Topic m_topic;
std::string m_title;};
inline
Topic const Book::getTopic() const
{
return m_topic;
}
inline
std::string const
Book::getTitle() const
{
return m_title;
}
inline
int Book::getAuthorsAmount() const
{
return m_authors.size();
}
inline
Author Book::getAuthor(int _index) const
{
return m_authors[_index];
}
inline
bool Book::operator == (Book const & _b) const
{
return m_title == _b.m_title;
}
#endif // !BOOK_HPP