kmp hashtable
This commit is contained in:
commit
5a311c3481
6
CMakeLists.txt
Normal file
6
CMakeLists.txt
Normal file
@ -0,0 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
project(demo)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
add_executable(demo HashTable.cpp)
|
127
HashTable.cpp
Normal file
127
HashTable.cpp
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// Created by Administrator on 2023/7/19.
|
||||
//
|
||||
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
template <class T>
|
||||
struct node_base {
|
||||
T data;
|
||||
node_base* last = nullptr;
|
||||
node_base* next = nullptr;
|
||||
};
|
||||
|
||||
template <class T, class T1>
|
||||
class List {
|
||||
public:
|
||||
List(size_t l = 10)
|
||||
: node(new node_base<T>()), last(node), len(l), size(0) {
|
||||
node_base<T>* for_old = nullptr;
|
||||
node_base<T>* current = last;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (i != 0)
|
||||
current->last = for_old;
|
||||
current->next = new node_base<T>();
|
||||
for_old = current;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
void push_ele(T data) {
|
||||
if (last->next != nullptr) {
|
||||
last->data = data;
|
||||
last = last->next;
|
||||
} else {
|
||||
node_base<T>* current = last;
|
||||
for (int i = 0; i < len * 2; ++i) {
|
||||
current->next = new node_base<T>();
|
||||
current->next->last = current;
|
||||
current = current->next;
|
||||
}
|
||||
len = len * 2;
|
||||
|
||||
last->data = data;
|
||||
last = last->next;
|
||||
}
|
||||
++size;
|
||||
}
|
||||
|
||||
size_t find(T& data, std::function<T1(T*)>& fun) {
|
||||
node_base<T>* header = node;
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (fun(&node->data) == fun(&data)) {
|
||||
|
||||
node = header;
|
||||
return i;
|
||||
}
|
||||
node = node->next;
|
||||
if (node == nullptr) {
|
||||
node = header;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
private:
|
||||
node_base<T>* node;
|
||||
node_base<T>* last;
|
||||
size_t len;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
struct pair {
|
||||
K first;
|
||||
V second;
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
class HashMap {
|
||||
public:
|
||||
HashMap() : size(100) {
|
||||
table = (List<pair<K, V>, K>**) malloc(sizeof( List<pair<K, V>, K>* ) * size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
table[i] = new List<pair<K, V>, K>();
|
||||
}
|
||||
}
|
||||
virtual ~HashMap() {
|
||||
delete table;
|
||||
}
|
||||
public:
|
||||
void insert(pair<K,V> ele) {
|
||||
List<pair<K, V>, K>* list = table[buildHash(ele.first)];
|
||||
list->push_ele(ele);
|
||||
}
|
||||
|
||||
pair<K,V> find(K key) {
|
||||
List<pair<K, V>, K>* list = table[buildHash(key)];
|
||||
pair<K,V> pa = {key, ""};
|
||||
std::function<V(pair<K,V>*)> fun = [&] (pair<K,V>* ele) {
|
||||
if (ele != &pa) {
|
||||
pa.second = ele->second;
|
||||
}
|
||||
return ele->first;
|
||||
};
|
||||
|
||||
list->find(pa, fun);
|
||||
return pa;
|
||||
}
|
||||
private:
|
||||
size_t buildHash(K key) {
|
||||
std::hash<K> hash;
|
||||
return hash(key) % size;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t size;
|
||||
List<pair<K, V>, K>** table;
|
||||
};
|
||||
|
||||
|
||||
int main () {
|
||||
HashMap<std::string, std::string> hashMap;
|
||||
hashMap.insert({"one", "exe haha"});
|
||||
auto item = hashMap.find("one");
|
||||
printf("%s", item.second.c_str());
|
||||
}
|
68
kmp.cpp
Normal file
68
kmp.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Created by Administrator on 2023/7/18.
|
||||
//
|
||||
|
||||
#include <string>
|
||||
|
||||
// next 数组指针 patt 模式串
|
||||
void buildNext(int* next, const std::string& patt) {
|
||||
int prefix; // 前缀
|
||||
int suffix; // 后缀
|
||||
for (prefix = 0, suffix = 0; suffix < patt.size(); ++suffix) {
|
||||
// 前后缀不相同 不同 后缀一直后退
|
||||
while (patt[prefix] != patt[suffix] && prefix != suffix && prefix > 0) {
|
||||
prefix = next[prefix - 1];
|
||||
}
|
||||
// 前后缀相同 那全部向后移动 suffix 在for头里
|
||||
if (patt[prefix] == patt[suffix] && prefix != suffix) {
|
||||
++prefix;
|
||||
}
|
||||
next[suffix] = prefix;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找 字符串 在文本中的 起始位置
|
||||
* @param str 待查文本
|
||||
* @param patt 模式串 查找的串
|
||||
* @return 子串在主串中的起始位置
|
||||
*/
|
||||
size_t stringIndexOf(const std::string& str, const std::string& patt) {
|
||||
if (str.empty() || patt.empty()) return -1;
|
||||
int next[patt.size()];
|
||||
buildNext(next, patt);
|
||||
|
||||
for (int str_i = 0, patt_i = 0; str_i < str.size(); ++str_i, ++patt_i) {
|
||||
while (str[str_i] != patt[patt_i] && patt_i > 0) {
|
||||
patt_i = next[patt_i - 1];
|
||||
}
|
||||
// patt_i +1 在for头内 不在 while 与 if 之间 这里的patt_i还没等待到自增 所以还是下标最大值
|
||||
if (patt_i == patt.size() - 1) {
|
||||
// str_1 是下标 patt.size() 是大小 差值1 故加1
|
||||
return str_i - patt.size() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
size_t index = stringIndexOf("aabaabaafa", "aabaaf");
|
||||
printf("%zu\n", index);
|
||||
|
||||
std::string temp = "在这种困难的抉择下, 本人思来想去, 寝食难安.每个人都不得不面对这些问题. "
|
||||
"在面对这种问题时, 要想清楚, "
|
||||
"随机一段废话, 到底是一种怎么样的存在. "
|
||||
"随机一段废话似乎是一种巧合,但如果我们从一个更大的角度看待问题,"
|
||||
"这似乎是一种不可避免的事实. 要想清楚, 随机一段废话, 到底是一种怎么样的存在."
|
||||
"随机一段废话, 到底应该如何实现. 雷锋曾经提到过, "
|
||||
"自己活着,就是为了使别人过得更美好。这启发了我";
|
||||
|
||||
size_t index1 = stringIndexOf(temp, "随机一段废话");
|
||||
printf("%zu\n", index1);
|
||||
char text[] = {temp[index1], temp[index1+1], temp[index1+2]};
|
||||
printf("%s\n", text);
|
||||
|
||||
size_t index2 = stringIndexOf("500201198807209975410101199712283432140201197412188071", "8807");
|
||||
printf("%zu\n", index2);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user