关于汉字在计算机中的表示,在计算机组成原理中有详细的表述,对于在编程的时候遇见的处理汉字的需求。
一下内容摘自互联网(向老前辈致敬)
汉字区位码
1.简介
所谓汉字编码,就是采用一种科学可行的办法,为每个汉字编一个唯一的代码,以便计算机辨认、接收和处理。在此介绍的是《国家标准信息交换汉字编码》。这种编码经过加工整理一律以汉语拼音的字母为序,音节相同的字以使用频率为序,其查找方法与一般汉语字典的汉字拼音音节索引查找法相同。
2.国家标准
为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准: GB2312-80《信息交换用汉字编码字符集》基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个”区”,每一列称为一个”位”,因此,这个方阵实际上组成了一个有94个区(区号分别为0 1到94)、每个区内有94个位(位号分别为01到94)的汉字字符集。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的”区位码”。在汉字的区位码中,高两位为区号,低两位为位号。 在区位码中,01-09区为682个特殊字符,16~87区为汉字区,包含6763个汉字 。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列),56-87区为二级汉字(3008个汉字,按部首次序排列)。
所以,当我们需要n个任意汉字时,我们不必建一个全部汉字表,而是利用区位码实现常用汉字的提取。
汉字提取拼音首字母
http://hi.baidu.com/suofang/item/019347031809a313cc34eaf2(感谢作者)
基础知识
GB 2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个。
分区表示
GB 2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。
1)01-09区为特殊符号。
2)16-55区为一级汉字,按拼音排序。
3)56-87区为二级汉字,按部首/笔画排序。
4)10-15区及88-94区则未有编码。
举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601。
字节结构
在使用GB2312的程序中,通常采用EUC储存方法,以便兼容于ASCII。浏览器编码表上的“GB2312”,通常都是指“EUC-CN”表示法。
每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”(也称“区字节)”,第二个字节称为“低位字节”(也称“位字节”)。
“高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上 0xA0)。由于一级汉字从16区起始,汉字区的“高位字节”的范围是0xB0-0xF7,“低位字节”的范围是0xA1-0xFE,占用的码位是 72*94=6768。其中有5个空位是D7FA-D7FE。
例如“啊”字在大多数程序中,会以两个字节,0xB0(第一个字节) 0xA1(第二个字节)储存。区位码=区字节+位字节(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。
GB2312编码表
16 0 1 2 3 4 5 6 7 8 9
0 啊 阿 埃 挨 哎 唉 哀 皑 癌
1 蔼 矮 艾 碍 爱 隘 鞍 氨 安 俺
2 按 暗 岸 胺 案 肮 昂 盎 凹 敖
3 熬 翱 袄 傲 奥 懊 澳 芭 捌 扒
4 叭 吧 笆 八 疤 巴 拔 跋 靶 把
5 耙 坝 霸 罢 爸 白 柏 百 摆 佰
6 败 拜 稗 斑 班 搬 扳 般 颁 板
7 版 扮 拌 伴 瓣 半 办 绊 邦 帮
8 梆 榜 膀 绑 棒 磅 蚌 镑 傍 谤
9 苞 胞 包 褒 剥
17 0 1 2 3 4 5 6 7 8 9
0 薄 雹 保 堡 饱 宝 抱 报 暴
1 豹 鲍 爆 杯 碑 悲 卑 北 辈 背
2 贝 钡 倍 狈 备 惫 焙 被 奔 苯
3 本 笨 崩 绷 甭 泵 蹦 迸 逼 鼻
4 比 鄙 笔 彼 碧 蓖 蔽 毕 毙 毖
5 币 庇 痹 闭 敝 弊 必 辟 壁 臂
6 避 陛 鞭 边 编 贬 扁 便 变 卞
7 辨 辩 辫 遍 标 彪 膘 表 鳖 憋
8 别 瘪 彬 斌 濒 滨 宾 摈 兵 冰
9 柄 丙 秉 饼 炳
18 0 1 2 3 4 5 6 7 8 9
0 病 并 玻 菠 播 拨 钵 波 博
1 勃 搏 铂 箔 伯 帛 舶 脖 膊 渤
2 泊 驳 捕 卜 哺 补 埠 不 布 步
3 簿 部 怖 擦 猜 裁 材 才 财 睬
4 踩 采 彩 菜 蔡 餐 参 蚕 残 惭
5 惨 灿 苍 舱 仓 沧 藏 操 糙 槽
6 曹 草 厕 策 侧 册 测 层 蹭 插
7 叉 茬 茶 查 碴 搽 察 岔 差 诧
8 拆 柴 豺 搀 掺 蝉 馋 谗 缠 铲
9 产 阐 颤 昌 猖
根据上面的表述,我们可以把16-55区的一级汉字,取拼音首之母了。
首先找出不同拼音首之母,且在码表中位置最靠前的汉字,计算出它们的编码值。
(GB2312完整码表http://210.44.195.12/yyx/chinese/News/UploadFile/GB2312.htm)
其他汉字在相同编码下,只需计算出其所在的区间位置。
判断是否为英文之母
如果是,直接返回英文之母
取字符的编码值
比较判断其编码值在码表中的位置。
根据位置值,返回之母表中相应值。
—————–两个汉字的例子—————————
DA A0
11011010
10100000
00111010
0x3a
‘讴’ 位于区位码 :58区第一个字
B0 A0啊
10110000
10100000
00010000
0x10=16
1601
/**
* 汉字转换为拼音字头的工具类
*文件名:ChineseTools.java
*版本:
*描述:
*文件描述:
*修改者:
*修改日期:
*修改描述:
*/
public class ChineseTools {
/**
* 存放国标一级汉字不同读音的起始区位码
*/
static final int[] secPosValueList = {
1601, 1637, 1833, 2078, 2274, 2302, 2433, 2594, 2787, 3106, 3212, 3472,
3635, 3722, 3730, 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249, 9999};
/**
* 存放国标一级汉字不同读音的起始区位码对应读音
*/
static final char[] firstLetter = {
‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’, ‘g’, ‘h’, ‘j’, ‘k’, ‘l’, ‘m’, ‘n’, ‘o’, ‘p’,
‘q’, ‘r’, ‘s’, ‘t’, ‘w’, ‘x’, ‘y’, ‘z’};
/**
* 获取一个字符串的拼音码
* @param oriStr
* @return
*/
public static String getFirstLetter(String oriStr) {
return getFirstLetter(oriStr,0);
}
/**
* 获取一个字符串的拼音码
* @param oriStr
* @param scale 返回的拼音字头的位数
* @return
*/
public static String getFirstLetter(String oriStr,int scale) {
String str = oriStr.toLowerCase();
StringBuffer buffer = new StringBuffer();
char ch;
char[] temp;
for (int i = 0; i < str.length(); i++) {
//依次处理str中每个字符
ch = str.charAt(i);
temp = new char[] {
ch};
byte[] uniCode = new String(temp).getBytes();
if (uniCode[0] < 128 && uniCode[0] > 0) {
// 非汉字
buffer.append(temp);
}
else {
buffer.append(convert(uniCode));
}
}
if(buffer.toString().length()