String
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
#include "c_InplaceMSD.h"
|
||||
#include "c_Test.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static int string_msd_extractor(const void* elem, c_size_t d, void* args) {
|
||||
(void)args;
|
||||
const char* str = *(const char* const*)elem;
|
||||
c_size_t len = strlen(str);
|
||||
if (d >= len) return -1;
|
||||
return (int)((unsigned char)str[d]);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(test_c_InPlace_MSD_RadixSort_VariableStrings) {
|
||||
// 构造一个包含 18 个元素、大量前缀交织("shor", "shore", "short", "sh")的变长恶劣方阵
|
||||
const char* arr[] = {
|
||||
"she", "sells", "seashells", "by", "the",
|
||||
"sea", "shore", "the", "shells", "she",
|
||||
"sea", "shore", "sit", "short", "shor", "a",
|
||||
"sh", "z"
|
||||
};
|
||||
c_size_t num = sizeof(arr) / sizeof(arr[0]);
|
||||
|
||||
// 调用纯就地 MSD 排序,零动态辅助缓冲分配
|
||||
c_err_t err = c_InPlaceMSD_RadixSort(arr, num, sizeof(char*), string_msd_extractor, NULL);
|
||||
ASSERT_INT_EQ(C_ERR_OK, err);
|
||||
|
||||
// 验证严格的全局字典序单调非减
|
||||
for (c_size_t i = 0; i < num - 1; i++) {
|
||||
if (strcmp(arr[i], arr[i + 1]) > 0) {
|
||||
printf(" " COLOR_RED "[FAIL] 就地置换错位捕获: arr[%d]='%s' 排在 arr[%d]='%s' 的前面!" COLOR_RESET "\n",
|
||||
(int)i, arr[i], (int)(i + 1), arr[i + 1]);
|
||||
ASSERT_TRUE(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 校验极短终止符和极长串的拓扑归位状态
|
||||
ASSERT_TRUE(strcmp("a", arr[0]) == 0);
|
||||
ASSERT_TRUE(strcmp("by", arr[1]) == 0);
|
||||
ASSERT_TRUE(strcmp("sea", arr[2]) == 0); // 极短终止符前缀必须完美垫底最前端
|
||||
ASSERT_TRUE(strcmp("shells", arr[9]) == 0); // 极短终止符前缀必须完美垫底最前端
|
||||
ASSERT_TRUE(strcmp("shor", arr[10]) == 0);
|
||||
ASSERT_TRUE(strcmp("shore", arr[11]) == 0);
|
||||
ASSERT_TRUE(strcmp("z", arr[num - 1]) == 0); // 尾部大收拢正确
|
||||
}
|
||||
|
||||
// ==========================================
|
||||
// 新增测试:强迫其在顶层就少于15个元素,精准覆盖降级插入排序专线
|
||||
// ==========================================
|
||||
TEST_CASE(test_c_InPlaceMSD_RadixSort_DirectInsertionSortCutoff) {
|
||||
// 🌟 故意精简至 10 个数据(小于阈值 15),且打乱顺序、包含相同前缀和变长终止符
|
||||
const char* arr_short[] = {
|
||||
"shore", "she", "sells", "sea", "sh",
|
||||
"shor", "sit", "short", "a", "sea"
|
||||
};
|
||||
c_size_t num = sizeof(arr_short) / sizeof(arr_short[0]);
|
||||
|
||||
// 调用入口:在第 0 字节探测时就因为总数 10 < 15 爆发降级,直接由 c_IP_MSD_InsertionSort 接管
|
||||
c_err_t err = c_InPlaceMSD_RadixSort(arr_short, num, sizeof(char*), string_msd_extractor, NULL);
|
||||
ASSERT_INT_EQ(C_ERR_OK, err);
|
||||
|
||||
// 验证降级插入排序后的全局字典序是否完全单调非减
|
||||
for (c_size_t i = 0; i < num - 1; i++) {
|
||||
if (strcmp(arr_short[i], arr_short[i + 1]) > 0) {
|
||||
printf(" " COLOR_RED "[FAIL] 降级插入排序错位: arr_short[%d]='%s' 居然排在 arr_short[%d]='%s' 前面!" COLOR_RESET "\n",
|
||||
(int)i, arr_short[i], (int)(i + 1), arr_short[i + 1]);
|
||||
ASSERT_TRUE(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 验证级联插入排序对短前缀终止符与后缀字典序的排序正确性
|
||||
ASSERT_TRUE(strcmp("a", arr_short[0]) == 0);
|
||||
ASSERT_TRUE(strcmp("sea", arr_short[1]) == 0);
|
||||
ASSERT_TRUE(strcmp("sea", arr_short[2]) == 0); // 稳定排序项紧凑排布
|
||||
ASSERT_TRUE(strcmp("sh", arr_short[4]) == 0); // 短前缀完美垫底
|
||||
ASSERT_TRUE(strcmp("shor", arr_short[6]) == 0);
|
||||
ASSERT_TRUE(strcmp("shore", arr_short[7]) == 0);
|
||||
ASSERT_TRUE(strcmp("short", arr_short[8]) == 0);
|
||||
ASSERT_TRUE(strcmp("sit", arr_short[num-1]) == 0);
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
TEST_START(C_InPlace_MSD_RadixSort_TestSuite);
|
||||
RUN_TEST(test_c_InPlace_MSD_RadixSort_VariableStrings);
|
||||
RUN_TEST(test_c_InPlaceMSD_RadixSort_DirectInsertionSortCutoff);
|
||||
TEST_REPORT();
|
||||
return (g_test_registry.failed_count > 0 ? 1 : 0);
|
||||
}
|
||||
Reference in New Issue
Block a user