varch/test/test_sort.c

371 lines
10 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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