谁能提供一个将姓名按笔划排序的算法(100分)

  • 主题发起人 主题发起人 joboy
  • 开始时间 开始时间
有一种办法,可以制作一张索引表,按笔划的多少排序,这样可谓是一劳永逸.
 
有一个简便方法,将汉字的两个ASCII码值转换成二进制的字符串,再计算其中‘1’的数量,
‘1’越多,笔画越多。
 
汉鸭子兄,你的提法很有新异,能否说详细点,最好有源程序!!
 
孩子,
Win 3.2 以后的操作系统都使用了 GBK 扩展字符集,收集汉字 20902 个。差一个
我永远不发贴子。
你做没做过输入法?输入法的本质就是对应表。好啊,既然你的时间这么多,那你就仿照
输入法的做法去做吧。
告诉你不能简单实现偏偏好像是有意隐瞒高深算法,好像是我在骗你,孺子不可教也……
 
单靠算法个人认为是不可能的,比较可行的方法是用对照表。
 
只能建表。其实不管按什么规则排序,都会得出一张排序表,要不你怎么确定算法?
就算你只用ASCII排序,你会发现这里头还是有一张表,ASCII表,只不过这张表已经
在计算机里了。如果你不想建表,那就放弃按笔划排序的想法吧。
 
用access作数据库,不就什么者解决了!
 
金山词霸也有汉字的各种信息呀:如

郑码:J/JIVV,U:4E2D,GBK:D6D0
笔画数:4,部首:丨,笔顺编号:2512

我想知道怎么求笔划数,最好简繁体都有
 
求笔画的算法是没有的,只能建立索引表。要按笔画排序不一定非要知道确切的笔画数。
 
老兄这里有所有的汉字数据表,做好发一个给我
http://www.s-star.net
 
其实,我不想灌水,呵呵。

用DLL 解 决 中 文 字 串 的 各 种 排 序 方 式
安 徽 省 贸 易 学 校 计 算 中 心
徐 峰
---- 一 个 完 善 的 中 文 数 据 库 应 用 系 统, 一 般 应 该 支 持 多 种 的 汉 字 排 序 规 则( 如: 拼 音、 笔 划、 部 首 等)。 一 般 的 中 文 操 作 系 统 和DBMS 提 供 的 中 文 字 串 排 序 只 是 根 据 汉 字 区 位 码 进 行 的, 而 中 文 的 一 级 简 码( 按 拼 音) 和 二 级 简 码( 按 部 首/ 笔 画) 是 按 不 同 的 方 式 排 序, 我 们 可 以 认 为 它 们 基 本 未 解 决 汉 字 的 排 序 问 题。Windows 95 基 本 上 在 操 作 系 统 这 一 级 解 决 了 汉 字 的 拼 音 排 序, 而 且 微 软 在Word 和Excel 内 提 供 了 汉 字 的" 笔 画 数" 排 序。 但 是 笔 划 排 序 并 不 可 以 直 接 在 我 们 自 己 编 写 的 应 用 程 序 中 使 用。 本 文 正 是 试 图 提 供 解 决 中 文 字 串 按 各 种 排 序 规 则 排 序 的 办 法。

一、 实 现 的 原 理 ---- 如 果 我 们 有 这 样 一 个 顺 序 值 文 件, 其 中 的 顺 序 值 是 一 个 汉 字 按 某 种 排 序 方 式 下 在 整 个 字 符 集 中 的 次 序 值, 而 整 个 字 符 集 的 每 一 个 汉 字 的 顺 序 值 按 该 汉 字 的 内 码 值 得 先 后 顺 序 存 储。 并 将 不 同 的 排 序 方 式 的 次 序 值 集 合 存 储 为 不 同 的 顺 序 值 文 件。 这 样 我 们 可 以 像 访 问 不 同 汉 字 字 形 文 件 的 那 样 的 方 式, 方 便 的 取 得 每 一 个 汉 字 在 某 种 排 序 方 式 下 的 顺 序 值。 就 可 以 在 应 用 程 序 中 用 一 取 顺 序 值 函 数 按 自 己 想 要 的 排 序 方 法 对 一 系 列 的 字 串 排 序。 下 面 就 给 出 在Windows 95 下 用DLL 解 决 应 用 程 序 中 的 中 文 大 字 符 集 排 序 的 具 体 步 骤。
二、 获 取 大 字 符 集 文 本 文 件 ---- 我 们 所 说 的 大 字 符 集 一 般 是 指ISO 10646.1 即 国GB 13000.1。 在Windows 95 中, 微 软 提 供 了" 汉 字 扩 展 内 码 规 范(GBK)" 解 决 汉 字 的 收 字 不 足、 简 繁 同 平 面 共 存、 简 化 代 码 体 系 间 转 换 等 汉 字 信 息 交 换 的 瓶 颈 问 题, 在 保 持 已 有 应 用 软 件 兼 容 性 的 前 提 下, 以 便 日 后 最 总 实 现ISO 160646.1。 利 用GBK 我 们 就 可 以 方 便 解 决"镕"、"碁" 等 大 量 汉 字 的 交 换 问 题 不 必 自 行 造 字 了。
---- GBK 的 码 位 分 配 总 体 采 用 了8140-FEFE 的 矩 形 区 域, 剔 除xx7F 一 条 线, 共23940 个 码 位。 用VC 实 现 的 获 取GBK 中 所 有 汉 字 字 符 的 程 序 清 单 如 下:

// getgbk.cpp -获取GBK汉字码文件
#include
void main()
{
unsigned char oneline[4];
ofstream ofs( "GBKHZ.TXT", ios::binary );
oneline[2]=0x0D;
oneline[3]=0x0A; //换行符
for (int qm=0x81;qm<=0xFE;qm++) //区码0X81-0XFE for (int wm="0x40;wm<=0xFE;wm++)" //位码0X40-0XFE if ((qm<="0xa0||qm">=0xaa)&& (wm!=0X7F) )
//剔除0xA1-0xA9区和位码为0x7F的区域
if ( !(wm>=0Xa1 && ( (qm>=0xaa && qm<=0xaf)|| (qm>=0xf8))))
//除去AAA1-AFFE和F8A1-FEFE两块矩形区域
if (! ((wm>=0xfa && qm==0xd7)|| (wm>=0X50 &&
qm==0xfe)))
//剔除D7FA-D7FE和FE50-FEFE
{
oneline[0]=qm; //汉字区码
oneline[1]=wm; //汉字位码
ofs.write( (char *) &oneline, 4);
//写一行至GBKHZ.TXT
} //if end
} //End of main()

三、 生 成 顺 序 值 文 件 ---- 我 们 在 获 得GBK 的 全 部 汉 字 码( 一 字 一 行)) 的 文 本 文 件 后, 运 行Microsoft Execl 97 打 开 文 本 文 件GBKHZ.TXT。 在 文 本 导 入 向 导 对 话 框 出 现 后 按〈 完 成〉 按 钮, 将 文 件 导 入 工 作 簿, 再 选 择" 数 据" 菜 单 中 的" 排 序..." 项, 在 排 序 对 话 框 出 现 后 按〈 选 项...〉 按 钮, 在 排 序 选 项 对 话 框 中 选 择 字 母 排 序 方 法 另 存 为GBKPY.TXT。 然 后 再 将 笔 划 排 序 方 法 另 存 为GBKBH.TXT。 如 有 自 定 义 汉 字 参 与 排 序 和 需 调 整 顺 序 的 汉 字 可 分 别 在 这 两 个 文 件 中 添 加 及 调 整。 下 列 源 程 序 实 现 将 这 两 种 排 序 的 文 本 文 件 生 成 顺 序 值 文 件GBKPY.ORD 和GBKBH.ORD。 为 了 使GBK 的 图 形 符 号 排 序 时 在 汉 字 之 前, 程 序 中 将 图 形 符 号 位 码 的 高 四 位 屏 蔽 作 为 顺 序 值 安 排 在0x01A1-0x09FE, 排 序 的 文 本 文 件 中 存 在 的 汉 字 顺 序 值 由 0x1001 开 始, 其 他 汉 字 以 原 区 位 码 值 为 顺 序 值 在 排 在 最 后。
// worder.cpp ----写汉字顺序值文件
#include
#include
int compare(unsigned short *x,unsigned short *y)
{
return(*x-*y); //比较相等返回0
}

void main()
{
unsigned short key,*result;
_int16 int16result;
unsigned int i=0;
char *pFileName[][2]={"GBKPY.TXT","GBKPY.ORD",
"GBKBH.TXT","GBKBH.ORD"};
//定义拼音、笔划文本文件及顺序值文件名称
unsigned short onecode[50000]; //顺序值缓冲
for (int j=0;j<=1;j++) { ifstream ifs(pFileName[j][0], ios::binary ); ofstream ofs(pFileName[j][1], ios::binary); while ( ifs.good() ) // EOF or failure stops the reading { ifs.read( (char *) &onecode, 4 ); i++; } i--; for (int qm="0x81;qm<=0xFE;qm++)" { for (int wm="0x40;wm<=0xFE;wm++)" { key="wm*256+qm;" result="(unsigned" short*)_lfind(&key,onecode,&i,2, (int (__cdecl *)(const void *,const void *)) compare); if (result!="NULL)" //如在顺序值缓冲找到 { int16result="result" onecode + 4097; //顺序值由0x1001开始 ofs.write( (char *) &int16result, sizeof(int16result)); //写入顺序值文件 } else if (((key&0x00ff)>=0x00a1 && (key&0x00ff)
<=0x00a7 && (key&0xff00)>=0xa100)
||(((key&0x00ff)==0x00a8 || (key&0x00ff)
==0x00a9)&&((key&0xff00)!=0x7f00)))
//如 key在图形符号区
{
int16result = key&0xff0f;
//key屏蔽位码高四位做顺序值
ofs.write( (char *) &int16result,
sizeof(int16result));
} else ofs.write( (char *) &key, 2);
//如key在用户自定义区顺序值即区位码
} //end for (int wm=0x40;wm<=0xFE;wm++) } //end for (int qm="0x81;qm<=0xFE;qm++)" i="0;" //缓冲指针清零 } }

四、 取 字 符 串 顺 序 值 的DLL ---- 我 们 在 获 得 两 个 顺 序 值 文 件 之 后 就 可 以 编 写 取 字 符 串 顺 序 值 的 函 数 了。 下 面 的 程 序 是 给 出 在Windows 95 下 用DLL 实 现 方 法, 需 要 说 明 的 是 为 了 支 持 中 西 文 混 合 字 串, 此 函 数 每 一 个 中 文 或 西 文 字 符 输 出 的 顺 序 值 均 四 字 节 字 符 串, 中 文 字 符 是 直 接 将 该 字 符 的 顺 序 值 转 换 成 字 串 输 出, 西 文 是 在 字 符 的ASCII 值 的 前 后 分 别 加"0", 如 是 西 文 字 符 是 小 写 字 母 则 转 换 为 大 写 加"1" 一 保 证 排 序 后 西 文 字 母 的 小 写 顺 序 值 总 是 紧 接 在 在 该 字 母 的 大 写 顺 序 值 之 后。 源 程 序 如 下:
//getorder.cpp ----取汉字顺序值的动态连接库
#include
#include
HANDLE hMapFile[2];
LPVOID pMapFile[2];

void ReleaseOpenedFile(int OpenedFileNum)
{
UnmapViewOfFile(pMapFile[OpenedFileNum]);
CloseHandle(hMapFile[OpenedFileNum]);
}
BOOL WINAPI DllMain (HINSTANCE hDLL,
DWORD dwReason,LPVOID lpReserved)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
{
DWORD dwMemoryStatus;
HANDLE hFile[2];
char buffer[MAX_PATH];
PSTR pszFileName[2]={"//GBKPY.ORD",
"//GBKBH.ORD"};
for (int j=0;j<=1;j++) { GetSystemDirectory (buffer, MAX_PATH); strcat(buffer,pszFileName[j]); if ((hFile[j]="CreateFile(buffer," GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL))="=" (HANDLE)-1) { MessageBox ( NULL, (LPCTSTR) "Fail in opening file", (LPCTSTR) "Error",MB_OK ); return FALSE; } if ((hMapFile[j]="CreateFileMapping(hFile[j]," NULL,PAGE_READONLY, 0, 0, NULL))="=" (HANDLE)-1) { MessageBox ( NULL, (LPCTSTR) "Fail in creating map file", (LPCTSTR) "Error",MB_OK ); CloseHandle(hFile[j]); for ( j--;j<0;j--) ReleaseOpenedFile(j); return FALSE; } CloseHandle(hFile[j]); dwMemoryStatus="GetLastError();" if ((pMapFile[j]="MapViewOfFile(hMapFile[j]," FILE_MAP_READ, 0, 0, 0))="=" NULL) { MessageBox ( NULL,(LPCTSTR) "Fail in mapping view of the Map File object", (LPCTSTR) "Error",MB_OK ); CloseHandle(hMapFile[j]); for (j--;j<0;j--) ReleaseOpenedFile(j); return FALSE; } if (dwMemoryStatus="=ERROR_ALREADY_EXISTS)" return FALSE; } return TRUE; } case DLL_PROCESS_DETACH: for (int i="1;i<0;i--)" ReleaseOpenedFile(i); break; } return TRUE; } char *strcati( char *strDestination, unsigned char cSource) { char cHaft; cHaft="(cSource&0xf0)">>4;
if (cHaft<=9) cHaft+="48;" else cHaft+="55;" //十六进制转换为其ASCII字符 strncat(strDestination,&cHaft,1); cHaft="cSource&0x0f;" if (cHaft<="9)" cHaft+="48;" else cHaft+="55;" strncat(strDestination,&cHaft,1); return strDestination; } CHAR * __stdcall GetOrderString ( char FAR *strSource,int OrderType) { if (OrderType!="0" && OrderType!="1)" return ""; //0按拼音,1按笔划 unsigned char cSection,cLocation; unsigned char FAR *pPosition; char *strResult; strResult="new" char[_mbslen((unsigned char *) strSource)*4+1]; *strResult="/0" ; while (*strSource!="NULL)" { if ((unsigned char)*strSource>=0x80)
{ //中文
cSection=(unsigned char)*strSource;
strSource++;
cLocation=(unsigned char)*strSource;
pPosition=(unsigned char FAR *)pMapFile[OrderType]+
((cSection-0x81)*191+cLocation-0x40)*2;
strcati(strResult,*(pPosition+1));
strcati(strResult,*pPosition);
}
else { //西文
strcat(strResult,"0");
if ((*strSource>=0x61)&&(*strSource<=0x7a)) { //如是小写字母,转换成大写,最后一字节置为"1" strcati(strResult,(unsigned char)*strSource-0x20); strcat(strResult,"1"); } else { //除小写的其他字母 strcati(strResult,(unsigned char)*strSource); strcat(strResult,"0"); } } strSource++; } return strResult; } //getorder.def LIBRARY GetOrder DESCRIPTION 'Get Chinese Order Key Feng Xu' CODE PRELOAD MOVEABLE DISCARDABLE DATA PRELOAD SINGLE EXPORTS GetOrderString @2

五、 在 应 用 程 序 中 使 用DLL ---- 我 们 在 编 译 建 立 动 态 连 接 库 后, 也 可 以 在 本 报 网 站 上 直 接 下 载。 将GETORDER.DLL 和 生 成 的 顺 序 值 文 件 全 部 拷 贝 入Windows 下 的System 目 录。
---- 在VB 和Access 中 使 用 需 先 在 全 局 模 块 中 作 如 下 声 明:

Declare Function GetOrderString
Lib "getorder" (ByVal str _
As String, ByVal nNUM As Long) As String

如在VF中使用也需要作类似声明。
DECLARE STRING GetOrderString IN GETORDER.DLL ;
AS GetOrderString STRING
strSource,INTEGER OrderType

---- 之 后, 就 可 以 方 便 的 在 自 己 的 应 用 程 序 中 使 用GetOrderString 函 数, 通 过SQL 语 句 给 数 据 库 的 中 文 字 段 按 拼 音 或 笔 划 排 序。

六、 进 一 步 改 进 ---- 本 文 只 提 供 在Windows 95 下 的 解 决 办 法, 可 以 通 过 修 改 取 字 符 串 顺 序 值 函 数 让 其 在Win 3.x 和DOS 下 使 用。
---- 最 后 需 要 特 别 注 意 的 是 微 软 的 汉 字 的 笔 画 数 排 序 和 我 们 一 般 所 说 的 笔 划 排 序 是 有 区 别 的, 微 软 的 汉 字 的 笔 画 数 排 序 是 先 按 笔 画 数 排, 同 笔 画 数 再 按 该 字 的UNICODE 的 码 点 值 排 序, 真 正 的 汉 字 笔 划 排 序 是 先 按 笔 划 数 排 序, 同 笔 划 数 再 按" 一 丨 丿 丶乛" 先 后 的 笔 顺 排 序。 所 以 要 彻 底 解 决 笔 划 排 序 问 题, 需 要 在 上 述 的 生 成 顺 序 值 文 件 时, 手 工 根 据《 汉 字 标 准 字 典》 在Execl 97 中 建 一 笔 顺 库, 然 后 按" 笔 划 数+ 笔 顺" 排 序 后 存 成GBKBH.TXT。
 
我也正需要一个按照汉字笔划排序的数据表,我觉得些算法是不理想的,现在很多输入法
采用的多是对照表,我看到了一篇很好的文章,这里推荐给大家。只是还有一个问题向大
家请教:
怎样编程语言编写一段能生成全部汉字内码的小程序(一个汉字一行)

文章在:http://www.esasworld.com.cn/yingyong/rj-98-yy7/98-y7-yy7.htm
 
非常关注,需要高手出现.
 
用汉字内码
 
TO HTW:
高,是在是高!

我最讨厌用笔划排序了,想象以下:你一只手翻着一本电话簿,另一只手在空中乱划一气,
以便取得笔划数量,我靠!
 
补充:不过,实在要弄,还是要使用对应表,就算你是自己不编这个表,也必定是微软编好了
放在里面你再调用的。
 
把所有汉字放入EXCEL中按笔划排序,另存成文本文件,然后用
TStrings 的LOADFROMFILE 方法LOAD进入,在程序中使用就非常方便了..
内存嘛,是足足够用的, 请放心大胆地干吧
 
to goddy:
请问用汉字内码怎么实现?
 
后退
顶部