uva 10391 Compound Words

哈希

题意简短:单case,输入一列单词即一个字典,已经按字典序排好输入,上限为120000,然后要你找一些单词,这种单词可以分为两部分,两部分都是字典里面的单词,按字典序输出这种单词

很裸的哈希,对于每个单词,将其分成两部分,一共有len中分法,然后去查找是否都在字典中,如果都在字典中就输出(因为输入已经按字典序排好,扫描时直接扫下来就可以了,找到合适的就输出)

问题的关键就转变为,给你一个单词,怎么判断这个单词是不是在字典中,用哈希就可以快速判断到。输入时随便将每个单词都用哈希函数映射掉,每得到要查询的单词也直接映射过去查找

处理冲突的方法是链表(静态链表数组模拟)

用了BKDHash函数在处理字符串的映射

BKDHash,40ms

#include <cstdio>
#include <cstring>
#define N 120000
#define LEN 110
#define P 0x7fffffff

int n,tot;
char word[N+10][LEN];
int head[N+10];
struct list
{
   int n;
   int next;
}e[N+10];

void add(unsigned int index ,int m)
{
   e[tot].n = m;
   e[tot].next = head[index];
   head[index] = tot++;
}

unsigned int BKDHash(char *str)
{
   unsigned int seed = 131;
   unsigned int hash = 0;
   int len = strlen(str);
   for(int i=0; i<len; i++)
      hash = hash * seed + str[i];
   return (hash & P) % N;
}

int find(char *str)
{
   unsigned int index = BKDHash(str);
   for(int k=head[index]; k!=-1; k=e[k].next)
   {
      int m = e[k].n;
      if(!strcmp(word[m] , str))
         return k;
   }
   return -1;
}

int main()
{
   n = tot = 0;
   memset(head,-1,sizeof(head));
   while(scanf("%s",word[n])!=EOF)
   {
      unsigned int index = BKDHash(word[n]);
      add(index , n);
      n++;
   }
   for(int i=0; i<n; i++)
   {
      char str1[LEN] , str2[LEN];
      int len = strlen(word[i]);
      for(int j=0; j<len-1; j++)
      {
         int k,kk;
         for(k=0,kk=0; kk<=j; k++,kk++)
            str1[k] = word[i][kk];
         str1[k] = '\0';
         for(k=0,kk=j+1; kk<len; k++,kk++)
            str2[k] = word[i][kk];
         str2[k] = '\0';

         int ok[2];
         ok[0] = find(str1);
         ok[1] = find(str2);
         if(ok[0] != -1 && ok[1] != -1)
         {
            printf("%s\n",word[i]);
            break;
         }
      }
   }
   return 0;
}

自己瞎比比写的一个字符串哈希,冲突死了,200ms

#include <cstdio>
#include <cstring>
#define N 120000
#define LEN 110

int n,tot;
char word[N+10][LEN];
int head[N+10];
struct list
{
   int n;
   int next;
}e[N+10];

void add(int index ,int m)
{
   e[tot].n = m;
   e[tot].next = head[index];
   head[index] = tot++;
}

int Hash(int m)
{
   int len = strlen(word[m]);
   int sum = 0;
   for(int i=0; i<len ; i++)
      sum += (word[m][i] - 'a')*i;
   return sum%N;
}

int find(char *str)
{
   int len = strlen(str);
   int sum = 0;
   for(int i=0; i<len ;i++)
      sum += (str[i] - 'a')*i;
   int index = sum%N;
   for(int k=head[index]; k!=-1; k=e[k].next)
   {
      int m = e[k].n;
      if(!strcmp(word[m] , str))
         return k;
   }
   return -1;
}

int main()
{
   n = tot = 0;
   memset(head,-1,sizeof(head));
   while(scanf("%s",word[n])!=EOF)
   {
      int index = Hash(n);
      add(index , n);
      n++;
   }
   for(int i=0; i<n; i++)
   {
      char str1[LEN] , str2[LEN];
      int len = strlen(word[i]);
      for(int j=0; j<len-1; j++)
      {
         int k,kk;
         for(k=0,kk=0; kk<=j; k++,kk++) str1[k] = word[i][kk];
         str1[k] = '\0';
         for(k=0,kk=j+1; kk<len; k++,kk++) str2[k] = word[i][kk];
         str2[k] = '\0';
         int ok[2];
         ok[0] = find(str1);
         ok[1] = find(str2);
         if(ok[0] != -1 && ok[1] != -1)
         {
            printf("%s\n",word[i]);
            break;
         }
      }
   }
   return 0;
}
原文地址:https://www.cnblogs.com/scau20110726/p/3038763.html