编程题
判断字符串 b 的所有字符是否都再字符串 a 中出现过,a,b都是可能包含汉字的字符串。b中重复出现的汉字,那么a中也要至少出现相同的次数。
汉字使用gbk编码(简单的所,用两个字节表示一个汉字,高字节最高位为1的代表汉字,低字节最高位可以不为1)。
int is_include(char *a , char *b)
返回0 表示没有都出现过,返回1表示都出现过。
#include <stdio.h>
#include <windows.h>
#include <string.h>
typedef struct node{
char key[2];
int count;
int tag;
}hnode;
/*--------------------------hash设计--------------------------------
/*本部分的哈希表采用二次探查闭散列算法*/
/* int hash(hnode item,int m)
* 功能: 哈希函数
* item: 字符结构体
* m: 散列质数
*/
int hash(hnode item,int m){
int ret;
char key[2];
key[0]=item.key[0];
key[1]=item.key[1];
if(item.tag==0){// 英文字符
ret=key[0]%m;
}else{ //中文字符
ret=((key[0])*key[1])%m;
if(ret<0){
ret=-ret;
}
}
return ret;
}
/* int p(hnode item,int i,int m2)
* 功能: 第i次探查函数
* item: 字符结构体
* i:第i次探查
* m2: 第二质数
*/
int p(hnode item,int i,int m2){
return i*hash(item,m2);
}
/* insert_node(hnode *item,hnode *table,int hlen,int m1,int m2)
* 功能: 将字符结构体插入一个哈希表中
* item: 需要检查的字符结构体
* table: 待检索的哈希表
* hlen: 带检索的哈希表的大小
* m1: 第一质数
* m2: 第二质数
*/
void insert_node(hnode item,hnode *table,int m1,int m2){
int index=hash(item,m1);
int i=1;
while(true){
hnode node=*(table+index);
if(node.tag==2){
item.count=1;
*(table+index)=item; //出错点!!!
break;
}else{
if(node.tag==item.tag){
if(node.key[0]==item.key[0] && node.key[1]==item.key[1] ){
(*(table+index)).count=node.count+1; //出错点!!!
break;
}
}else{
index=(index+p(item,i++,m2))%m1;
}
}
}
}
/* 功能: 为一个字符串创建哈希表
* list: 字符串
* len: 字符串的长度
* m1: 质数1
* m2: 质数2
*/
hnode* create_hash(char *list,int len,int m1,int m2){
/* 新建hashtable,长度为字符串长度的两倍 */
hnode *htable=new hnode[len*2];
for(int k=0;k<len*2;k++){
hnode node;
node.tag=2;
*(htable+k)=node;
}
/* 为list中的每个字符创建hashnode */
/* 将每个hashnode insert到 hashtable中 */
/* 返回 hashtable的指针 */
for(int i=0;i<len;i++){
hnode *node=new hnode();
if(list[i]>0){
node->key[0]=list[i];
node->key[1]='#';
node->tag=0;
}else{
node->key[0]=list[i];
node->key[1]=list[i++];
node->tag=1;
}
insert_node(*node,htable,m1,m2);
}
return htable;
}
/* 求比n小的最大质数 */
int getZhiShu(int n){
int tag=0;
int ret=-1;
for(int i=n;i>=2;i--){
for(int j=2;j<i;j++){
if(i%j==0){
tag=1;
break;
}
}
if(tag==0){
ret=i;
break;
}
tag=0;
}
return ret;
}
/*----------判断字串函数 int is_include(char *a , char *b)-----------------*/
/*
*功能: 判断字符串包含关系
*a, b: 待判断的两个字符串
*/
int is_include(char *a , char *b){
/*求得a、b的字符数目*/
int len1=strlen(a);
int len2=strlen(b);
int hashlen1=len1*2;
int hashlen2=len2*2;
//获得第一和第二质数
int m11=getZhiShu(hashlen1);
int m12=getZhiShu(m11-1);
int m21=getZhiShu(hashlen2);
int m22=getZhiShu(m21-1);
//创建两个哈希表,哈希表的大小为字符数的两倍
hnode *htable2=create_hash(b,len2,m21,m22);
hnode *htable1=create_hash(a,len1,m11,m12);
//hashb中的每个元素在 hasha中进行查找
// 如果没找到,则退出 return -1
// 如果找到了
//如果b中的个数比a中少,则查找下一个
//退出 return -1
for(int i=0;i<hashlen2;i++){
hnode node2=*(htable2+i);
if(node2.tag!=2){
int index=hash(node2,m11); //出错点!!!!!!
hnode node1=*(htable1+index);
int n=0;
while(node1.tag!=2){
if(node1.tag==node2.tag){
if(node1.key[0]==node2.key[0] &&node1.key[1]==node2.key[1]){
if(node1.count>=node2.count){
break;
}else{
return 0;
}
}
}
else{
index=(index+p(node2,n++,m12))%m11;
node1=*(htable1+index);
}
}
if(node1.tag==2){
return 0;
}
}
}
return 1;
}
void main(){
char *a="aabbcc黄老师";
char *b="abc黄宇";
int ret=is_include(a, b);
printf("result is :%d\n",ret);
}