中文名通讯录转换成拼音排序后发现李、黎 姓的排序夹杂在一起,比如李三、黎三、李四。下面的排序就是将李姓排在一起,同音姓按照中文汉字来排序,让其不再混在一起。
#include <iostream>
#include <string>
#include <list>
#include <string.h>
#include <algorithm>
static const char trailingBytesForUTF8[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
4, 5, 5, 5, 5 }; //检查包含的字节数
static bool compareFilterName(char c) {
if (c == '-' || c == ' ' || c == '(' || c == ')') {
return true;
}
return false;
}
static std::string trimName(const std::string& name) {
std::string filter_name = name;
if (filter_name.empty()) {
return filter_name;
}
//remove_if()将所有应该移除的元素都移动到了容器尾部并返回一个分界的迭代器.
//移除的所有元素仍然可以通过返回的迭代器访问到. 为了实际移除元素, 你必须对容器自行调用erase()以擦除需要移除的元素
std::string::iterator new_end = std::remove_if(filter_name.begin(),
filter_name.end(), compareFilterName);
filter_name.erase(new_end, filter_name.end());
return filter_name;
}
测试的通讯录数据,包含通讯录人名以及人名转换后对应的拼音
struct Contact {
std::string name;
std::string name_pin;//拼音已经按照单个汉字转换,每个汉字拼音中间用空格隔开
};
//获取姓名中的姓
std::string getFirstName(const std::string& name) {
unsigned char c = name.at(0);
int len = trailingBytesForUTF8[c] + 1;
std::string destination = name;
if (name.size() >= len) {
destination = name.substr(0, len);
}
//std::cout << "des =" << destination << std::endl;
return destination;
}
//获取姓对应的拼音
std::string getFirstPingYin(const std::string& pinyin) {
std::string des = pinyin;
int pos = pinyin.find_first_of(" ");
if (pos < pinyin.size()) {
des = pinyin.substr(0, pos);
}
//std::cout << "des-pin =" << des << std::endl;
return des;
}
int main() {
std::list<Contact> listBooks;//测试通讯录数组
Contact cc;
cc.name = "李工";
cc.name_pin = "li gong";
listBooks.push_back(cc);
cc.name = "里三";
cc.name_pin = "li san";
listBooks.push_back(cc);
cc.name = "李网1";
cc.name_pin = "li wang";
listBooks.push_back(cc);
cc.name = "黎四1";
cc.name_pin = "li si";
listBooks.push_back(cc);
cc.name = "里四";
cc.name_pin = "li si";
listBooks.push_back(cc);
cc.name = "黎三";
cc.name_pin = "li san";
listBooks.push_back(cc);
cc.name = "李网";
cc.name_pin = "li wang";
listBooks.push_back(cc);
cc.name = "黎四";
cc.name_pin = "li si";
listBooks.push_back(cc);
cc.name = "李kk";
cc.name_pin = "li wang";
listBooks.push_back(cc);
std::list<Contact> desList;
std::string prePin = "";//用于保存上一个通讯录姓名的姓拼音
std::string preName = "";//用于保存上一个通讯录姓名的姓
std::list<Contact>::iterator itor = listBooks.begin();
int i = 0;
while (itor != listBooks.end()) {
//姓为空即第一条通讯录数据直接加入目标数组中
if (prePin.empty()) {
std::cout << "prePin empty" << "push --name" << itor->name << std::endl;
desList.push_back(*itor);
} else {
std::string curPin = getFirstPingYin(itor->name_pin);
std::string curName = getFirstName(itor->name);
std::cout << "fullname ="<<itor->name << " curPin =" << curPin << " curName =" << curName << std::endl;
if ((curPin == prePin) && (curName != preName)) {//判断有同音的姓
std::list<Contact>::iterator itorFind = itor;
itorFind++;//last
//查找列表后面是否存在与添加目标数组一样的姓,如果有则先添加到目标数组中,并从源数组中删除
while(itorFind != listBooks.end()){
std::string lastName = getFirstName(itorFind->name);
std::string lastPin = getFirstPingYin(itorFind->name_pin);
std::cout << "while --lastPin =" << lastPin << " lastName =" << lastName << std::endl;
if(lastPin == curPin){
if(lastName == preName){
std::cout << "find same pre name and pin and push list" << "pushand error findItor" << itorFind->name <<std::endl;
desList.push_back(*itorFind);
itorFind = listBooks.erase(itorFind);
}else{
++itorFind;
}
}else{
break;
}
}//while
}
//将当前浏览的通讯录添加到目标数组中
std::cout << "push cur itor" << "push --name" << itor->name << std::endl;
desList.push_back(*itor);
}
prePin = getFirstPingYin(itor->name_pin);
preName = getFirstName(itor->name);
std::cout << "i = " << i++ << " prePin =" << prePin << " preName =" << preName << std::endl;
++itor;
}
for(auto it : desList){
std::cout << "name =" << it.name << " pinyin = " << it.name_pin << std::endl;
}
return 1;
}
运行结果: