我有这个问题:
我有一个程序,计算两个算法(shellsort和插入排序)的执行时间,每个算法分别在三个不同的数组(最有利的情况,最不利的情况和随机的情况),所以基本上我需要做一个相同的功能东西六次(shell排序最有利的情况,shell排序最不利的情况和shell排序随机的情况下,和插入排序相同的东西)但我不想复制和粘贴代码六次,并且一个函数与六个案例并不高效。所以我试图理解功能指针,但我不知道如何在那里使用它。这是我的代码:
void testInsMostUnfavorableCase()
{
int i,j,n=500,K=1000,p=0;
double c,d,t1,t2,t;
printf("Insertion sort on most unfavorable case\n");
printf("%9s%20s%12s%12s%12s\n", "n","t(n)","t(n)/n^0.8","t(n)/n","t(n)/nlogn");
for(i=1;i<8;i++)
{
int v[n];
descending(v,n); //THERE
c=microseconds();
ins_sort(v,n); //THERE
d=microseconds();
t=d-c;
if(t<500) /*times <500ms */
{
p=1;
c=microseconds();
for(j=0;j<K;j++)
{
descending(v,n); //THERE
ins_sort(v,n); //THERE
}
d=microseconds();
t1=d-c;
c=microseconds();
for(j=0;j<K;j++)
descending(v,n); //THERE
d=microseconds();
t2=d-c;
t=(t1-t2)/K;
printf("%3s%6d%20.3f%12f%12f%12f\n","(*)",n,t,t/pow(n,0.8),t/n,t/(n*log(n)));
}
else
printf("%9d%20.3f%12f%12f%12f\n",n,t,t/pow(n,0.8),t/n,t/(n*log(n)));
n=n*2;
}
if(p==1)
printf("%s%d%s\n","*: Average time (in microseconds) of ",K," algorithm executions." );
}
void testInsMostFavorableCase() {...}
void testInsRandomCase() {...}
void testShellMostUnfavorableCase() {...}
void testShellMostFavorableCase() {...}
void testShellRandomCase() {...}
问题是我必须重复六次才能使用THERE更改注释行。你有任何其他解决方案使用功能指针吗?
答案 0 :(得分:1)
我不想复制和粘贴代码六次
然后不要。这三个测试用例仅因输入数据而不同 - &gt;
benchmarkInsertionSort( int[] data, int dataSize)
每个算法 每个算法
benchmarkInsertionSort(dataset1, 500);
benchmarkInsertionSort(dataset2, 500);
benchmarkInsertionSort(dataset3, 500);
在您的代码中,将每个测试运行的设置(例如int v[n]; descending(v,n);
)与要测试的实际操作分开。
如果你真的想,你可以使用函数指针使基准代码更通用:
// Define a type for a pointer to a void function with two arguments (int[],int):
typedef void (*sort_function_t)(int[] data, int size);
// A function compatible with the pointer type above:
void ins_sort( int[] data, int size ) {
...
}
// Another function compatible with the pointer type above:
void shell_sort( int[] data, int size ) {
...
}
void benchmarkSortAlgo( sort_function_t sortFunction, int[] data, int dataSize ) {
...
// Call the function pointed to by the sortFuntion parameter:
sortFunction(data,dataSize);
...
}
...
// Pass pointers to the sort function to the benchmark.
// Note that we get the pointer to a function by just using 'functionname' without any parenthesis!
benchmarkSortAlgo( ins_sort, testData1, 500 );
benchmarkSortAlgo( shell_sort, testData2, 500 );
...
答案 1 :(得分:0)
它遵循一个例子,编译从中获得灵感。 它完全基于您的代码,因此它仍然需要更改,因为我只添加了指向 THERE 标记的函数的指针。
#include <stdio.h>
#include <math.h>
typedef void(*fnptr)(int*, int);
void test(
fnptr descending_ptr,
fnptr ins_sort_ptr
)
{
int i,j,n=500,K=1000,p=0;
double c,d,t1,t2,t;
printf("%9s%20s%12s%12s%12s\n", "n","t(n)","t(n)/n^0.8","t(n)/n","t(n)/nlogn");
for(i=1;i<8;i++)
{
int v[n];
descending_ptr(v,n); //THERE
c=microseconds();
ins_sort_ptr(v,n); //THERE
d=microseconds();
t=d-c;
if(t<500) /*times <500ms */
{
p=1;
c=microseconds();
for(j=0;j<K;j++)
{
descending_ptr(v,n); //THERE
ins_sort_ptr(v,n); //THERE
}
d=microseconds();
t1=d-c;
c=microseconds();
for(j=0;j<K;j++)
descending_ptr(v,n); //THERE
d=microseconds();
t2=d-c;
t=(t1-t2)/K;
printf("%3s%6d%20.3f%12f%12f%12f\n","(*)",n,t,t/pow(n,0.8),t/n,t/(n*log(n)));
}
else
printf("%9d%20.3f%12f%12f%12f\n",n,t,t/pow(n,0.8),t/n,t/(n*log(n)));
n=n*2;
}
if(p==1)
printf("%s%d%s\n","*: Average time (in microseconds) of ",K," algorithm executions." );
}
void test() { /* ... */ }
double microseconds() { return 0; }
void descendingInsMostFavorableCase(int*, int) { /* ... */ }
void insSortInsMostFavorableCase(int*, int) { /* ... */ }
int main() {
printf("Insertion sort on most favorable case\n");
test(&descendingInsMostFavorableCase, &insSortInsMostFavorableCase);
}
答案 2 :(得分:0)
鉴于问题的标题,这里有一些如何使用泛型编程的提示。那就是:如何在学术目的之外实现这些排序算法以供实际使用。
要将参数中的这些不同功能分解,您似乎需要以下内容:
如果要将排序算法作为函数的参数,首先需要标准化其格式。同时将它实现为可以接受任何类型的通用排序函数也是一个好主意。
为实现这一目标,您可以了解如何实现标准C库qsort
,以了解如何编写通用排序算法:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
base
是数据数组,nmemb
是对象数,size
是每个对象的大小,compar
是指向比较函数的函数指针。
应该实现比较函数,以便给定两个参数a
和b
,如果a > b
则返回正值,如果a < b
则返回负值0如果a == b
。因此对于有符号整数数据,该函数只包含一行return a - b;
。 (它的工作原理与strcmp,memcmp等完全相同。)
如果您使用编写排序函数的概念,则可以将比较函数键入:
typedef int compare_t (const void*, const void*);
然后,所有排序函数都将具有标准签名,例如:
void insertion_sort (void* base,
size_t n,
size_t obj_size,
compare_t* comp);
意思是你也可以输入那个函数签名:
typedef void sort_t (void* base,
size_t n,
size_t obj_size,
compare_t* comp);
然后你会得到一个基准函数,如:
void benchmark (sort_t* sort,
void* base,
size_t n,
size_t obj_size,
compare_t* comp)
{
// set up & start timer etc
sort(base, n, obj_size, comp);
// stop timer
// print results
}
最后,你的主要看起来像这样,例如整数:
benchmark(insertion_sort,
most_favourable, // this is an int array
sizeof(most_favourable) / sizeof(*most_favourable),
sizeof(int),
compare_int);
benchmark(insertion_sort,
random_case, // this is an int array
sizeof(random_case) / sizeof(*random_case),
sizeof(int),
compare_int);
等等。在调用者中,您可以创建大量具有不同数据,不同数据类型等的测试用例。