目录
题目
怎么删除字符串的首字母
1.使用 string::erase
哈希中的碰撞冲突
3.1 线性探测法
3.2 链地址法
3.3 再哈希法
3.4 …
哈希函数的设计
4.1 更大的哈希表
4.2 更好的哈希运算
题目
给你一个字符串数组
ideas
表示在公司命名过程中使用的名字列表。公司命名流程如下:
- 从
ideas
中选择 2 个 不同 名字,称为ideaA
和ideaB
。- 交换
ideaA
和ideaB
的首字母。- 如果得到的两个新名字 都 不在
ideas
中,那么ideaA ideaB
(串联ideaA
和ideaB
,中间用一个空格分隔)是一个有效的公司名字。- 否则,不是一个有效的名字。
返回 不同 且有效的公司名字的数目。
补充 引用来源(第四讲. 经典算法之哈希映射)
引用来源(从 C++ 中的字符串中删除第一个字符)
怎么删除字符串的首字母
1.使用
string::erase
从字符串中就地删除字符的推荐解决方案是使用
string::erase
功能。以下 C++ 程序使用范围重载演示了它的用法:#include <iostream>#include <string>int main(){std::string str = "ABCD";str.erase(0, 1);std::cout << str << std::endl; // BCDreturn 0;}
这string::erase
函数也被重载以接受迭代器。迭代器应该指向需要从字符串中删除的元素。
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
int main()
{
std::string str = "ABCD";
str.erase(str.begin());
std::cout << str << std::endl; // BCD
return 0;
}
下载 运行代码
建议在调用之前检查一个空字符串string::erase
功能。否则,代码会抛出std::length_error
空输入序列的异常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
int main()
{
std::string str = "ABCD";
if (!str.empty()) {
str.erase(str.begin());
}
std::cout << str << std::endl; // BCD
return 0;
}
哈希中的碰撞冲突
哈希冲突是由于不同键值经过哈希函数后产生相同的哈希值而产生的情况,可以说这种情况的发生是必然的。
解决碰撞冲突的思路有两个,其一是为冲突发生的情况下,设置新的规则来应对,比方说,如果出现冲突,那么就从冲突出现位置顺序往后找,直到找到一个空的位子,填上去;或者是隔几个位子跳着跳着找;又或者是在冲突出现的位置链接上一条链表,依次记录相同哈希值元素的出现次数。我们着重介绍下这几种常用的方法。3.1 线性探测法
顾名思义,若出现冲突,则逐个往后或往前搜索,直到找到空的位子。
假设现在又出现一个元素 20 经哈希函数后得到的映射结果也是位置 0 ,而发现该位置已被元素 10 所占据,那么就可以线性向后查找,直到找到第一个空的位置 2 ,然后放上去。(若找到了哈希表结尾,则回到开头继续向后查找,由于保证了哈希表的大小一定比元素总个数多,所以能保证每个元素都能找到自己的位置)
但这样有一个弊端就是,此时 20 占据了一个本不属于它的位置 2 ,如若下次来了一个本就映射到位置 2 的元素,那么它也只好继续向后探测,换句话说,虽然你解决了一个冲突,但同时又产生了另一个产生冲突的隐患,而且甚至还有可能出现无限冲突的情况。另一方面对于要在表中删除元素的情况,处理起来也不太方便。3.2 链地址法
这种思想是将所有映射到位置 i 的元素构建一条链表,并将单链表的头指针存在哈希表的第 i 个单元中,这样做的好处是一方面不会出现前面方法的那种解决一个哈希冲突,又带了新冲突隐患的问题,另一方面是在元素的删除上也能很好的处理,只需删除对应节点即可。但缺点也有,就是可能会在某个位置出现一条很长很长的链,增加了时间的开销。
3.3 再哈希法这种方式是选取多个哈希函数,若第 j 个哈希函数出现了冲突,那么选用第 j+1 个哈希函数计算,直至找到不发生冲突的哈希函数。又或者使用同一个哈希函数,以上一轮产生的哈希值作为键值进行再次映射,直至找到可用的位置。
3.4 …
除了以上这些方法外,还有很多类似的方法,如平方探测法等等,这类处理思路都是着重于当冲突发生的时候如何处理,此外,另一种解决冲突的思想便是在冲突发生之前尽可能的减少冲突的发生概率,即设计更好的哈希函数。
哈希函数的设计
显然,冲突的产生其实很大的一部分原因是由于哈希函数设计得不够好,一个更好的哈希函数应该是让不同键值尽量映射到不同的位置,或者说尽可能地做到随机映射。
4.1 更大的哈希表
不难想到,一张更大的哈希表能降低冲突发生的概率,以之前的简单哈希函数为例,极端情况是如果把 m 取得很大到 1010 时,那么显然就不会发生冲突了。一般而言,在经验和习惯上,会将哈希表的大小设置在元素个数的 1~10 倍之间,以实现在较小空间冗余的代价上,减小冲突的发生,提高时间效率。
4.2 更好的哈希运算
......
————————————————版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_38609781/article/details/84836583