diff --git a/.gitignore b/.gitignore index 9c5a79d..ad80d49 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ cmake-build*/ **/cmake-build*/ -/.idea -!/.idea/dictionaries \ No newline at end of file +/.idea/ +!/.idea/dictionaries + +**/localtest*/ \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index d03b073..c992c16 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/ZACLib/Android.mk b/ZACLib/Android.mk new file mode 100644 index 0000000..7599873 --- /dev/null +++ b/ZACLib/Android.mk @@ -0,0 +1,12 @@ +# ZACLib/Android.mk +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := ZACLib +LOCAL_SRC_FILES := ZACLib.cpp +LOCAL_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_CPPFLAGS := -std=c++11 # or higher + +include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/ZACLib/CMakeLists.txt b/ZACLib/CMakeLists.txt index 4d444b1..5b6ff3f 100644 --- a/ZACLib/CMakeLists.txt +++ b/ZACLib/CMakeLists.txt @@ -1,10 +1,8 @@ - -set(CMAKE_CXX_STANDARD 11) # or higher - -add_library(ZACLib STATIC "ZACLib.cpp") # if use source +# ZACLib/CMakeLists.txt +add_library(ZACLib STATIC "ZACLib.cpp") target_include_directories(ZACLib PUBLIC ".") set_target_properties(ZACLib PROPERTIES - CXX_STANDARD 11 + CXX_STANDARD 11 # or higher CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS NO ) \ No newline at end of file diff --git a/ZACLib/Makefile b/ZACLib/Makefile new file mode 100644 index 0000000..67608ea --- /dev/null +++ b/ZACLib/Makefile @@ -0,0 +1,19 @@ +# ZACLib/Makefile +CXX := g++ +CXXFLAGS := -I./ \ +-std=c++11 # or higher + +SRC := ZACLib.cpp +OBJ := $(SRC:.cpp=.o) +TARGET := libZACLib.a + +all: $(TARGET) + +$(TARGET): $(OBJ) + ar rcs $@ $(OBJ) + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJ) $(TARGET) diff --git a/ZACLib/ZACLib.cpp b/ZACLib/ZACLib.cpp index ae457c4..033331e 100644 --- a/ZACLib/ZACLib.cpp +++ b/ZACLib/ZACLib.cpp @@ -2,7 +2,6 @@ // Created by wanjiangzhi on 2026/2/24. // -// ReSharper disable CppClassNeverUsed #include "ZACLib.hpp" #include #include @@ -13,26 +12,26 @@ namespace ZACLib { } void Replace::AddRule(const ZAC_SV& from) { - AddRule(from, ZAC_SV("", 0)); + AddRule(from, ZAC_SV("")); } void Replace::AddRule(const ZAC_SV& from, const ZAC_SV& to) { if (from.empty()) return; if (from.size() > max_rule_len) max_rule_len = from.size(); int node = 0; - for (const char i : from) { + for (const ZAC_CHAR i : from) { const auto c = static_cast(i); if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) + trie[node].next[c] = Node::ToIndexOrThrow(trie.size()); trie.emplace_back(); } node = trie[node].next[c]; } if (from.size() > trie[node].match_len) { - trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions) + trie[node].output_id = outputs.size(); trie[node].match_len = from.size(); - outputs.emplace_back(to.data(), to.size()); + outputs.emplace_back(reinterpret_cast(to.data()), to.size()); } } @@ -62,7 +61,7 @@ namespace ZACLib { if (v != -1) { trie[v].fail = trie[trie[u].fail].next[c]; - int f = trie[v].fail; + const int f = trie[v].fail; if (trie[f].match_len > trie[v].match_len) { trie[v].match_len = trie[f].match_len; trie[v].output_id = trie[f].output_id; @@ -82,11 +81,11 @@ namespace ZACLib { if (input.empty()) return result; if (max_rule_len == 0) { - result.append(input.data(), input.size()); + result.append(reinterpret_cast(input.data()), input.size()); return result; } - const auto invalid_output = Node::kInvalidOutput; + constexpr auto invalid_output = Node::kInvalidOutput; const size_t ring_size = max_rule_len + 1; std::vector pending_start(ring_size, invalid_output); std::vector pending_len(ring_size, 0); @@ -121,7 +120,7 @@ namespace ZACLib { size_t cursor = 0; auto emit_until = [&](const size_t upper_bound) { - while (cursor < upper_bound) { + while (cursor < upper_bound) { // NOLINT size_t best_len = 0; size_t best_output = invalid_output; get_best(cursor, best_len, best_output); @@ -129,8 +128,7 @@ namespace ZACLib { ++cursor; continue; } - - result.append(input.data() + last_pos, cursor - last_pos); + result.append(reinterpret_cast(input.data() + last_pos), cursor - last_pos); result.append(outputs[best_output]); cursor += best_len; last_pos = cursor; @@ -138,7 +136,7 @@ namespace ZACLib { }; for (size_t i = 0; i < input.size(); ++i) { - const unsigned char c = input[i]; + const auto c = static_cast(input[i]); state = trie[state].next[c]; if (trie[state].output_id != invalid_output) { @@ -154,7 +152,7 @@ namespace ZACLib { emit_until(input.size()); if (last_pos < input.size()) { - result.append(input.data() + last_pos, input.size() - last_pos); + result.append(reinterpret_cast(input.data() + last_pos), input.size() - last_pos); } return result; @@ -168,19 +166,20 @@ namespace ZACLib { void Search::AddRule(const ZAC_SV& from) { if (from.empty()) return; int node = 0; - for (const char i : from) { + for (const ZAC_CHAR i : from) { const auto c = static_cast(i); if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) + trie[node].next[c] = Node::ToIndexOrThrow(trie.size()); trie.emplace_back(); } node = trie[node].next[c]; } if (from.size() > trie[node].match_len) { - trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions) + + trie[node].output_id = outputs.size(); trie[node].match_len = from.size(); - outputs.emplace_back(from.data(), from.size()); + outputs.emplace_back(reinterpret_cast(from.data()), from.size()); } } @@ -253,7 +252,7 @@ namespace ZACLib { int node = 0; for (const unsigned char c : from) { if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) + trie[node].next[c] = Node::ToIndexOrThrow(trie.size()); trie.emplace_back(); } node = trie[node].next[c]; diff --git a/ZACLib/ZACLib.hpp b/ZACLib/ZACLib.hpp index af98317..e3fba9e 100644 --- a/ZACLib/ZACLib.hpp +++ b/ZACLib/ZACLib.hpp @@ -2,7 +2,6 @@ // Created by wanjiangzhi on 2026/2/24. // -// ReSharper disable CppNonExplicitConvertingConstructor #ifndef ZACLIB_HPP #define ZACLIB_HPP diff --git a/ZACLib/ZACLib.vcxproj b/ZACLib/ZACLib.vcxproj new file mode 100644 index 0000000..2a90b37 --- /dev/null +++ b/ZACLib/ZACLib.vcxproj @@ -0,0 +1,17 @@ + + + + + StaticLibrary + Unicode + c++11 + + + + + + + + + + \ No newline at end of file diff --git a/ZACLib/ZACLib_Types.hpp b/ZACLib/ZACLib_Types.hpp index ca00e36..5dc3ad1 100644 --- a/ZACLib/ZACLib_Types.hpp +++ b/ZACLib/ZACLib_Types.hpp @@ -7,37 +7,82 @@ #define ZACLIB_TYPES_HPP #if __cplusplus >= 201703L - #include +#define HAS_STRING_VIEW +#endif + +#ifdef HAS_STRING_VIEW +#include #else - #include +#include #endif #include #include #include +#include +#if defined(__CHAR_UNSIGNED__) || (defined(_CHAR_UNSIGNED) && _CHAR_UNSIGNED) +#define CHAR_UNSIGNED +#endif namespace ZACLib { + #ifdef CHAR_UNSIGNED + #define ArmCastChar(ptr) reinterpret_cast(ptr) + using ZAC_CHAR = unsigned char; + #else + using ZAC_CHAR = char; + #define ArmCastChar(ptr) (ptr) + #endif + #if __cplusplus >= 201703L - using ZAC_SV = std::string_view; + class ZAC_SV : public std::basic_string_view { + public: + using std::basic_string_view::basic_string_view; + ZAC_SV() = default; + + ZAC_SV(const std::string& s) noexcept + : std::basic_string_view(reinterpret_cast(s.data()), s.size()) {} + + #ifdef CHAR_UNSIGNED + ZAC_SV(const char* s, const size_t n) + : std::basic_string_view(reinterpret_cast(s), n) {} + + ZAC_SV(const char* s) + : std::basic_string_view( + reinterpret_cast(s), + s ? std::char_traits::length(s) : 0 + ) {} + #endif + }; #else class ZAC_SV { - const char* m_data; - const size_t m_size; + const ZAC_CHAR* m_data; + const std::size_t m_size; + public: ZAC_SV() : m_data(nullptr), m_size(0) {} - ZAC_SV(const char* d, const size_t s) : m_data(d), - m_size(s) {} + ZAC_SV(const ZAC_CHAR* d, const std::size_t s) : m_data(d), + m_size(s) {} + + #ifdef CHAR_UNSIGNED + ZAC_SV(const char* d, const size_t s) : m_data(reinterpret_cast(d)), + m_size(s) {} + #endif - ZAC_SV(const std::string& s) : m_data(s.c_str()), - m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造 + ZAC_SV(const std::string& s) noexcept : m_data(ArmCastChar(s.data())), + m_size(s.size()) {} - ZAC_SV(const char* d) : m_data(d), - m_size(d ? std::strlen(d) : 0) {} // 模仿std::string_view,不禁止隐式构造 + ZAC_SV(const ZAC_CHAR* d) : m_data(d), + m_size(d ? std::strlen(reinterpret_cast(d)) : 0) {} - const char* data() const noexcept { + #ifdef CHAR_UNSIGNED + ZAC_SV(const char* d) : m_data(reinterpret_cast(d)), + m_size(d ? std::strlen(d) : 0) {} + #endif + + const ZAC_CHAR* data() const noexcept { return m_data; } @@ -49,22 +94,31 @@ namespace ZACLib { return m_size == 0; } - const char* begin() const { return m_data; } - const char* end() const { return m_data + m_size; } - const char* cbegin() const { return m_data; } - const char* cend() const { return m_data + m_size; } + const ZAC_CHAR* begin() const { return m_data; } + const ZAC_CHAR* end() const { return m_data + m_size; } + const ZAC_CHAR* cbegin() const { return m_data; } + const ZAC_CHAR* cend() const { return m_data + m_size; } - const char& operator[](const size_t i) const { return m_data[i]; } + const ZAC_CHAR& operator[](const size_t i) const { return m_data[i]; } }; #endif struct Node { - std::array next{}; - int fail; - // ReSharper disable once CppVariableCanBeMadeConstexpr - static const auto kInvalidOutput = std::numeric_limits::max(); - size_t output_id; - size_t match_len; + using value_type = int; + using next_type = std::array; + using size_type = std::size_t; + next_type next{}; + value_type fail; + size_type output_id; + size_type match_len; + static constexpr auto kInvalidOutput = std::numeric_limits::max(); + + static value_type ToIndexOrThrow(const size_type value) { + if (value > static_cast(std::numeric_limits::max())) { + throw std::overflow_error("Trie node count exceeds Node::value_type range"); + } + return static_cast(value); + } Node() : fail(0), output_id(kInvalidOutput), @@ -73,3 +127,4 @@ namespace ZACLib { } #endif //ZACLIB_TYPES_HPP +// ReSharper enable CppNonExplicitConvertingConstructor diff --git a/ZACLib/ZACLib_single.hpp b/ZACLib/ZACLib_single.hpp deleted file mode 100644 index 2592784..0000000 --- a/ZACLib/ZACLib_single.hpp +++ /dev/null @@ -1,400 +0,0 @@ -// -// Created by wanjiangzhi on 2026/2/24. -// - -// ReSharper disable CppNonExplicitConvertingConstructor -#ifndef ZACLIB_SINGLE_HPP -#define ZACLIB_SINGLE_HPP - -#ifndef ZACLIB_HPP -#define ZACLIB_HPP - -#include -#include - -// ZACLib_Types.hpp -// -// Created by wanjiangzhi on 2026/2/24. -// - -// ReSharper disable CppNonExplicitConvertingConstructor -#ifndef ZACLIB_TYPES_HPP -#define ZACLIB_TYPES_HPP - -#if __cplusplus >= 201703L -#include -#else -#include -#endif - -#include -#include -#include - - -namespace ZACLib { - #if __cplusplus >= 201703L - using ZAC_SV = std::string_view; - #else - class ZAC_SV { - const char* m_data; - const size_t m_size; - - public: - ZAC_SV() : m_data(nullptr), - m_size(0) {} - - ZAC_SV(const char* d, const size_t s) : m_data(d), - m_size(s) {} - - ZAC_SV(const std::string& s) : m_data(s.c_str()), - m_size(s.size()) {} // 模仿std::string_view,不禁止隐式构造 - - ZAC_SV(const char* d) : m_data(d), - m_size(d ? std::strlen(d) : 0) {} // 模仿std::string_view,不禁止隐式构造 - - const char* data() const noexcept { - return m_data; - } - - std::size_t size() const noexcept { - return m_size; - } - - bool empty() const noexcept { - return m_size == 0; - } - - const char* begin() const { return m_data; } - const char* end() const { return m_data + m_size; } - const char* cbegin() const { return m_data; } - const char* cend() const { return m_data + m_size; } - - const char& operator[](const size_t i) const { return m_data[i]; } - }; - #endif - - struct Node { - std::array next{}; - int fail; - // ReSharper disable once CppVariableCanBeMadeConstexpr - static const auto kInvalidOutput = std::numeric_limits::max(); - size_t output_id; - size_t match_len; - - Node() : fail(0), - output_id(kInvalidOutput), - match_len(0) { next.fill(-1); } - }; -} - -#endif //ZACLIB_TYPES_HPP - -// ZACLib_Types.hpp end - -namespace ZACLib { - class Replace { - public: - Replace() { trie.emplace_back(); } - - void AddRule(const ZAC_SV& from) { - AddRule(from, ZAC_SV("", 0)); - } - - void AddRule(const ZAC_SV& from, const ZAC_SV& to) { - if (from.empty()) return; - if (from.size() > max_rule_len) max_rule_len = from.size(); - int node = 0; - for (const char i : from) { - const auto c = static_cast(i); - if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) - trie.emplace_back(); - } - node = trie[node].next[c]; - } - if (from.size() > trie[node].match_len) { - trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions) - trie[node].match_len = from.size(); - outputs.emplace_back(to.data(), to.size()); - } - } - - void AddReplaceRule(const ZAC_SV& from, const ZAC_SV& to) { AddRule(from, to); } - void AddRemoveRule(const ZAC_SV& from) { AddRule(from); } - - void Build() { - std::queue q; - for (int c = 0; c < 256; ++c) { - int nxt = trie[0].next[c]; - if (nxt != -1) { - trie[nxt].fail = 0; - q.push(nxt); - } else trie[0].next[c] = 0; - } - while (!q.empty()) { - const int u = q.front(); - q.pop(); - for (int c = 0; c < 256; ++c) { - int v = trie[u].next[c]; - if (v != -1) { - trie[v].fail = trie[trie[u].fail].next[c]; - const int f = trie[v].fail; - if (trie[f].match_len > trie[v].match_len) { - trie[v].match_len = trie[f].match_len; - trie[v].output_id = trie[f].output_id; - } - q.push(v); - } else { - trie[u].next[c] = trie[trie[u].fail].next[c]; - } - } - } - } - - std::string Do(const ZAC_SV& input) const { - std::string result; - result.reserve(input.size()); - - if (input.empty()) return result; - if (max_rule_len == 0) { - result.append(input.data(), input.size()); - return result; - } - - const auto invalid_output = Node::kInvalidOutput; - const size_t ring_size = max_rule_len + 1; - std::vector pending_start(ring_size, invalid_output); - std::vector pending_len(ring_size, 0); - std::vector pending_output(ring_size, invalid_output); - - auto get_best = [&](const size_t start, size_t& best_len, size_t& best_output) { - const size_t idx = start % ring_size; - if (pending_start[idx] == start) { - best_len = pending_len[idx]; - best_output = pending_output[idx]; - } else { - best_len = 0; - best_output = invalid_output; - } - }; - - auto set_best = [&](const size_t start, const size_t len, const size_t output_id) { - const size_t idx = start % ring_size; - if (pending_start[idx] != start) { - pending_start[idx] = start; - pending_len[idx] = 0; - pending_output[idx] = invalid_output; - } - if (len > pending_len[idx]) { - pending_len[idx] = len; - pending_output[idx] = output_id; - } - }; - - int state = 0; - size_t last_pos = 0; - size_t cursor = 0; - - auto emit_until = [&](const size_t upper_bound) { - while (cursor < upper_bound) { - size_t best_len = 0; - size_t best_output = invalid_output; - get_best(cursor, best_len, best_output); - if (best_len == 0) { - ++cursor; - continue; - } - - result.append(input.data() + last_pos, cursor - last_pos); - result.append(outputs[best_output]); - cursor += best_len; - last_pos = cursor; - } - }; - - for (size_t i = 0; i < input.size(); ++i) { - const unsigned char c = input[i]; - state = trie[state].next[c]; - - if (trie[state].output_id != invalid_output) { - const size_t match_len = trie[state].match_len; - const size_t match_start = i + 1 - match_len; - set_best(match_start, match_len, trie[state].output_id); - } - - const size_t finalize_before = (i + 1 > max_rule_len) ? (i + 1 - max_rule_len) : 0; - emit_until(finalize_before); - } - - emit_until(input.size()); - - if (last_pos < input.size()) { - result.append(input.data() + last_pos, input.size() - last_pos); - } - - return result; - } - - private: - std::vector trie{Node{}}; - std::vector outputs; - size_t max_rule_len = 0; - }; - - - class Search { - public: - struct Match { - size_t pos, len; - size_t ruleId; - }; - - Search() { trie.emplace_back(); } - - void AddRule(const ZAC_SV& from) { - if (from.empty()) return; - int node = 0; - for (const char i : from) { - const auto c = static_cast(i); - if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) - trie.emplace_back(); - } - node = trie[node].next[c]; - } - if (from.size() > trie[node].match_len) { - trie[node].output_id = outputs.size(); // NOLINT(*-narrowing-conversions) - trie[node].match_len = from.size(); - outputs.emplace_back(from.data(), from.size()); - } - } - - void Build() { - std::queue q; - for (int c = 0; c < 256; ++c) { - int nxt = trie[0].next[c]; - if (nxt != -1) { - trie[nxt].fail = 0; - q.push(nxt); - } else trie[0].next[c] = 0; - } - while (!q.empty()) { - const int u = q.front(); - q.pop(); - for (int c = 0; c < 256; ++c) { - int v = trie[u].next[c]; - if (v != -1) { - trie[v].fail = trie[trie[u].fail].next[c]; - const int f = trie[v].fail; - if (trie[f].match_len > trie[v].match_len) { - trie[v].match_len = trie[f].match_len; - trie[v].output_id = trie[f].output_id; - } - q.push(v); - } else { - trie[u].next[c] = trie[trie[u].fail].next[c]; - } - } - } - } - - std::vector Do(const ZAC_SV& input) const { - std::vector result; - if (trie.empty()) return result; - - int state = 0; - for (size_t i = 0; i < input.size(); ++i) { - const auto c = static_cast(input[i]); - while (state != 0 && trie[state].next[c] == -1) { - state = trie[state].fail; - } - if (trie[state].next[c] != -1) { - state = trie[state].next[c]; - } else { - state = 0; - } - if (trie[state].output_id != Node::kInvalidOutput) { - result.push_back( - Match{ - i + 1 - trie[state].match_len, - trie[state].match_len, - trie[state].output_id - } - ); - } - } - return result; - } - - private: - std::vector trie{Node{}}; - std::vector outputs; - }; - - - class Has { - public: - Has() { trie.emplace_back(); } - - void AddRule(const ZAC_SV& from) { - if (from.empty()) return; - int node = 0; - for (const unsigned char c : from) { - if (trie[node].next[c] == -1) { - trie[node].next[c] = trie.size(); // NOLINT(*-narrowing-conversions) - trie.emplace_back(); - } - node = trie[node].next[c]; - } - trie[node].output_id = 0; - } - - void Build() { - std::queue q; - for (int c = 0; c < 256; ++c) { - int nxt = trie[0].next[c]; - if (nxt != -1) { - trie[nxt].fail = 0; - q.push(nxt); - } else { - trie[0].next[c] = 0; - } - } - - while (!q.empty()) { - const int u = q.front(); - q.pop(); - for (int c = 0; c < 256; ++c) { - int v = trie[u].next[c]; - if (v != -1) { - trie[v].fail = trie[trie[u].fail].next[c]; - q.push(v); - } else { - trie[u].next[c] = trie[trie[u].fail].next[c]; - } - } - } - } - - bool Do(const ZAC_SV& input) const { - int state = 0; - for (const unsigned char c : input) { - state = trie[state].next[c]; - - int s = state; - while (s != 0) { - if (trie[s].output_id != Node::kInvalidOutput) return true; - s = trie[s].fail; - } - } - return false; - } - - private: - std::vector trie{Node{}}; - }; -} // namespace ZACLIB - -#endif // ZACLIB_HPP -#endif //ZACLIB_SINGLE_HPP diff --git a/examples/windows/CMakeLists.txt b/examples/windows/CMakeLists.txt deleted file mode 100644 index 088a91c..0000000 --- a/examples/windows/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -cmake_minimum_required(VERSION 3.28.3) -project(ZACLib_Example_windows) - -set(CMAKE_CXX_STANDARD 23) - -add_subdirectory( - ../../ZACLib - ${CMAKE_BINARY_DIR}/ZACLib -) - -add_executable(${CMAKE_PROJECT_NAME} test.cpp) -target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ZACLib) diff --git a/examples/windows/main.cpp b/examples/windows/main.cpp deleted file mode 100644 index 1b127ed..0000000 --- a/examples/windows/main.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include "../../ZACLib/ZACLib.hpp" - -int main() { - SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8); - using namespace ZACLib; - - Replace replacer; - replacer.AddReplaceRule("1", "一"); - replacer.AddReplaceRule("2", "二"); - replacer.AddRemoveRule("_"); - replacer.Build(); - - const std::string name = "1221_2112"; - const std::string replaced = replacer.Do(name); - std::cout << "原始: " << name << "\n"; - std::cout << "替换后: " << replaced << "\n\n"; - - Search searcher; - searcher.AddRule("二"); - searcher.AddRule("三"); - searcher.Build(); - - const std::string& text = "一一二二三三"; - const auto matches = searcher.Do(text); - std::cout << "Search 匹配结果:\n"; - for (auto &m : matches) { - std::cout << "匹配: " << text.substr(m.pos, m.len) - << " 位置: " << m.pos - << " 规则ID: " << m.ruleId << "\n"; - } - std::cout << "\n"; - - Has hasCheck; - hasCheck.AddRule("一"); - hasCheck.AddRule("三"); - hasCheck.Build(); - - std::cout << "Has 检查:\n"; - std::cout << "是否包含 '一' 或 '三'? " - << (hasCheck.Do("一三") ? "是" : "否") << "\n"; - - std::cout << "是否包含 '四'? " - << (hasCheck.Do("四") ? "是" : "否") << "\n"; - - return 0; -} diff --git a/examples/windows/test.cpp b/examples/windows/test.cpp deleted file mode 100644 index 7921439..0000000 --- a/examples/windows/test.cpp +++ /dev/null @@ -1,55 +0,0 @@ -#include - -/*#include "windows.h"*/ -#include "../../ZACLib/ZACLib_single.hpp" -#include -#include -#include - - -int main() { - /*SetConsoleCP(CP_UTF8); - SetConsoleOutputCP(CP_UTF8);*/ - - ZACLib::Search GrenadeSearcher; - - // 添加规则 - GrenadeSearcher.AddRule("FragGrenade"); - GrenadeSearcher.AddRule("SmokeBomb"); - GrenadeSearcher.AddRule("BurnGrenade"); - GrenadeSearcher.AddRule("StunGrenade"); - - // 构建 Trie - GrenadeSearcher.Build(); - - std::vector testClasses = {"BP_Projectile_FragGrenade_C_2", "SmokeBombY", "RecycledGrenade"}; - ZACLib::ZAC_SV input; - - const std::unordered_map GrenadeType = { - {"FragGrenade", "Grenade.FragGrenade"}, - {"SmokeBomb", "Grenade.SmokeBomb"}, - {"BurnGrenade", "Grenade.BurnGrenade"}, - {"StunGrenade", "Grenade.StunGrenade"}, - }; - - for (auto& ClassName : testClasses) { - if (ClassName.find("Recycled") != std::string::npos) continue; - - std::string GrenadeName = "Grenade.Default"; - - // 使用 ZACLib::Search - auto matches = GrenadeSearcher.Do(ClassName); - for (auto &m : matches) { - auto key = ClassName.substr(m.pos, m.len); - auto it = GrenadeType.find(key); - if (it != GrenadeType.end()) { - GrenadeName = it->second; - break; - } - } - - std::cout << ClassName << " -> " << GrenadeName << "\n"; - } - - return 0; -} \ No newline at end of file