进阶实验5-3.3 基于词频的文件相似度 (30分)-哈希

解题思路:

1、存储:用一张哈希表存储单词以及对应所在的文件,再用一张文件表,存储每个文件的词汇量以及单词在哈希表中的位置

2、查询:先在文件表中查询对应的文件名,(取文件词汇量较少的文件名)-> 找到对应文件名中的词汇所在位置-> 根据此单词的位置到哈希表中查找单词所在文件列表->从而判断该单词是否是两文件的公共词汇

重复步骤2,直至文件中的单词全部查询完毕

#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>

#define MAXSIZE 500009
#define MAXS 10
#define MINS 3
#define MAXB 5

typedef char Element[MAXS+1];
typedef struct FileEntry *FList;
struct FileEntry{
    short FileNo;
    FList Next;
};
typedef struct WordEntry *WList;
struct WordEntry{
    int words;
    WList Next;
};

struct HashEntry{
    short FileNo;
    Element Word;
    FList InvIndex;
};
typedef struct HashTbl *HashTable;
struct HashTbl{
    int TableSize;
    struct HashEntry *TheCells;
};

HashTable InitialHashTable(int size);//哈希表初始化
WList CreateWordList(int size);//文件单词表初始化
int Hash(Element Key,int P);//哈希函数
int Find(HashTable H,Element Key);//获取存储位置
int FindAndInsert(HashTable H,Element Key,int FileNo);//插入哈希表(前插法)
void FileInsert(WList File,int Pos,int FileNo);//插入文凭单词表(前插法)
int GetWord(Element Word);//获取单词
double CalSim(HashTable H,WList File,int F1,int F2);//计算公共词汇量占两文件总词汇量的百分比

int main()
{
    int i,N,M,F1,F2;
    HashTable H;
    WList File;
    Element Word;

    scanf("%d",&N);
    H=InitialHashTable(MAXSIZE);
    File=CreateWordList(N+1);

    for(i=1;i<=N;i++)
    {
        while(GetWord(Word))
        FileInsert(File,FindAndInsert(H,Word,i),i);
    }

    scanf("%d",&M);
    for(i=0;i<M;i++)
    {
        scanf("%d%d",&F1,&F2);
        printf("%.1lf%%\n",CalSim(H,File,F1,F2));
    }
}

HashTable InitialHashTable(int size)
{
    HashTable H=malloc(sizeof(struct HashTbl));
    H->TheCells=malloc(sizeof(struct HashEntry)*size);
    H->TableSize=size;
    while(size)
    {
        H->TheCells[--size].InvIndex=NULL;
        H->TheCells[size].FileNo=0;
    }
    return H;
}

WList CreateWordList(int size)
{
    WList F=malloc(sizeof(struct WordEntry)*size);
    while(size)
    {
        F[--size].words=0;
        F[size].Next=NULL;
    }
    return F;
}

int Hash(Element Key,int P)
{
    unsigned int h=0;
    while(*Key!=‘\0‘)
    {
        h=(h<<MAXB)+(*Key++-‘a‘);
    }
    return h%P;
}

int Find(HashTable H,Element Key)
{
    int Pos=Hash(Key,H->TableSize);
    while(H->TheCells[Pos].FileNo&&strcmp(H->TheCells[Pos].Word,Key))
    {
        Pos++;
        if(Pos==H->TableSize)
        Pos-=H->TableSize;
    }
    return Pos;
}
int FindAndInsert(HashTable H,Element Key,int FileNo)
{
    int Pos=Find(H,Key);
    if(H->TheCells[Pos].FileNo!=FileNo)
    {
        if(!H->TheCells[Pos].FileNo)
        strcpy(H->TheCells[Pos].Word,Key);
        H->TheCells[Pos].FileNo=FileNo;

        FList node=malloc(sizeof(struct FileEntry));
        node->FileNo=FileNo;
        node->Next=H->TheCells[Pos].InvIndex;
        H->TheCells[Pos].InvIndex=node;
        return Pos;
    }
    return -1;
}
void FileInsert(WList File,int Pos,int FileNo)
{
    if(Pos<0)return;
    WList W=malloc(sizeof(struct WordEntry));
    W->words=Pos;
    W->Next=File[FileNo].Next;
    File[FileNo].Next=W;
    File[FileNo].words++;
}

int GetWord(Element Word)
{
    char c;
    int p=0;
    scanf("%c",&c);
    while(!isalpha(c)&&(c!=‘#‘))scanf("%c",&c);
    if(c==‘#‘)return 0;
    while(isalpha(c)&&(p<MAXS))
    {
        Word[p++]=tolower(c);
        scanf("%c",&c);
    }
    while(isalpha(c))scanf("%c",&c);
    if(p<MINS)return GetWord(Word);
    else
    {
        Word[p]=‘\0‘;
        return 1;
    }
}

double CalSim(HashTable H,WList File,int F1,int F2)
{
    int i;
    if(File[F1].words>File[F2].words)
    {
        i=F1;F1=F2;F2=i;
    }
    WList W=File[F1].Next;
    i=0;
    while(W)
    {
        FList F=H->TheCells[W->words].InvIndex;
        while(F)
        {
            if(F->FileNo==F2)
            break;
            F=F->Next;
        }
        if(F) i++;
        W=W->Next;
    }
    return ((double)(i*100)/(double)(File[F1].words+File[F2].words-i));
}

原文地址:https://www.cnblogs.com/snzhong/p/12662503.html

时间: 2024-10-18 00:10:15

进阶实验5-3.3 基于词频的文件相似度 (30分)-哈希的相关文章

进阶实验6-3.2 社交网络图中结点的“重要性”计算 (30分)-dijkstra算法

解题思路:(邻接矩阵存储) 用dijkstra算法依次求出每个结点到其余结点的最短距离 #include <stdio.h> #include <string.h> #define INF 0x3f3f3f3f #define MaxVex 1000+10 int G[MaxVex][MaxVex]; int visit[MaxVex]; int Nv,Ne; void Init() { memset(G,INF,sizeof(G)); int i; for(i=1; i<=

进阶实验8-2.3 二叉搜索树的最近公共祖先 (30分)

解题思路: 1.定义一个结构体,来存储二叉排序树 typedef struct { int data; int left; int right; int parent; int h; } T; 2.再定义一个结构体,将输入数据存入 typedef struct { int data; int pos; } Info; 3.对输入数据排序 4.用二分法确实查询数据是否存在树中 5.寻找最近公共祖先 1)如果x,y均不是根结点 1.1.如果x==y,则x是y的祖先 1.2.若x,y分别在左右子树,则

【小梅哥FPGA进阶教程】第九章 基于串口猎人软件的串口示波器

九.基于串口猎人软件的串口示波器 1.实验介绍 本实验,为芯航线开发板的综合实验,该实验利用芯航线开发板上的ADC.独立按键.UART等外设,搭建了一个具备丰富功能的数据采集卡,芯航线开发板负责进行数据的采集并将数据通过串口发送到PC机上,PC端,利用强大的串口调试工具--串口猎人,来实现数据的接收分析,并将数据分别以波形.码表.柱状图的形式动态显示出来,以让使用者能够直观的看到ADC采集到的信号细节.同时,用户也可以使用串口猎人通过串口给下位机(FPGA)发送指令,下位机将对接收到的指令进行解

SDUT 2141 【TEST】数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) Input 输入第一行为整数n(0< n <100),表示数据的组数.对于每组数据,第一行是三个整数k,m,t(0<

基于优先级的抢占式调度及实验的源程序和实验步骤

基于优先级的抢占式调度及实验的源程序和实验步骤 1 实验目的    1.学习并验证基于优先级的抢占式调度2 实验内容    在实验一建立的 project 中,创建3 个任务,对这三个任务使用基于优先级的抢占式调度.观察运行结果. 3 实验设备及工具   1.硬件:      a) PC 机   2.软件:      a) PC 机操作系统Windows2000 或windowsXP      b) Tornado2.24 实验原理 Wind 内核调度默认使用基于优先级抢占式调度.每个任务有一个

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历

数据结构实验图论一:基于邻接矩阵的广度优先搜索遍历 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给定一个无向连通图,顶点编号从0到n-1,用广度优先搜索(BFS)遍历,输出从某个顶点出发的遍历序列.(同一个结点的同层邻接点,节点编号小的优先遍历) 输入 输入第一行为整数n(0< n <100),表示数据的组数. 对于每组数据,第一行是三个整数k,m,t(0<k<100,0<m<(k-1)*k/2,

Jieba分词包(三)——基于词频最大切分组合

Jieba分词包(三)--基于词频最大切分组合 在前面,我们已经知道dict中所有的单词和词频信息已经存在了一个trie树中,并且需要分词的句子已经构建成了一个DAG图,构建的过程也运用了dict.那么这次我们来说如何基于每句话的DAG图,找到一个组合路径,使得该组合最合理(即打分最高)? 我们直接针对Jieba分词的源代码来解释,其中已经有了很多注释: def calc(sentence,DAG,idx,route): #动态规划,计算最大概率的切分组合 #输入sentence是句子,DAG句

3Python全栈之路系列之基于socket实现文件上传

Python全栈之路系列之基于socket实现文件上传 发布时间:2017年3月16日 00:04 浏览(106) 评论(0) 分类:Python 前言 此处没有前言 粘包 在实现发送文件功能之前我们先来理解下粘包的问题,下面有两张图,我觉得很清晰的就可以理解到了. 正常情况下发送文件 第一步: 客户端把获取到的文件总大小(size=65426)先放到缓冲区,然后发送给服务端 第二步: 此时客户端接收到的文件总大小就是65426 粘包的问题下发送文件 第一步: 客户端把获取到的文件总大小(siz

SpringMVC经典系列-12基于SpringMVC的文件上传---【LinusZhu】

注意:此文章是个人原创,希望有转载需要的朋友们标明文章出处,如果各位朋友们觉得写的还好,就给个赞哈,你的鼓励是我创作的最大动力,LinusZhu在此表示十分感谢,当然文章中如有纰漏,请联系[email protected],敬请朋友们斧正,谢谢. 不知不觉已经把Spring的基础部分讲解完了,所讲述的都是在项目中经常用到的东西,是经得住考验的,接下来的部分主要是要讲述使用SpringMVC进行的文件上传.处理Ajax请求.自定义拦截器功能的实现,不多说了,首先讲解文件上传部分,开始--