免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3557 | 回复: 6
打印 上一主题 下一主题

关于数组中的不规则映问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-01-22 14:46 |只看该作者 |倒序浏览
我有一个数组{4, 5, 10, 2 ... },这些值事先知道,用什么方法映射到{0, 1, 2, 3 ... }这样子有规律的数组。

例如程序中变量 Val = 5; 我可不可以通过什么映射关系(不使用循环)得到对应的值1.

高人指教一下,谢谢了先。

论坛徽章:
0
2 [报告]
发表于 2007-01-22 15:10 |只看该作者
如果映射规则简单,定义在数组中试试

论坛徽章:
0
3 [报告]
发表于 2007-01-22 15:43 |只看该作者
原帖由 libin1983 于 2007-1-22 15:10 发表
如果映射规则简单,定义在数组中试试


假设数据为{4, 5, 10, 2},那数组应该如何定义啊?10个元素还是4个元素。谢谢了

论坛徽章:
0
4 [报告]
发表于 2007-01-22 16:30 |只看该作者
可以考虑用哈希。

论坛徽章:
0
5 [报告]
发表于 2007-01-22 17:05 |只看该作者
原帖由 emacsnw 于 2007-1-22 16:30 发表
可以考虑用哈希。

能给个具体的解决方法么?很想了解到散列在实际中的应用

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2007-01-22 19:19 |只看该作者
原帖由 InfoHunter 于 2007-1-22 17:05 发表

能给个具体的解决方法么?很想了解到散列在实际中的应用

楼主的问题不懂。
不过可以给你一段摘自《编译原理及实践》中的话,
可以看到hash的应用。
T I N Y对保留字的识别是通过首先将它们看作是标识符,之后再在保留字表中查找它们来
完成的。这在扫描程序中很平常,但它却意味着扫描程序的效率须依赖于在保留字表中查找过
程的效率。我们的扫描程序使用了一种非常简便的方法—线性搜索,即按顺序从开头到结尾
搜索表格。这对于小型表格不成问题,例如T I N Y中的表格,它只有8个保留字,但对于真实语
言而言,这却是不可接受的,因为它通常有3 0 ~ 6 0个保留字。这时就需要一个更快的查找,而
这又要求使用更好的数据结构而不是线性列表。假若保留字列表是按字母表的顺序写出的,那
么就可以使用二分搜索。另一种选择是使用杂凑表,此时我们希望利用一个冲突性很小的杂凑
函数。由于保留字不会改变(至少不会很快地),所以可事先开发出这样一个杂凑函数,它们
在表格中的位置对于编译器的每一步运行而言都是固定的。人们已经确定了各种语言的最小完
善杂凑函数(minimal perfect hash function),也就是说能够区分出保留字且具有最小数值的函
数,因此杂凑表可以不大于保留字的数目。例如,如果只有8个保留字,则最小完善杂凑函数
总会生成一个0 ~ 7的值,且每个保留字也会生成不同的值(参见“注意与参考”一节)

论坛徽章:
0
7 [报告]
发表于 2007-01-22 22:39 |只看该作者
原帖由 小丌 于 2007-1-22 14:46 发表
我有一个数组{4, 5, 10, 2 ... },这些值事先知道,用什么方法映射到{0, 1, 2, 3 ... }这样子有规律的数组。

例如程序中变量 Val = 5; 我可不可以通过什么映射关系(不使用循环)得到对应的值1.

高人指教 ...

我不是高人,共同学习

第一种情况,映射可以用数学表达式描述(线性的):
将数学表达式用程序实现,

第一种情况,映射不能用数学表达式描述:
比如第一个数组是A[10] = {4, 5, 10, 2, 53, 8, 9, 3, 18, 14}, 要映射到的数组是B {0, 1, 2, 7}

映射关系(记为f):
A       4       5       10      2       53      8       9       3       18      14      
B       7       2        1      0        2      7       1       2        0       7   
即, 4 映射到7, 5映射到2, 10映射到1, ...
这个映射关系很简单,并且数组元素较少(最重要的一点 )
可以一个二维数组将以设关系放进去,做成一个表
如,int c[10][2];
c[0][0] = 4, c[1][0] = 7;
c[0][1] = 5, c[1][1] = 2;
...
用的时候直接查表。
如,查5的对应值:
for (int index = 0; index < 10; i++ ){
    if (c[0][index] == 5){
          return c[1][index]; //ans: 2
    }
}


也可以用一维数组,int c2[10];
4对应7,4在A中的索引值为0,  则 c2[0] = 4;
5对应2,5在A中的索引值为1, 2在B中的索引值为2, 则 c2[1] = 2;
...
查5的对应值:
for (int index =0; index < 10; i++){
    if (a[index] == 5){
        return c2[index]; //ans: 2
    }
}



速度快点的版本:(以空间换时间)
取数组A中的最大值53,建数组:
int c3[53+1];
4对应7,c3[4] = 7;
5对应2,c3[5] = 2;
10对应1,c3[10] = 1;
...
查5对应值:
return c3[5]; //快吧


如果A中的最大值为2000,并且A中的元素很少,用楼上的哈希函数吧


(见笑了 )


==========================================
一个Hash函数链接: http://www.ccw.com.cn/htm/app/aprog/01_8_22_3.asp

[ 本帖最后由 libin1983 于 2007-1-22 22:47 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP