mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-06 08:46:42 +08:00
371 lines
10 KiB
C
371 lines
10 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#if defined(TEST_TARGET_sort)
|
||
#include <varch/command.h>
|
||
#include <varch/unitt.h>
|
||
#include <varch/sort.h>
|
||
#include <varch/list.h>
|
||
#else
|
||
#include "init.h"
|
||
#include "command.h"
|
||
#include "unitt.h"
|
||
#include "kern.h"
|
||
#include "sort.h"
|
||
#include "list.h"
|
||
#endif
|
||
|
||
/************************************************************************************/
|
||
/************************************* Unit Test ************************************/
|
||
/************************************************************************************/
|
||
|
||
// #define EXIT_TEST
|
||
extern uint64_t unitt_clock(void);
|
||
|
||
static int test_0(void)
|
||
{
|
||
for (int i = 0; i < 100; i++)
|
||
{
|
||
if (0)
|
||
{
|
||
|
||
#if defined (EXIT_TEST)
|
||
exit(0);
|
||
#endif
|
||
return UNITT_E_FAIL;
|
||
}
|
||
}
|
||
|
||
return UNITT_E_OK;
|
||
}
|
||
|
||
static void unitt_task(void)
|
||
{
|
||
static UNITT_TCASE rand_tests[] = {
|
||
UNITT_TCASE(test_0),
|
||
// UNITT_TCASE(test_1),
|
||
// UNITT_TCASE(test_2),
|
||
};
|
||
|
||
static UNITT suites[] = {
|
||
{ "xxx suite", rand_tests, sizeof(rand_tests) / sizeof(rand_tests[0]) , unitt_clock },
|
||
};
|
||
|
||
UNITT_EXE(suites);
|
||
}
|
||
|
||
/************************************************************************************/
|
||
/************************************* Base Test ************************************/
|
||
/************************************************************************************/
|
||
|
||
static void test_basic_usage(void)
|
||
{
|
||
/* 针对int型数组,进行升序
|
||
*/
|
||
int array_int[] = {1, 3, 6, 5, 0, 2, 9, 8, 7, -4}; // 定义时候任意乱序
|
||
|
||
// 传入数组基地址,排序的区间,指定int型的升序ops
|
||
sort_bubble(array_int, 0, sizeof(array_int)/sizeof(array_int[0]) - 1, &sops_int_ascend);
|
||
|
||
// 输出排序后的数组
|
||
for (int i = 0; i < sizeof(array_int)/sizeof(array_int[0]); i++)
|
||
{
|
||
printf("%d, ", array_int[i]);
|
||
}
|
||
printf("\r\n");
|
||
|
||
/* ---------------------------------------- 代码分割线 ---------------------------------------- */
|
||
|
||
/* 针对float型数组,进行降序
|
||
*/
|
||
float array_float[] = {-1.1, 2.1, 6.6, 5.0, 0.1, 2.8, 9.9, 9.8, 7.0, -4.5}; // 定义时候任意乱序
|
||
|
||
// 传入数组基地址,排序的区间,指定float型的降序ops
|
||
sort_bubble(array_float, 0, sizeof(array_float)/sizeof(array_float[0]) - 1, &sops_float_descend);
|
||
|
||
// 输出排序后的数组
|
||
for (int i = 0; i < sizeof(array_float)/sizeof(array_float[0]); i++)
|
||
{
|
||
printf("%.2f, ", array_float[i]);
|
||
}
|
||
printf("\r\n");
|
||
}
|
||
|
||
static void test_interval(void)
|
||
{
|
||
int array_int[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // 先定义升序的数组
|
||
|
||
// 传入数组基地址,指定在[3, 7]区间内进行排序,指定int型的降序ops
|
||
sort_bubble(array_int, 3, 7, &sops_int_descend);
|
||
|
||
// 输出排序后的数组
|
||
for (int i = 0; i < sizeof(array_int)/sizeof(array_int[0]); i++)
|
||
{
|
||
printf("%d, ", array_int[i]);
|
||
}
|
||
printf("\r\n");
|
||
}
|
||
|
||
// 获取list数据项地址
|
||
static void* list_int_addr(void *array, int index)
|
||
{
|
||
return list_data((list_t)array, index);
|
||
}
|
||
|
||
// 交换list两个成员数据
|
||
static void list_int_swap(void *array, int index0, int index1)
|
||
{
|
||
int temp = list_at((list_t)array, int, index0);
|
||
list_at((list_t)array, int, index0) = list_at((list_t)array, int, index1);
|
||
list_at((list_t)array, int, index1) = temp;
|
||
}
|
||
|
||
// 显示list存储的数据
|
||
static void list_int_show(list_t list)
|
||
{
|
||
for (int i = 0; i < list_size(list); i++)
|
||
{
|
||
printf("%d, ", list_at(list, int, i));
|
||
}
|
||
printf("\r\n");
|
||
}
|
||
|
||
static void test_list_sort(void)
|
||
{
|
||
list_t list = list(int); // 定义一个int型的list
|
||
SOPS ops; // 定义一个新的ops
|
||
int array[] = {1, 3, 6, 5, 0, 2, 9, 8, 7, -4}; // 定义要给list装载的数据
|
||
|
||
// 将数据装载到list
|
||
for (int i = 0; i < sizeof(array)/sizeof(array[0]); i++)
|
||
{
|
||
list_push_back(list, &array[i]);
|
||
}
|
||
|
||
ops.order = sops_int_ascend.order; // 复用int升序规则
|
||
ops.addr = list_int_addr; // 使用list获取元素的地址
|
||
ops.swap = list_int_swap; // list交换数据
|
||
|
||
// 输出排序前的list
|
||
list_int_show(list);
|
||
|
||
// 进行排序
|
||
sort_bubble(list, 0, list_size(list) - 1, &ops);
|
||
|
||
// 输出排序后的list
|
||
list_int_show(list);
|
||
|
||
// 释放list
|
||
_list(list);
|
||
}
|
||
|
||
typedef struct
|
||
{
|
||
char *name;
|
||
int age;
|
||
char gender; /* 1 表示男,0 表示女 */
|
||
float weight;
|
||
} STUDENT;
|
||
|
||
static void student_print(STUDENT *s, int size)
|
||
{
|
||
for (int i = 0; i < size; i++)
|
||
{
|
||
printf("name: %s, \t\t age = %d, \t\t gender = %d, \t\t weight = %.2f\r\n", s[i].name, s[i].age, s[i].gender, s[i].weight);
|
||
}
|
||
}
|
||
|
||
static void* student_addr(void *array, int index)
|
||
{
|
||
return ((STUDENT *)array) + index;
|
||
}
|
||
|
||
static void student_swap(void *array, int index0, int index1)
|
||
{
|
||
STUDENT temp = ((STUDENT *)array)[index0];
|
||
((STUDENT *)array)[index0] = ((STUDENT *)array)[index1];
|
||
((STUDENT *)array)[index1] = temp;
|
||
}
|
||
|
||
static int student_name_ascend(void *front, void *back)
|
||
{
|
||
return -strcmp(((STUDENT *)front)->name, ((STUDENT *)back)->name);
|
||
}
|
||
|
||
static int student_gender_descend(void *front, void *back)
|
||
{
|
||
if (((STUDENT *)front)->gender > ((STUDENT *)back)->gender) return 1;
|
||
else if (((STUDENT *)front)->gender < ((STUDENT *)back)->gender) return -1;
|
||
else return 0;
|
||
}
|
||
|
||
static int student_age_descend(void *front, void *back)
|
||
{
|
||
if (((STUDENT *)front)->age > ((STUDENT *)back)->age) return 1;
|
||
else if (((STUDENT *)front)->age < ((STUDENT *)back)->age) return -1;
|
||
else return 0;
|
||
}
|
||
|
||
static int student_weight_ascend(void *front, void *back)
|
||
{
|
||
if (((STUDENT *)front)->weight < ((STUDENT *)back)->weight) return 1;
|
||
else if (((STUDENT *)front)->weight > ((STUDENT *)back)->weight) return -1;
|
||
else return 0;
|
||
}
|
||
|
||
static void test_struct(void)
|
||
{
|
||
SOPS ops;
|
||
STUDENT table[] = {
|
||
{"ZhanSan", 18, 1, 56.3},
|
||
{"LiSi", 17, 1, 62.2},
|
||
{"WangWu", 21, 0, 58.9},
|
||
{"ZhaoLiu", 22, 1, 65.5},
|
||
{"SunQi", 18, 1, 71.7},
|
||
{"ZhouBa", 30, 0, 48.8},
|
||
{"WuJiu", 16, 1, 56.3},
|
||
{"ZhenShi", 19, 0, 52.1},
|
||
};
|
||
|
||
ops.addr = student_addr;
|
||
ops.swap = student_swap;
|
||
|
||
// 指定为按照名字升序排序
|
||
ops.order = student_name_ascend;
|
||
sort_bubble(table, 0, sizeof(table)/sizeof(table[0])-1, &ops);
|
||
printf("sorting by name in ascending order\r\n");
|
||
student_print(table, sizeof(table)/sizeof(table[0]));
|
||
printf("---------------------------------\r\n");
|
||
|
||
// 指定为按照年龄降序排序
|
||
ops.order = student_age_descend;
|
||
sort_bubble(table, 0, sizeof(table)/sizeof(table[0])-1, &ops);
|
||
printf("sorting by age in descending order\r\n");
|
||
student_print(table, sizeof(table)/sizeof(table[0]));
|
||
printf("---------------------------------\r\n");
|
||
|
||
// 指定为按照性别降序排序
|
||
ops.order = student_gender_descend;
|
||
sort_bubble(table, 0, sizeof(table)/sizeof(table[0])-1, &ops);
|
||
printf("sorting by gender in descending order\r\n");
|
||
student_print(table, sizeof(table)/sizeof(table[0]));
|
||
printf("---------------------------------\r\n");
|
||
|
||
// 指定为按照体重升序排序
|
||
ops.order = student_weight_ascend;
|
||
sort_bubble(table, 0, sizeof(table)/sizeof(table[0])-1, &ops);
|
||
printf("sorting by weight in ascending order\r\n");
|
||
student_print(table, sizeof(table)/sizeof(table[0]));
|
||
printf("---------------------------------\r\n");
|
||
}
|
||
|
||
static void test_base(void)
|
||
{
|
||
// test_basic_usage();
|
||
// test_interval();
|
||
// test_list_sort();
|
||
test_struct();
|
||
}
|
||
|
||
/************************************************************************************/
|
||
/************************************* Command ************************************/
|
||
/************************************************************************************/
|
||
|
||
static void usage(void)
|
||
{
|
||
printf(
|
||
"Usage: sort [opt] [arg] ...\n"
|
||
"\n"
|
||
"options:\n"
|
||
" -e <execute> Specifies the function to execute, the default is the <base> test\n"
|
||
" <base> Test base function\n"
|
||
" <ut> Unit test\n"
|
||
" -h Print help\n"
|
||
" -v Print version\n"
|
||
" -u [<period>] Unit test period, unit ms, the default is 1000ms\n"
|
||
"\n"
|
||
|
||
);
|
||
}
|
||
|
||
static int test(int argc, char *argv[])
|
||
{
|
||
char *execute = NULL;
|
||
int ut_period = 1000;
|
||
|
||
/* reset getopt */
|
||
command_opt_init();
|
||
|
||
while (1)
|
||
{
|
||
int opt = command_getopt(argc, argv, "e:hvu::");
|
||
if (opt == -1) break;
|
||
|
||
switch (opt)
|
||
{
|
||
case 'u' :
|
||
if (command_optarg) ut_period = atoi(command_optarg);
|
||
break;
|
||
case 'e' :
|
||
execute = command_optarg;
|
||
break;
|
||
case 'v' :
|
||
printf("sort version %d.%d.%d\r\n", SORT_V_MAJOR, SORT_V_MINOR, SORT_V_PATCH);
|
||
return 0;
|
||
case '?':
|
||
printf("Unknown option `%c`\r\n", command_optopt);
|
||
return -1;
|
||
case 'h' :
|
||
default:
|
||
usage();
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
if (execute)
|
||
{
|
||
if (!strcmp(execute, "base"))
|
||
{
|
||
test_base();
|
||
}
|
||
else if (!strcmp(execute, "ut"))
|
||
{
|
||
srand((unsigned int)time(NULL));
|
||
#if defined(TEST_TARGET_sort)
|
||
while (1)
|
||
{
|
||
unitt_task();
|
||
usleep(1000 * ut_period);
|
||
}
|
||
#else
|
||
printf("create task %d\r\n", task_create(ut_period, unitt_task));
|
||
#endif
|
||
}
|
||
}
|
||
else
|
||
{
|
||
test_base();
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
/************************************************************************************/
|
||
/************************************ Test entry ************************************/
|
||
/************************************************************************************/
|
||
|
||
#if defined(TEST_TARGET_sort)
|
||
int main(int argc, char *argv[])
|
||
{
|
||
return test(argc, argv);
|
||
}
|
||
#else
|
||
void test_sort(void)
|
||
{
|
||
command_export("sort", test);
|
||
}
|
||
init_export_app(test_sort);
|
||
#endif
|
||
|
||
|