PTA数据结构与算法题目集(中文) 7-43字符串关键字的散列映射 (25 分)

时间:2021-09-03 14:27:18

PTA数据结构与算法题目集(中文)  7-43字符串关键字的散列映射 (25 分)

7-43 字符串关键字的散列映射 (25 分)
 

给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数(将关键字Key中的最后3个字符映射为整数,每个字符占5位;再用除留余数法将整数映射到长度为P的散列表中。例如将字符串AZDEG插入长度为1009的散列表中,我们首先将26个大写英文字母顺序映射到整数0~25;再通过移位将其映射为3;然后根据表长得到,即是该字符串的散列映射位置。

发生冲突时请用平方探测法解决。

输入格式:

输入第一行首先给出两个正整数N(≤)和P(≥的最小素数),分别为待插入的关键字总数、以及散列表的长度。第二行给出N个字符串关键字,每个长度不超过8位,其间以空格分隔。

输出格式:

在一行内输出每个字符串关键字在散列表中的位置。数字间以空格分隔,但行末尾不得有多余空格。

输入样例1:

4 11
HELLO ANNK ZOE LOLI

输出样例1:

3 10 4 0

输入样例2:

6 11
LLO ANNA NNK ZOJ INNK AAA

输出样例2:

3 0 10 9 6 1
题目分析:这是也是一道散列表的基础题
 #define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#define MAXTABLESIZE 100000 typedef enum{Legitimate,Empty,Deleted}EntryType;
typedef struct HashEntry Cell;
struct HashEntry
{
EntryType Type;
char Data[];
};
typedef struct HblNode* HashTable;
struct HblNode
{
int TableSize;
Cell* Cells;
}; int NextPrime(int N)
{
int P = (N % )?N:N + ;
for (; P < MAXTABLESIZE; P += )
{
int i = (int)sqrt(P);
for (; i > ; i--)
if (P % i == )
break;
if (i == )
break;
}
return P;
} HashTable CreateHashTable(int N)
{
int TableSize = NextPrime(N);
HashTable H = (HashTable)malloc(sizeof(struct HblNode));
H->TableSize = TableSize;
H->Cells = (Cell*)malloc(H->TableSize * sizeof(Cell));
for (int i = ; i < H->TableSize; i++)
{
H->Cells[i].Type = Empty;
H->Cells[i].Data[] = '\0';
}
return H;
} int Hash(char Data[], int TableSize)
{
int L = strlen(Data);
int sum = ;
if (L >= )
{
L--;
for (int i = L - ; i <= L; i++)
sum = sum * + Data[i] - 'A';
}
else
{
for (int i = ; i < L; i++)
sum = sum * + Data[i] - 'A';
}
return sum%TableSize;
} int Find(char Data[], HashTable H)
{
int NewPos, CurrentPos;
NewPos = CurrentPos = Hash(Data, H->TableSize);;
int CNum = ;
while (H->Cells[NewPos].Type!=Empty&&strcmp(H->Cells[NewPos].Data,Data))
{
if (++CNum % )
{
NewPos = CurrentPos + ((CNum + ) / )*((CNum + ) / );
while (NewPos >= H->TableSize)
NewPos -= H->TableSize;
}
else
{
NewPos = CurrentPos - (CNum / ) * (CNum / );
while (NewPos < )
NewPos += H->TableSize;
}
}
return NewPos;
} void Insert(char Data[], HashTable H)
{
int Pos = Find(Data, H);
if (H->Cells[Pos].Type != Legitimate)
{
H->Cells[Pos].Type = Legitimate;
strcpy(H->Cells[Pos].Data, Data);
}
} int main()
{
int N, P;
scanf("%d%d", &N, &P);
HashTable H = CreateHashTable(P);
char Data[] = { };
for (int i = ; i < N - ; i++)
{
scanf("%s", Data);
Insert(Data, H);
printf("%d ", Find(Data, H));
}
scanf("%s", Data);
Insert(Data, H);
printf("%d", Find(Data, H));
return ;
}