由一道腾讯面试题引发对于关联数组的思考

本文主要通过例子来了解关联数组:


关联数组的定义:

计算机科学中,关联数组(Associative Array)(又称映射(Map)或字典(Dictionary))是一个抽象的数据结构,它包含着类似于(键,值)的有序对。一个关联数组中的有序对可以重复(如C++中的multimap)也可以不重复(如C++中的map)。

  • 向关联数组添加配对
  • 从关联数组内删除配对
  • 修改关联数组内的配对
  • 根据已知的键寻找配对[1][2]

字典问题是设计一种能够具备关联数组特性的数据结构。解决字典问题的常用方法,是利用散列表,但有些情况下,也可以直接使用有地址的数组,或二叉树,和其他结构。[1][2][3]

许多程序设计语言内置基本的数据类型,提供对关联数组的支持。而Content-addressable memory则是硬件层面上实现对关联数组的支持


http://zh.wikipedia.org/wiki/%E5%85%B3%E8%81%94%E6%95%B0%E7%BB%84

来看一个例子:

题目1

假设两个字符串中所含有的字符和个数都相同我们就叫这两个字符串匹配,
 比如:abcda和adabc,由于出现的字符个数都是相同,只是顺序不同,所以这两个字符串是匹配的。

解法:

假定字符串中都是ASCII字符。如下用一个数组来计数,前者加,后者减,全部为0则匹配。
C程序代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ERROR -1
#define OK 1

typedef int Status;

Status StringIsMatch(char s1[],char s2[])
{
	int a=strlen(s1);
	int b=strlen(s2);
	if (a==-1||b==-1||((a!=b)))
		return ERROR;
	int check[128]={0};
	int i,j,keys1,keys2;
	for (i=0;i<a;i++)
	{
		keys1=(int)s1[i];//键
		check[keys1]++;
	}
	for (j=0;j<b;j++)
	{
		keys2=(int)s2[j];//键
		check[keys2]--;
	}
	for (i=0;i<128;i++)
	{
		if (check[i]!=0)
			return ERROR;
	}
	return OK;
}

void main()
{
	int result;
	char s1[]="abcda";
	char s2[]="adabc";
	result=StringIsMatch(s1,s2);
	if (result==1)
		printf("两个字符串是匹配的!\n");
	else
		printf("两个字符串是不匹配的!\n");
	system("pause");

}

时间复杂度O(n).

该思想与哈希表、字典数据结构的设计起源类似都是借助映射,实现关键码与键值的对应。


题目2

类似的思想见我的博客:

让文本飞 linux shell脚本数据挖掘实践,统计出出现次数top3的url。


http://blog.csdn.net/jiezou007/article/details/7917321

shell脚本程序:

egrep -o "http://[a-zA-Z0-9.]+\.[a-zA-Z]{2,3}" $filename | \  
#网站出现的次数统计,用到关联数组  
awk '{ count[$0]++ }#$0代表每行,只需遍历一次  
END{ printf("%-30s%s\n","wensite","count");  
for(ind in count)  
{ printf("%-30s%d\n",ind,count[ind]); }  
}'  
define wordcount ad muliset;
for each document in documentset{
T=tokenize(document);
for each token in T{
wordcount[taken]++;
}
}
display(wordcount);
}


题目3
Hadoop实战一书中的的单词统计map/reduce伪代码的思想也是如此,感兴趣的读者自己找书看看:
单词统计伪代码如下:

define wordcount as multiset;
for each document in documentset{
    T=tokenize(document);
    for each token in T{
        wordcount[token]++;
     }
}
display(wordcount);













  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值