使用 map






2.89/5 (9投票s)
2002年1月5日
2分钟阅读

138084

1165
本文的目标是演示如何使用 STL 的关联容器之一——map。
引言
本文的目标是演示如何使用 STL 的关联容器之一——map。关联容器将一个键与一个值关联起来,允许根据键找到对应的值。map 和 multimap 是关联容器中最强大的两个。它们允许键和值都具有不同且任意的数据类型。map 和 multimap 的区别在于,map 要求键是唯一的,而 multimap 则没有这个要求。
因此,map 类支持一个关联容器,其中唯一的键被映射到值。本质上,键只是您为值指定的一个名称。一旦值被存储,您就可以使用其键来检索它。因此,从最广泛的意义上讲,map 是一个键/值对的列表。map 的强大之处在于,您可以根据键查找值。
map 的模板规范如下所示
template <class Key, class T, class Comp = less<Key>, class Allocator = allocator<T> class map
这里,Key 是键的数据类型,T 是存储(映射)的值的数据类型,Comp 是一个比较两个键的函数。
map 类包含许多有用的函数,但我会优先考虑这个类的一些最重要的函数,例如:insert、erase 和 find,它们代表了这个关联容器的最强武器。
这些函数根据业务需求封装在 MyCompanyEmployees
类中。
本文的测试应用程序指的是负责公司中员工简单管理的系统。这只是一个原型,但足以说明 map 类的强大功能及其可能的用途。
在我的测试应用程序中,我还使用了一个修改后的 String 类 Tokenizer
。
作为说明,我将给出一个相对简单的示例,包含以下类层次结构
class Employee { // Some code }; class Employees { virtual bool InitData() = 0; public: Employee employee; virtual bool AddToEmployees( Employee new_employee ) = 0; virtual bool RemoveFromEmployees( string ssn ) = 0; virtual bool FindEmployee( string ssn, Employee &employee_found ) = 0; }; class MyCompanyEmployees : public Employees { EmployeeMap theMap; EmployeeMap::iterator theIterator; bool InitData(); public: MyCompanyEmployees(); ~MyCompanyEmployees(); bool AddToEmployees( Employee new_employee ); bool RemoveFromEmployees( string ssn ); bool FindEmployee( string ssn, Employee &employee_found ); STRING_VECTOR GetData( Employee employee ); }; // MyCompanyEmployees.cpp #include <iostream> #include <fstream> #include "MyCompanyEmployees.h" #include "StringTokenizer.h" MyCompanyEmployees::MyCompanyEmployees() { InitData(); } MyCompanyEmployees::~MyCompanyEmployees() { } bool MyCompanyEmployees::AddToEmployees( Employee new_employee ) { bool bRet; pair<map<string, Employee>::iterator, bool> result; result = theMap.insert( pair<string, Employee>( new_employee.GetSSN(), Employee( new_employee ) ) ); if( result.second ) bRet = true; else bRet = false; return bRet; } bool MyCompanyEmployees::RemoveFromEmployees( string ssn ) { bool bRes; int nResult; nResult = theMap.erase( ssn ); if( nResult != 0 ) bRes = true; else bRes = false; return bRes; } bool MyCompanyEmployees::FindEmployee( string ssn, Employee &employee_found ) { bool bRet; theIterator = theMap.find( ssn ); if( theIterator != theMap.end() ) { employee_found = theIterator->second; bRet = true; } else bRet = false; return bRet; } bool MyCompanyEmployees::InitData() { bool bRet = true; char row[200]; ifstream file( "parsing_file.txt", ios::in ); if( !file ) { cerr << "Error while file opening!"; bRet = false; goto Exit; } while( !file.eof() ) { file.getline( row, 200 ); StringTokenizer strtok( row, "," ); employee.SetSSN( strtok.elementAt( 0 ) ); employee.SetFirstName( strtok.elementAt( 1 ) ); employee.SetLastName( strtok.elementAt( 2 ) ); employee.SetMaritalStatus( strtok.elementAt( 3 ) ); employee.SetHomeAddress( strtok.elementAt( 4 ) ); employee.SetHomePhoneNumber( strtok.elementAt( 5 ) ); employee.SetOfficePhoneNumber( strtok.elementAt( 6 ) ); employee.SetSalary( strtok.elementAt( 7 ) ); employee.SetTitle( strtok.elementAt( 8 ) ); theMap.insert( pair<string, Employee>( employee.GetSSN(), Employee(employee) ) ); } Exit: return bRet; } STRING_VECTOR MyCompanyEmployees::GetData( Employee employee ) { vector<string> str_vector; str_vector.push_back( employee.GetSSN() ); str_vector.push_back( employee.GetFirstName() ); str_vector.push_back( employee.GetLastName() ); str_vector.push_back( employee.GetMaritalStatus() ); str_vector.push_back( employee.GetHomeAddress() ); str_vector.push_back( employee.GetHomePhoneNumber() ); str_vector.push_back( employee.GetOfficePhoneNumber() ); str_vector.push_back( employee.GetSalary() ); str_vector.push_back( employee.GetTitle() ); return str_vector; }
这是一个纯 C++ 驱动程序,主函数如下所示
#include <iostream> #include "MyCompanyEmployees.h" typedef vector<string> STRING_VECTOR; int main( void ) { string ssn; Employee emp; MyCompanyEmployees MyCompany; STRING_VECTOR employee_data; STRING_VECTOR::iterator employee_data_iterator; char input; cout << "DEMONSTRATION PROGRAM - EMPLOYEE" << endl; while( 1 ) { cout << "Enter add(a), remove(r), find(f), quit(q): "; cin >> input; switch( input ) { case 'a': { string ssn, first_name, last_name, marital_status, home_address, home_phone_number, office_phone_number, salary, title; cout << endl << "Enter SSN: "; cin >> ssn; cout << "Enter first name: "; cin >> first_name; cout << "Enter last name: "; cin >> last_name; cout << "Enter marital status: "; cin >> marital_status; cout << "Enter home address: "; cin >> home_address; cout << "Enter home phone number: "; cin >> home_phone_number; cout << "Enter office phone number: "; cin >> office_phone_number; cout << "Enter salary: "; cin >> salary; cout << "Enter title: "; cin >> title; emp.SetSSN( ssn ); emp.SetFirstName( first_name ); emp.SetLastName( last_name ); emp.SetMaritalStatus( marital_status ); emp.SetHomeAddress( home_address ); emp.SetHomePhoneNumber( home_phone_number ); emp.SetOfficePhoneNumber( office_phone_number ); emp.SetSalary( salary ); emp.SetTitle( title ); if( MyCompany.AddToEmployees( emp ) ) cout << "Insertion occured...\n"; else cout << "Duplicate not allowed...\n"; } continue; case 'r': { cout << "Enter SSN that you want to remove: "; cin >> ssn; if( !MyCompany.RemoveFromEmployees( ssn ) ) cout << "Error while removing..." << endl; else cout << "Removing occured..." << endl; } continue; case 'f': { cout << "Enter SSN that you want to find: "; cin >> ssn; if( MyCompany.FindEmployee( ssn, emp ) ) { employee_data = MyCompany.GetData( emp ); for( employee_data_iterator = employee_data.begin(); employee_data_iterator != employee_data.end(); employee_data_iterator++ ) { cout << *employee_data_iterator; if( employee_data_iterator != employee_data.end() - 1 ) cout << ", "; } cout << endl; } else cout << "Name not in directory...\n"; } continue; case 'q': cout << "Quit\n"; exit( 0 ); default: cout << "Error: Bad command " << input << '\n'; break; } } return 0; }
作为数据源,您有一个简单的文本 (parsing_file.txt) 文件,其中包含四行数据
1111,John,Johnson,yes,Street1,(416)111-1111,(416)101-1010,50000,Manager 2222,Adam,Smith,yes,Street2,(416)222-2222,(416)202-2020,35000,Technician 3333,Bob,Fitzgerald,no,Street3,(416)333-3333,(416)303-3030,45000,Programmer 4444,James,Sulivan,no,Street4,(416)444-4444,(416)404-4040,40000,Teacher
第一列同时代表 map 中的键,因此如果您想查找或删除 map 中的某些数据,您应该只输入数字:1111 或 2222 或…
这个例子更有用,因为我们正在 map 中存储类对象。
我推荐一本非常有帮助的程序员书籍,它讨论了 STL 主题——“从基础开始的 STL 编程”,Herbert Schildt。