如何使用特定的成员变量修剪我的向量?
Posted
技术标签:
【中文标题】如何使用特定的成员变量修剪我的向量?【英文标题】:How do I trim my vector with a specific member variable? 【发布时间】:2020-05-08 01:06:50 【问题描述】:我有一个由字符串标题、int 页数、流派组成的类 Book。 我制作了一些书籍对象,我想返回一本奇幻类型的书,它的页数也排名第二。这是我所做的:
std::vector<Book> sortPages(vector<Book> books) //sorts books in descending order
sort(books.begin(), books.end(), [](const Book& lhs, const Book rhs)
return lhs.getPages() > rhs.getPages();
);
return books;
int main()
Book book ("The Hunger Games ", 374, "Adventure fiction");
Book book1 ("Game of Thrones", 694, "Fantasy");
Book book2 ("Harry Potter and the Philosopher's Stone", 223, "Fantasy");
Book book3 ("Holes", 272, "Adventure fiction");
Book book4 ("The Hobbit", 400, "Fantasy");
Book book5 ("The Maze Runner", 375, "Adventure fiction");
std:vector<Book> books;
books.push_back(book);
books.push_back(book1);
books.push_back(book2);
books.push_back(book3);
books.push_back(book4);
books.push_back(book5);
sortPages(books);
//get all fantasy books, maybe into a new vector?
//print 2nd element of fantasy books vector
return 0;
我在想,我要不要创建一个新的向量来存储所有的奇幻书籍?这是我想要的输出。
"The Hobbit", 400, "Fantasy"
【问题讨论】:
【参考方案1】:您可以使用std::partition
获取所有Fantasy
书籍:
auto i = std::partition(books.begin(), books.end(),
[](auto const &book)
return book.genre == "Fantasy";
);
然后用std::nth_element
得到页数第二多的书:
std::nth_element(books.begin(), books.begin() + 1, i,
[](auto const &book1, auto const &book2)
return book1.pages > book2.pages;
);
现在books[1]
有了答案。
【讨论】:
【参考方案2】:这是您的情况的解决方案。注意不建议在vector使用指针中使用object。
#include <iostream>
#include <vector>
#include <algorithm>
class Book
public:
Book(std::string title, int pages, std::string gender):
m_title(title),
m_pages(pages),
m_gender(gender)
std::string getTitle() const return m_title;
int getPages() const return m_pages;
std::string getGender() const return m_gender;
private:
std::string m_title;
int m_pages;
std::string m_gender;
;
std::vector<Book*> sortPages(std::vector<Book*> books) //sorts books in descending order
std::sort(books.begin(), books.end(), [](const Book* lhs, const Book* rhs)
return lhs->getPages() > rhs->getPages();
);
return books;
std::vector<Book*> getSpecificGender(std::vector<Book*> books, const std::string gender) //sorts books in descending order
std::vector<Book*> result;
for(auto it=books.begin();it!=books.end();it++)
if(gender == (*it)->getGender())
result.push_back(*it);
std::sort(result.begin(), result.end(), [](const Book* lhs, const Book* rhs)
return lhs->getPages() > rhs->getPages();
);
return result;
Book* get2ndRankBook(std::vector<Book*> books, const std::string gender) //sorts books in descending order
Book* first_rank_book=nullptr;
Book* second_rank_book=nullptr;
std::sort(books.begin(), books.end(), [](const Book* lhs, const Book* rhs)
return lhs->getPages() > rhs->getPages();
);
for(auto it=books.begin();it!=books.end();it++)
if(gender != (*it)->getGender())
continue;
if(!first_rank_book)
first_rank_book = *it;
if(first_rank_book->getPages()>(*it)->getPages())
second_rank_book=first_rank_book;
first_rank_book = *it;
return second_rank_book;
int main()
Book* book = new Book ("The Hunger Games ", 374, "Adventure fiction");
Book* book1 = new Book ("Game of Thrones", 694, "Fantasy");
Book* book2 = new Book ("Harry Potter and the Philosopher's Stone", 223, "Fantasy");
Book* book3 = new Book ("Holes", 272, "Adventure fiction");
Book* book4 = new Book ("The Hobbit", 400, "Fantasy");
Book* book5 = new Book ("The Maze Runner", 375, "Adventure fiction");
std::vector<Book*> books;
books.push_back(book);
books.push_back(book1);
books.push_back(book2);
books.push_back(book3);
books.push_back(book4);
books.push_back(book5);
sortPages(books);
//get all fantasy books, maybe into a new vector?
//print 2nd element of fantasy books vector
auto fantasy = getSpecificGender(books, "Fantasy");
for(auto it=fantasy.begin();it!=fantasy.end();it++)
std::cout<<(*it)->getTitle()<<", "<<(*it)->getPages()<<", "<<(*it)->getGender()<<std::endl;
std::cout<<"2nd Rank:"<<std::endl;
Book* second_book = get2ndRankBook(books,"Fantasy");
if(!second_book)
std::cout<<"There is no second rank book!"<<std::endl;
else
std::cout<<second_book->getTitle()<<", "<<second_book->getPages()<<", "<<second_book->getGender()<<std::endl;
delete book;
delete book1;
delete book2;
delete book3;
delete book4;
delete book5;
return 0;
测试结果:
Game of Thrones, 694, Fantasy
The Hobbit, 400, Fantasy
Harry Potter and the Philosopher's Stone, 223, Fantasy
2nd Rank:
The Hobbit, 400, Fantasy
【讨论】:
“不建议在向量中使用对象使用引用或指针”是不好的建议,完全不正确。在 C++ 中甚至不可能使用引用向量(必须是 reference_wrapper),并且指针向量仅在特定情况下才真正有用——但不是很好,因为它们不传达所有权(在现代 C++ 中,应该是 @987654323 @/shared_ptr
除非只观察状态)。值类型的向量并没有什么不好,而 r-value/move 语义使得移动包含值的向量变得很便宜。
此外,这个解决方案存在内存泄漏,因为分配的Book
s 都不是delete
d。以上是关于如何使用特定的成员变量修剪我的向量?的主要内容,如果未能解决你的问题,请参考以下文章