此文已由作者严跃杰授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

Sqlite3是一款C语言实现的小型SQL数据库引擎,它体积小巧但功能强大, 性能表现也非常不错, 因此在客户端及嵌入式应用开发中受到广泛的欢迎。在网易云音乐的开发中,我们就用到了sqlite3,但是不幸的是在开发过程中发现它不支持汉字拼音排序,但这又是必须的功能。今天我们就来看下如何为sqlite3添加汉字拼音排序的功能。

首先我们想到的是既然原生不支持拼音排序,那它是否提供了扩展接口允许我们添加自定义排序功能呢?通过网上查找和文档阅读,果不其然,它为提供了安装比较函数的接口:

int sqlite3_create_collation16(

sqlite3* db,  const char *zName,  int enc,  void* pCtx,  int(*xCompare)(void*,int,const void*,int,const void*)

)int sqlite3_create_collation(

sqlite3* db,  const char *zName,  int enc,  void* pCtx,  int(*xCompare)(void*,int,const void*,int,const void*)

)

前者用来安装UTF-16的比较函数,后者用来安装UTF-8的比较函数。

除了扩展接口,还有一项资源是必须要有的,当然就是汉字拼音库。网上一通猛找,发现没有合适的。后来发现是云音乐资源包里已经有一个现成的汉字拼音库,省却了不少麻烦(共享在附件工程解决方案目录下)。

必要的资源有了,就可以着手实现了。

以下是获取汉字拼音实现

std::wstring LetterHelp::ConvertLetterToPinyin(const std::wstring& chinese)

{

std::wstring str_pinyin;for(unsigned int i = 0; i

{wchar_t tch = chinese[i];const char *pinyin_char = GetLetter((unsigned short)tch);

if(pinyin_char)

{int len = strlen(pinyin_char);

wchar_t* wch = new wchar_t[len];

FUTF82WConvert(pinyin_char,wch, len);

str_pinyin.append(wch);

}else

{

str_pinyin.push_back(tch);

}

}return str_pinyin;

}const char* LetterHelp::GetLetter(unsigned short ch)

{if(ch >= HANZI_MIN && ch <= HANZI_MAX)return m_pinyin + m_code[ch - HANZI_MIN];else

return nullptr;

}

以下比较函数实现:

// 两个都是汉字时比较函数static int pinyin_strcmp(const wchar_t *key1, const wchar_t *key2) {

std::wstring str1 = LetterHelp::getInstance()->ConvertLetterToPinyin(key1);

std::wstring str2 = LetterHelp::getInstance()->ConvertLetterToPinyin(key2);return wcscmp(str1.c_str(), str2.c_str());

}// 升序排序时将数字,字母排到汉字前static int pinyin_cmplmpl(int nKey1, const void *pKey1,int nKey2, const void *pKey2) {int size = min(nKey1, nKey2);int i = 0, flag = 0, ret = 0;;wchar_t s[2]={0}, d[2]={0};for (i = 0; i

flag = 0;

ret = 0;

s[0] = *((wchar_t*)pKey1+i);

d[0] = *((wchar_t*)pKey2+i);

if ((int)s[0] > HANZI_MAX || (int)s[0]

flag += 1;

} else {

flag += 2;

}

if ((int)d[0] > HANZI_MAX || (int)d[0]

flag += 4;

} else {

flag += 8;

}switch(flag) {

case  5:

ret = wcscmp(s, d);

if (ret != 0) {

return ret;

}

break;

case 9:

return -1;

case 6:

return 1;

case 10:

ret = pinyin_strcmp(s, d);

if (ret != 0) {

return ret;

}

break;

}

}if (i >= size && nKey1 == nKey2) {

return 0;

} else if (i >= size && nKey1

return -1;

} else if(i >= size && nKey1 > nKey2) {

return 1;

}return -1;

}// 升序比较函数static int pinyin_cmp_asc(

void *NotUsed,int nKey1, const void *pKey1,

int nKey2, const void *pKey2)

{return pinyin_cmplmpl(nKey1,pKey1,nKey2,pKey2);

}// 降序比较函数static int pinyin_cmp_desc(

void *NotUsed,int nKey1, const void *pKey1,

int nKey2, const void *pKey2)

{int ret = pinyin_cmplmpl(nKey1,pKey1,nKey2,pKey2);

if (ret == 0) {

return ret;

} else {

return -ret;

}

}

在打开数据库后安装汉字拼音比较函数

// 打开数据库文件并安装汉字拼音比较函数bool Db::open(const string path) {

if (db != nullptr) {

cout <

return false;

}int ret = sqlite3_open(path.c_str(), &db);

if(ret != SQLITE_OK){

cout <

return false;

}unsigned short asc[] = {'p', 'i', 'n', 'y', 'i', 'n', '_', 'a', 's', 'c', 0};

sqlite3_create_collation16(db, asc, SQLITE_UTF16, 0, pinyin_cmp_asc);

unsigned short desc[] = {'p', 'i', 'n', 'y', 'i', 'n', '_', 'd', 'e', 's', 'c', 0};

sqlite3_create_collation16(db, desc, SQLITE_UTF16, 0, pinyin_cmp_desc);return true;

}

最后如下sql进行测试

select * from person order by name collate pinyin_asc

select * from person order by name collate pinyin_desc

测试结果如下

网易云免费体验馆,0成本体验20+款云产品!

更多网易技术、产品、运营经验分享请点击。

c语言中文拼音排序,为sqlite增加汉字拼音排序功能相关推荐

  1. python汉字拼音查询_python获取一组汉字拼音首字母的方法

    本文实例讲述了python获取一组汉字拼音首字母的方法.分享给大家供大家参考.具体实现方法如下: #!/usr/bin/env python # -*- coding: utf-8 -*- def m ...

  2. Python 汉字转拼音库 pypinyin, 附:汉字拼音转换工具

    一.初衷: 一些开源软件的配置文件中识别区分的部分用英文,那么我们在批量生成配置文件的时候,可以从CMDB导入汉字(idc_name), 然后将它转换成拼音,再或者拼接上IP地址,以便更准确的识别.例 ...

  3. oracle数据库生成拼音码,Oracle中生成汉字拼音码的函数(转载)

    效果: select fgetpy('中国') FROM dual; 结果   zg CREATE OR REPLACE FUNCTION fgetpy (v_str VARCHAR2) RETURN ...

  4. php取汉字拼音首字母,php获取汉字拼音首字母的函数(真正可以使用的)

    //php获取中文字符拼音首字母 function getFirstCharter($str){ if(empty($str)){return '';} $fchar=ord($str{0}); if ...

  5. php提取汉字拼音首字母,php获取汉字拼音首字母的函数(真正可以使用的)

    //php获取中文字符拼音首字母 function getFirstCharter($str){ if(empty($str)){return '';} $fchar=ord($str{0}); if ...

  6. oracle 汉字和英文排序,关于oracle对汉字的排序

    最近项目过程中碰到对于数据进行排序按照升序排序需求.这需求貌似很简单,我没多想直接order by columnName.忽略了汉字排序的问题导致bug的出现. 业务要求,按照excel中排序出来的结 ...

  7. java获取汉字的拼音首字母_Java获取汉字拼音首字母

    根据网上C#版和JAVA版改的.代码很短,但有些复杂的汉字取不了拼音,如"鑫"等.适用一般不是很复杂的情况. 如要更完整的版本,可以使用这个开源的pinyin4j组件.packag ...

  8. mysql中的汉字怎么转换_Mysql中文汉字转拼音的实现(每个汉字转换全拼)

    一.创建拼音对照表 代码如下: -- 创建汉字拼音对照临时表 CREATE TABLE IF NOT EXISTS `t_base_pinyin` ( `pin_yin_` varchar(255) ...

  9. mysql root dengru_Mysql学习Mysql中文汉字转拼音的实现(每个汉字转换全拼)

    <Mysql学习Mysql中文汉字转拼音的实现(每个汉字转换全拼)>要点: 本文介绍了Mysql学习Mysql中文汉字转拼音的实现(每个汉字转换全拼),希望对您有用.如果有疑问,可以联系我 ...

最新文章

  1. Linux 操作系统原理 — 文件系统 — 虚拟文件系统
  2. python基础第六天
  3. Scala的集合类中的map方法和count 方法
  4. 用U盘或移动硬盘安装Windows7 (超简单制作Win7安装U盘方法)
  5. linux 线程间传送消息,Linux 多线程同步-消息队列
  6. 微博:冬奥期间累计共清理相关违规内容近31万条
  7. maya如何导出ue4_ue4 maya max导入导出问题
  8. 无人自助便利店采用射频识别技术 30秒钟就能完成付款
  9. 使用CSS控制表单样式/示例演示
  10. JSONP跨域以及CORS跨域
  11. 项目成本管理-案例分享
  12. LaTex编辑器编辑公式
  13. ICM-20602 IMU ACCEL/GYRO/TEMP I2C/SPI LGA
  14. Ubuntu进行apt-get出现Package xxx is not available,but is referred to by another package错误
  15. 检测网络是否正常(ping,Telnet,tracert以及tnsping)
  16. 单反相机坏点和噪点测试软件,坏点和噪点测试程序(照片检测工具)
  17. python图片保存_Python中读取,显示,保存图片的方法
  18. 视频格式转换器哪个好?用什么软件转换格式
  19. MySQL-count(*)、count(1)、count(主键)、count(非索引列)、count(索引列)性能分析
  20. 常见面试题整理--数据库篇(每位开发者必备

热门文章

  1. 小哥Cadence Allegro 132讲字幕版PCB设计视频教程-cadence视频-allegro视频-PCB视频
  2. Java异常,教课书式知识梳理
  3. 7款功能超牛的电脑软件,分分钟提高效率!
  4. windows store下载_年度付费软件排行榜这10款软件,你用过5款以上,就算效率达人!Windows平台...
  5. 51单片机LCD1602的使用
  6. 力天创见商场客流统计方案
  7. 技嘉 RTX 4090 已在香港发售,距正式上市两周
  8. J2V8 -- 开始使用J2V8
  9. camera调试基础经验分享
  10. Groovy~Groovy的方法