1.15学习总结

一.

1.字典树--倘若要比对两个字符串是否相同,只需要比对在这棵字典树上,这两个串最后一个元素的祖先链(即前缀)是否相同,并且对于祖先链来说,并不用逐个比较,只需要记录访问就行(字典树是不会使用根节点的,原因很浅显,因为根节点的个数决定究竟有几棵字典树,而通常字典树是只有一棵的,否则产生森林会很麻烦)

3.降低哈希冲突--无错哈希:对于每一个新的哈希值,我们都可以来判断是否和已有的哈希值冲突,如果冲突,那么可以将这个新的哈希值不断加上一个大质数,直到不再冲突

4.链表:

for(int i=1;i<=m;i++)//m个串
{
cin>>str;//下一行的check为bool型 
while(check[hash(str)])hash[i]+=19260817;
hash[i]+= hash(str) ;
}

还有一种多重哈希:用不同的两种或多种方式哈希,然后分别比对每一种哈希值是否相同

for伪代码排序,用来使哈希值单调(更好判断相/不同的数量) 
for(int i=1;i<=m;i++){
	check=1; 
	for(int j=1;j<=qwq;j++)//皮一下
		if(hash[j][i]==hash[j][i+1]){check=0;break;} 
	if(check)ans++;//此为判断相同个数 
} 

2.哈希--对一个串的单向加密过程,并且需要保证所加的密不能高概率重复;

二.

【模板】字符串哈希 - 洛谷

# 【模板】字符串哈希

## 题目描述

如题,给定 $N$ 个字符串(第 $i$ 个字符串长度为 $M_i$,字符串内包含数字、大小写字母,大小写敏感),请求出 $N$ 个字符串中共有多少个不同的字符串。


**友情提醒:如果真的想好好练习哈希的话,请自觉。**

## 输入格式

第一行包含一个整数 $N$,为字符串的个数。

接下来 $N$ 行每行包含一个字符串,为所提供的字符串。

## 输出格式

输出包含一行,包含一个整数,为不同的字符串个数。

## 样例 #1

### 样例输入 #1

```
5
abc
aaaa
abc
abcc
12345
```

### 样例输出 #1

```
4
```

## 提示

对于 $30\%$ 的数据:$N\leq 10$,$M_i≈6$,$Mmax\leq 15$。

对于 $70\%$ 的数据:$N\leq 1000$,$M_i≈100$,$Mmax\leq 150$。

对于 $100\%$ 的数据:$N\leq 10000$,$M_i≈1000$,$Mmax\leq 1500$。


样例说明:

样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。


Tip:
感兴趣的话,你们可以先看一看以下三题:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^\_^

我们通过一个固定的转换方式,将相同的串使其的“密”一定相同,不同的串 尽量 不同。 

1.输入字符串;

2.进制转换,转化为int值;进制设置要大于127;例如130;

3.将得到的int值映射到较小空间(空间复杂度)(折叠)取模计算(mod的值取决于我们开多大的数组)

4.链表:在数组上找到对应下标的值(链表)。

首先判断这个链表是否为空,

如果不为空,则遍历链表元素;

如果找到相同元素(元素比较),停止操作;

如果没有找到相同的元素,则添加元素,更新ans;

5.最后输出ans;

vector:可变数组当链表用;

#include
using namespace std;
string s;
vector M[2001];//链表;
int ans,mod=2000;
void hold(string s){
	//将s变成0—1999之间的值,用130禁止做转化
	int hash=0;
	for(int i=0;i t=M[hash];
	for(int i=0;i>n;
	for(int i=1;i<=n;i++){
		cin>>s;
		//装字符串的函数
		hold(s);
		
	}
	cout<

你可能感兴趣的:(学习)