C语言如何把汉字映射为数字?

各位大神,我现在刚大一,正在上C语言的课,老师让我们读取一个txt文件(它的每一行都是一个中文字符串),把每行的字符串,用一个整数表示(int或者long long等都可以)。这个本来不难吧,但是规定必须做到一点,一个汉字只对应一个整数,一个整数也必须只对应一个汉字!
我想的办法是把每个汉字获得其gbk2312编码,然后组合起来,比如“字”这个汉字,gbk2312编码为D7D6,十进制为215-214,那么“字”就可以用整数215214表示,这样就有了汉字和整数两者相互一一对应。但是问题又来了!txt中有的字符串非常的长,最多的有32个汉字,这样最大可能要一个32*2*3=192位长度的整数(这样的数最小是10^191),即使用unsigned long long 也存不下!
大神们有什么别的办法吗??老弟谢谢你了!!

很容易的。汉字总共才几万个。从1开始编号,最多也不会超过10万。比如:
1-好
2-人
3-中
。。。
用一个int型数组就够了。
int map[100000];
总共也才40万字节,不到400KB。追问

大佬你说的没错..但是这所有汉字和数字的编码关系没有啊!!

温馨提示:答案为网友推荐,仅供参考
第1个回答  2019-10-13
比如“字”这个汉字,gbk2312编码为D7D6,十进制为215-214,那么“字”就可以用整数215214表示,但是具体存储时,并不是存储215214这一个数字,而是连在一起存储215和214这两个数字的。
所以,最多有32个汉字时,它就用64个数字来存储这32个汉字的。
第2个回答  2019-10-13
每一行用一个整数表示?而且每个汉字和一个整数必须一一对应?把问题描述贴出来看看。追问

课件是很多页的ppt,没有直接的问题。

我说的是我想的办法:先把每个汉字对应一个整数,再把这行的n个汉字所对应的n个整数,分别视为一个字符串,然后把这n个字符串拼接起来

追答

既然是这样的话,那按照你的想法怎么会会需要那么大的一个数字来表示呢?假设“程序设计”这四个字对应的数字是“123;456;789;012”,然后你把这四个整数转成字符类型再拼接成“123456789012”不就好了,是这样没错吧?

追问

这样理论上需要一个32*2*3=192位的整数才行,大大超出了long long的最大值

大神,请问你有什么思路或者别的想法吗??我同学说用C语言实现一个类似C++的std::map也可以,但我们根本不会啊!!

追答

不用c++也可以的

而且理论上也不需要那么大的数啊!不知道你是怎么算出来了,一个汉字占2字节,也就是unsigned short类型就够了

这样吧,明天贴个代码给你参考参考!

/*
* 函 数 名: chinese_to_digit
* 函数说明: 汉字转数字,一个汉字对应一个唯一的整数
* 参数说明:
* chinese: 中文字符串(有英文字符也可以)
* 返 回 值: 与一个中文汉字唯一对应的整数 dig
*/
unsigned short chinese_to_digit(unsigned char const *chinese) {

unsigned short dig;

if ( *chinese & 0x80 ) { // 中文

dig = *chinese & 0x00ff;
dig = ( dig > 8;
*ch++ = digit & 0x00ff;
} else { // 字符串形式

*ch++ = digit & 0x00ff;
}
*ch = '\0';
return chinese;
}
/*
* 数字还原汉字,字符串形式
*/
void digits_to_chinese(unsigned char *chinese, unsigned short const *digit) {

unsigned short *dig;

dig = digit;

while ( *dig != 0x0000 ) {

if ( *dig & 0x8000 ) {

*chinese++ = ( *dig & 0xff00 ) >> 8;
*chinese = *dig & 0x00ff;
} else {

*chinese = *dig;
}
chinese++;
dig++;
}
*chinese = '\0';
}
直接调用就行

#include

int main(void) {

unsigned char *p = "欢迎学习C语言程序设计";
unsigned char *a = "你";
unsigned short ad;
unsigned char adc[3];
unsigned char chinese[100];
unsigned short dig[100];
unsigned char *ps = p;
int i;
printf("汉字转数字:\n");
printf("原始汉字: %s\n", p);
printf("数字:\n");
chineses_to_digit(dig, p);
for ( i = 0; dig[i] != 0x0000; i++ ) {

printf("%ld\n", dig[i]);
}
digits_to_chinese(chinese, dig);
printf("数字还原汉字: %s\n", chinese);
ad = chinese_to_digit(a);
printf("单个汉字的转化: %s-%ld\n", a, ad);
printf("还原: %ld-%s\n", ad, digit_to_chinese(adc, ad));

return 0;
}
给你个demo参考参考。

追问

谢谢大神!

万分感谢!!

大神,我认真看了一下,觉得还是不太行啊!比如您的“欢迎学习C语言程序设计”,“欢”对应48054,“迎”对应54189,那么“欢迎”对应什么?是4805454189吗??“欢迎”只有两个字还可以,字数如果多起来怎么办?一个字是一个5位的整数,那30个字就是150位吗??long long也存不下啊!

我这个程序的重点就是把字符串映射到整数,不能把这个150位的整数按字符串存储呀

追答

(⊙o⊙)…,我感觉你是被哪一个知识点卡住了。

如果你非要像你那么说的理解的话,那么一个大小为100的unsigned short数组就是100*16=160位长,这么说没错吧?还嫌不够多的话用int就差不多够了,320位。我觉得你的重点应该是想想你的思路在哪一步出错了。

本回答被提问者采纳
第3个回答  2019-10-13
用map就能完成离散化了追问

大神,你能具体的说一下吗,我刚学不懂啊😭

追答

话说你学的是C++吗?

追问

不是c++啊,就是c

大神我懂一点了,我这里也可以实现一个类似C++里面的std::map的数据结构

您能给提供点思路吗

追答

或者你可以把每一个汉字字符串用hash来完成离散化,hash一般不会出错

相似回答