通讯录同音姓按照汉字排序

中文名通讯录转换成拼音排序后发现李、黎 姓的排序夹杂在一起,比如李三、黎三、李四。下面的排序就是将李姓排在一起,同音姓按照中文汉字来排序,让其不再混在一起。

#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;
}

运行结果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值