本例是 Completed Modern C++的容器的一个课后作业,做起来还是比较简单的。
注释写的比较完整了。
题目,
STL Project
Create a contacts application that allows users to store contact information:
1. First Name
2. Last Name
3. Primary phone number
4. Secondary phone number
5. Email id
6. Address
7. Company
8. Group (Friends, Family, Coworker, Acquaintance)
Provide the following features:
1. Display all contacts sorted by first or last name (provide an option that users can choose)
2. Display only first name with primary number
3. Display contacts from the same company only
4. Display contacts based on group type
5. Allow contact search by first or last name
6. Display count of contacts by company and group.
Decide carefully about the usage of containers and algorithms
CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(chat_room)
add_definitions(-std=c++14)
add_compile_options(
"-g"
)
find_package(Boost REQUIRED COMPONENTS
system
filesystem
serialization
program_options
thread
)
include_directories(${Boost_INCLUDE_DIRS})
file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
foreach( sourcefile ${APP_SOURCES} )
file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile})
if( "${filename}" STREQUAL "main.cpp")
string(REPLACE ".cpp" "" file ${filename})
add_executable(${file} ${APP_SOURCES})
target_link_libraries(${file} ${Boost_LIBRARIES})
target_link_libraries(${file} pthread)
endif()
endforeach( sourcefile ${APP_SOURCES})
代码,
main.cpp
#include "contact_manager.h"
int main(int argc, char* argv[]) {
std::vector<Contact> contacts {
Contact {"San", "Zhang", "17316289999", "17316288888", "zhangsan@gmail.com", "ShenzhenFutian", "ST", Group::Friends},
Contact {"Si", "Li", "13928276666", "13828275555", "lisi@gmail.com", "BeijingChaoyang", "KS", Group::Coworker},
Contact {"Liu", "Zhao", "17316277779", "17516285688", "zhaoliu@gmail.com", "SanyaYalongwan", "ST", Group::Friends},
Contact {"Liu", "Wang", "13828272222", "13628275567", "wangwu@gmail.com", "BeijingHaidian", "KS", Group::Coworker},
};
ContactManager cm {std::move(contacts)};
std::cout << "Display sorted by firstName.." << std::endl;
cm.displaySortedContact();
std::cout << std::endl;
std::cout << "Display sorted by lastName.." << std::endl;
cm.displaySortedContact(Option::LastName);
std::cout << std::endl;
std::cout << "Display only firstName with primary Number.." << std::endl;
cm.displayFirstNameWithPrimaryNumber();
std::cout << std::endl;
std::cout << "Display contacts from a company.." << std::endl;
cm.displayContactsFromACompany("ST");
std::cout << std::endl;
std::cout << "Display contacts based on group type.." << std::endl;
cm.displayContactsOnGroupType();
std::cout << std::endl;
std::cout << "Search contacts by first name.." << std::endl;
cm.searchContact("Liu", Option::FirstName);
std::cout << std::endl;
std::cout << "Search contacts by last name.." << std::endl;
cm.searchContact("Zhang", Option::LastName);
std::cout << std::endl;
std::cout << "Display count of contacts by company and group..." << std::endl;
cm.displayCountOfContacts();
std::cout << std::endl;
return 0;
}
contact.h
#ifndef _FREDRIC_CONTACT_H_
#define _FREDRIC_CONTACT_H_
#include <iostream>
#include <string>
enum class Group {
Friends,
Family,
Coworker,
Acquaintance
};
struct Contact {
std::string firstName{};
std::string lastName{};
std::string primaryPhoneNumber{};
std::string secondaryPhoneNumber{};
std::string emailID{};
std::string address{};
std::string company;
Group group{Group::Friends};
};
std::ostream& operator<<(std::ostream& out, const Contact& contact);
#endif
contact.cpp
#include "contact.h"
std::ostream& operator<<(std::ostream& out, const Contact& contact) {
out << contact.firstName << " " << contact.lastName << " " << contact.address << " "
<< contact.emailID << " " << contact.company << " " << contact.primaryPhoneNumber << " "
<< contact.secondaryPhoneNumber << " ";
switch (contact.group)
{
case Group::Friends:
out << "Friends";
break;
case Group::Family:
out << "Family";
break;
case Group::Coworker:
out << "Coworker";
break;
case Group::Acquaintance:
out << "Acquaintance";
break;
default:
out << "Err, Wrong group";
break;
}
return out;
}
contact_manager.h
#ifndef _CONTACT_MANAGER_H_
#define _CONTACT_MANAGER_H_
#include "contact.h"
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
#include <unordered_map>
enum class Option {
FirstName,
LastName
};
class ContactManager {
std::vector<Contact> contacts_;
public:
ContactManager(const std::vector<Contact>& contacts);
ContactManager(std::vector<Contact>&& contacts);
void displaySortedContact(Option option=Option::FirstName);
void displayFirstNameWithPrimaryNumber() const;
void displayContactsFromACompany(const std::string& company) const;
void displayContactsOnGroupType();
void searchContact(const std::string& name, Option option=Option::FirstName) const;
void displayCountOfContacts();
};
#endif
contact_manager.cpp
#include "contact_manager.h"
ContactManager::ContactManager(const std::vector<Contact>& contacts)
: contacts_{contacts} {}
ContactManager::ContactManager(std::vector<Contact>&& contacts)
: contacts_{contacts} {}
void ContactManager::displaySortedContact(Option option) {
if (option == Option::FirstName) {
std::sort(contacts_.begin(), contacts_.end(),
[](const Contact& c1, const Contact& c2) {
return c1.firstName.compare(c2.firstName) > 0 ? false
: true;
});
} else {
std::sort(contacts_.begin(), contacts_.end(),
[](const Contact& c1, const Contact& c2) {
return c1.lastName.compare(c2.lastName) > 0 ? false
: true;
});
}
for (const auto& contact : contacts_) {
std::cout << contact;
std::cout << std::endl;
}
}
void ContactManager::displayFirstNameWithPrimaryNumber() const {
std::for_each(contacts_.begin(), contacts_.end(),
[](const Contact& contact) {
std::cout << contact.firstName << " "
<< contact.primaryPhoneNumber << std::endl;
});
}
void ContactManager::displayContactsFromACompany(
const std::string& company) const {
std::for_each(contacts_.begin(), contacts_.end(),
[&company](const Contact& contact) {
if (contact.company.compare(company) == 0) {
std::cout << contact << std::endl;
}
});
}
void ContactManager::displayContactsOnGroupType() {
std::unordered_multimap<Group, Contact> cMap;
for (const auto& c : contacts_) {
cMap.emplace(c.group, c);
}
for (auto ele : cMap) {
std::string groupName{};
switch (ele.first) {
case Group::Friends:
groupName = "Friends";
break;
case Group::Family:
groupName = "Family";
break;
case Group::Coworker:
groupName = "Coworker";
break;
case Group::Acquaintance:
groupName = "Acquaintance";
break;
default:
break;
}
std::cout << "Group: " << groupName << " Contact: " << ele.second
<< std::endl;
}
}
void ContactManager::searchContact(const std::string& name,
Option option) const {
std::vector<Contact>::const_iterator resBegin = contacts_.begin();
std::vector<Contact>::const_iterator resEnd{contacts_.end()};
while (resBegin != resEnd) {
resBegin =
std::find_if(resBegin, contacts_.end(),
[&option, &name](const Contact& contact) {
if (option == Option::FirstName) {
if (contact.firstName.compare(name) == 0) {
return true;
} else {
return false;
}
} else {
if (contact.lastName.compare(name) == 0) {
return true;
} else {
return false;
}
}
});
if (resBegin != resEnd) {
std::cout << *resBegin << std::endl;
++resBegin;
}
}
}
struct ContactHashFunc {
std::size_t operator()(const Contact& c) const {
return std::hash<std::string>()(c.company) ^
std::hash<Group>()(c.group);
}
};
struct ContactEqualFunc {
std::size_t operator()(const Contact& c1, const Contact& c2) const {
return (c1.company == c2.company) && (c1.group == c2.group);
}
};
void ContactManager::displayCountOfContacts() {
std::unordered_map<Contact, int, ContactHashFunc, ContactEqualFunc> countMap{};
std::for_each(contacts_.begin(), contacts_.end(),
[&countMap](const Contact& contact) {
if (countMap.find(contact) != countMap.end()) {
countMap[contact]++;
} else {
countMap[contact] = 1;
}
});
std::string groupInfo{};
for (const auto& eleInfo : countMap) {
switch (eleInfo.first.group) {
case Group::Friends:
groupInfo = "Friends";
break;
case Group::Family:
groupInfo = "Family";
break;
case Group::Coworker:
groupInfo = "Coworker";
break;
case Group::Acquaintance:
groupInfo = "Acquaintance";
break;
default:
groupInfo = "Err Wrong group";
break;
}
std::cout << eleInfo.first.company << " " << groupInfo << " "
<< "has " << eleInfo.second << " person.." << std::endl;
}
}
程序输出如下,
image.png
网友评论