mirror of
https://github.com/hasherezade/hollows_hunter.git
synced 2026-10-12 02:15:21 +00:00
106 lines
2.8 KiB
C++
106 lines
2.8 KiB
C++
#include "strings_util.h"
|
|
|
|
#include <algorithm>
|
|
#include <cstring>
|
|
|
|
std::string hhunter::util::to_lowercase(std::string str)
|
|
{
|
|
std::transform(str.begin(), str.end(), str.begin(), tolower);
|
|
return str;
|
|
}
|
|
|
|
bool hhunter::util::is_cstr_equal(char const *a, char const *b, const size_t max_len)
|
|
{
|
|
for (size_t i = 0; i < max_len; ++i) {
|
|
if (tolower(a[i]) != tolower(b[i])) {
|
|
return false;
|
|
}
|
|
if (tolower(a[i]) == '\0') break;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
#define MIN(x,y) ((x) < (y) ? (x) : (y))
|
|
|
|
size_t hhunter::util::levenshtein_distance(const char s1[], const char s2[])
|
|
{
|
|
const size_t MAX_LEN = 100;
|
|
const size_t len1 = strlen(s1);
|
|
const size_t len2 = strlen(s2);
|
|
|
|
if (len1 >= MAX_LEN || len2 >= MAX_LEN) return(-1);
|
|
|
|
//init the distance matrix
|
|
int dist[MAX_LEN][MAX_LEN] = { 0 };
|
|
for (int i = 0;i <= len1;i++) {
|
|
dist[0][i] = i;
|
|
}
|
|
for (int j = 0;j <= len2; j++) {
|
|
dist[j][0] = j;
|
|
}
|
|
// calculate
|
|
for (int j = 1;j <= len1; j++) {
|
|
for (int i = 1;i <= len2; i++) {
|
|
int track = 1;
|
|
if (s1[i - 1] == s2[j - 1]) {
|
|
track = 0;
|
|
}
|
|
int t = MIN((dist[i - 1][j] + 1), (dist[i][j - 1] + 1));
|
|
dist[i][j] = MIN(t, (dist[i - 1][j - 1] + track));
|
|
}
|
|
}
|
|
return dist[len2][len1];
|
|
}
|
|
|
|
size_t hhunter::util::str_hist_diffrence(const char s1[], const char s2[])
|
|
{
|
|
const size_t MAX_LEN = 255;
|
|
size_t hist1[MAX_LEN] = { 0 };
|
|
size_t hist2[MAX_LEN] = { 0 };
|
|
|
|
const size_t len1 = strlen(s1);
|
|
const size_t len2 = strlen(s2);
|
|
|
|
for (size_t i = 0; i < len1; i++) {
|
|
char c = tolower(s1[i]);
|
|
hist1[c]++;
|
|
}
|
|
|
|
for (size_t i = 0; i < len2; i++) {
|
|
char c = tolower(s2[i]);
|
|
hist2[c]++;
|
|
}
|
|
|
|
size_t diffs = 0;
|
|
for (size_t i = 0; i < MAX_LEN; i++) {
|
|
if (hist2[i] == hist1[i]) continue;
|
|
diffs++;
|
|
}
|
|
return diffs;
|
|
}
|
|
|
|
hhunter::util::stringsim_type hhunter::util::is_string_similar(const std::string ¶m, const std::string &filter)
|
|
{
|
|
bool sim_found = (param.find(filter) != std::string::npos) || (filter.find(param) != std::string::npos);
|
|
if (sim_found) return SIM_SUBSTR;
|
|
|
|
size_t dist = util::levenshtein_distance(filter.c_str(), param.c_str());
|
|
if (dist <= (param.length() / 2)) {
|
|
sim_found = true;
|
|
}
|
|
if (dist >= param.length() || dist >= filter.length()) {
|
|
sim_found = false;
|
|
}
|
|
if (sim_found) return SIM_LAV_DIST;
|
|
|
|
size_t diff = util::str_hist_diffrence(filter.c_str(), param.c_str());
|
|
if (diff <= (param.length() / 2) || diff <= (filter.length() / 2)) {
|
|
sim_found = true;
|
|
}
|
|
if (diff >= param.length() || diff >= filter.length()) {
|
|
sim_found = false;
|
|
}
|
|
if (sim_found) return SIM_HIST;
|
|
return SIM_NONE;
|
|
}
|