- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我需要使用通过省略号获取参数的通用函数对多个数组进行排序。
我尝试将所有元素放在一个数组中,对其进行排序,然后将结果推送到以下数组中。
这是函数的原型(prototype):
void gSortAll(int n, int m, int(*cmp)(void*,void*),void* base,...);
int n:每个数组中元素的个数。
int m:数组中每个元素的字节大小。
cmp:比较函数,用于比较特定类型。
void* base:第一个要排序的数组,后面是带省略号的其他数组,然后是 NULL。
假设我用这些数组调用函数:
int a[] = {17,2,7,8,1};
int b[] = {3,6,5,14,11};
int c[] = {12,9,10,1,4};
排序函数之后的数组应该是:
int a[] = {1,1,2,3,4};
int b[] = {5,6,7,8,9};
int c[] = {10,11,12,14,17};
我已经开始输入函数了:
int cmpInt(void *a, void *b) {
return *(int*)a > *(int*)b;
}
void swap(void* p, void* q, int size) {
char *pt = (char *)p;
char *qt = (char *)q;
char c;
while(size--) {
c = *pt;
*pt = *qt;
*qt = c;
pt++;
qt++;
}
}
void insert(void* from, void* to, int size) {
char *pt = (char *)from;
char *qt = (char *)to;
while(size--) {
*qt = *pt;
pt++;
qt++;
}
}
void sort(void* arr, int size, int sizeType, int(*f)(void *, void *)) {
int i,j;
for (i=0; i<size; i++) {
for (j=0; j<size-1; j++) {
if(f((char*)arr+j*sizeType,(char*)arr+j*sizeType+sizeType)>0) {
swap((char*)arr+j*sizeType,(char*)arr+j*sizeType+sizeType, sizeType);
}
}
}
}
// n: number of elements in array
// m: size in bytes of element
// cmp: compare function
// base: the first array
void gSortAll(int n, int m, int(*cmp)(void*,void*),void* base,...) {
void** arr = malloc(0);
int count = 0;
int i;
void* item;
va_list param;
va_start(param, base);
for(i=0;i<n;i++) {
arr = realloc(arr, m*(count+1));
arr[count] = (char*)base+i*m;
count++;
}
va_start(param, base);
while((item=va_arg(param, void*))!=NULL) {
for(i=0;i<n;i++) {
arr = realloc(arr, m*(count+1));
arr[count] = (char*)item+i*m;
count++;
}
}
va_end(param);
sort(arr, count, m, cmp);
va_start(param, base);
for(i=0;i<n;i++) insert(arr+i*m, base+i*m, m);
va_start(param, base);
while((item=va_arg(param, void*))!=NULL) {
for(i=0;i<n;i++) insert(arr+i*m, item+i*m, m);
}
va_end(param);
}
int main() {
int a[] = {17,2,7,8,1};
int b[] = {3,6,5,14,11};
int c[] = {12,9,10,1,4};
gSortAll(sizeof(a)/sizeof(a[0]), sizeof(a[0]), *cmpInt, a, b, c, NULL);
return 0;
}
任何帮助将不胜感激!
最佳答案
逐字使用您的 sort
代码(以及一些但不是所有的支持函数),这是 gSortAll()
的变体,其签名略有不同。它避免了显式的 void *base
参数,因此不必对其进行特殊处理。
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void sort(void *arr, int size, int sizeType, int (*f)(void *, void *));
/* Changed (simplified) function signature */
static void gSortAll(int n, int m, int (*cmp)(void *, void *), ...)
{
void *item;
va_list param;
/* How many arrays? */
va_start(param, cmp);
size_t num_arrays = 0;
while ((item = va_arg(param, void *)) != 0)
num_arrays++;
va_end(param);
if (num_arrays == 0)
return;
void *arr = malloc(num_arrays * n * m);
if (arr == 0)
return;
/* Copy data into allocated array */
va_start(param, cmp);
void *data = arr;
while ((item = va_arg(param, void *)) != 0)
{
memmove(data, item, n * m);
data = (char *)data + n * m;
}
va_end(param);
sort(arr, n * num_arrays, m, cmp);
/* Copy data from allocated array */
va_start(param, cmp);
data = arr;
while ((item = va_arg(param, void *)))
{
memmove(item, data, n * m);
data = (char *)data + n * m;
}
va_end(param);
free(arr);
}
static int cmpInt(void *a, void *b)
{
return *(int *)a > *(int *)b;
}
static void swap(void *p, void *q, int size)
{
char *pt = (char *)p;
char *qt = (char *)q;
char c;
while (size--)
{
c = *pt;
*pt = *qt;
*qt = c;
pt++;
qt++;
}
}
static void sort(void *arr, int size, int sizeType, int (*f)(void *, void *))
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size - 1; j++)
{
if (f((char *)arr + j * sizeType, (char *)arr + j * sizeType + sizeType) > 0)
{
swap((char *)arr + j * sizeType, (char *)arr + j * sizeType + sizeType,
sizeType);
}
}
}
}
/* Non-generic code */
static void dump_array(const char *tag, size_t size, int data[size])
{
printf("%s (%zu): ", tag, size);
for (size_t i = 0; i < size; i++)
printf("%5d", data[i]);
putchar('\n');
}
int main(void)
{
int a[] = {17, 2, 7, 8, 1};
int b[] = {3, 6, 5, 14, 11};
int c[] = {12, 9, 10, 1, 4};
printf("Before\n");
dump_array("A", 5, a);
dump_array("B", 5, b);
dump_array("C", 5, c);
gSortAll(sizeof(a) / sizeof(a[0]), sizeof(a[0]), *cmpInt,
(void *)a, (void *)b, (void *)c, (void *)NULL);
printf("After\n");
dump_array("A", 5, a);
dump_array("B", 5, b);
dump_array("C", 5, c);
/* random -n 12 10 99 | commalist -B 4 -w -W3 -n 12 -b 'int w[] = { ' -T ' };' */
int w[] = { 86, 86, 48, 40, 39, 29, 69, 71, 30, 15, 46, 19, };
int x[] = { 21, 43, 11, 85, 82, 81, 41, 46, 33, 32, 15, 43, };
int y[] = { 91, 19, 82, 33, 25, 83, 36, 85, 75, 65, 37, 57, };
int z[] = { 39, 61, 65, 83, 26, 82, 30, 81, 30, 34, 22, 82, };
printf("Before\n");
dump_array("W", 12, w);
dump_array("X", 12, x);
dump_array("Y", 12, y);
dump_array("Z", 12, z);
gSortAll(sizeof(w) / sizeof(w[0]), sizeof(w[0]), *cmpInt,
(void *)w, (void *)x, (void *)y, (void *)z, (void *)NULL);
printf("After\n");
dump_array("W", 12, w);
dump_array("X", 12, x);
dump_array("Y", 12, y);
dump_array("Z", 12, z);
return 0;
}
它使用 memmove()
— 如果您愿意,可以使用 memcpy()
— 将单独的数组复制到它创建的单个数组中,并复制排序后的数组数据返回到单独的数组。
示例输出:
Before
A (5): 17 2 7 8 1
B (5): 3 6 5 14 11
C (5): 12 9 10 1 4
After
A (5): 1 1 2 3 4
B (5): 5 6 7 8 9
C (5): 10 11 12 14 17
Before
W (12): 86 86 48 40 39 29 69 71 30 15 46 19
X (12): 21 43 11 85 82 81 41 46 33 32 15 43
Y (12): 91 19 82 33 25 83 36 85 75 65 37 57
Z (12): 39 61 65 83 26 82 30 81 30 34 22 82
After
W (12): 11 15 15 19 19 21 22 25 26 29 30 30
X (12): 30 32 33 33 34 36 37 39 39 40 41 43
Y (12): 43 46 46 48 57 61 65 65 69 71 75 81
Z (12): 81 82 82 82 82 83 83 85 85 86 86 91
在 Valgrind 的健康状况良好的情况下运行。
如果你绝对必须有 void *base
参数,那么你必须在代码中单独处理它,这很愚蠢,因为命名参数不会为函数的用户提供任何好处并且强加一些实现成本。
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void sort(void *arr, int size, int sizeType, int (*f)(void *, void *));
/* Changed (simplified) function signature */
static void gSortAll(int n, int m, int (*cmp)(void *, void *), void *base, ...)
{
void *item;
va_list param;
if (base == 0)
return;
/* How many arrays? */
va_start(param, base);
size_t num_arrays = 1; // base is counted too
while ((item = va_arg(param, void *)) != 0)
num_arrays++;
va_end(param);
void *arr = malloc(num_arrays * n * m);
if (arr == 0)
return;
/* Copy data into allocated array */
void *data = arr;
memmove(data, base, n * m);
data = (char *)data + n * m;
va_start(param, base);
while ((item = va_arg(param, void *)) != 0)
{
memmove(data, item, n * m);
data = (char *)data + n * m;
}
va_end(param);
sort(arr, n * num_arrays, m, cmp);
/* Copy data from allocated array */
data = arr;
memmove(base, data, n * m);
data = (char *)data + n * m;
va_start(param, base);
while ((item = va_arg(param, void *)))
{
memmove(item, data, n * m);
data = (char *)data + n * m;
}
va_end(param);
free(arr);
}
static int cmpInt(void *a, void *b)
{
return *(int *)a > *(int *)b;
}
static void swap(void *p, void *q, int size)
{
char *pt = (char *)p;
char *qt = (char *)q;
char c;
while (size--)
{
c = *pt;
*pt = *qt;
*qt = c;
pt++;
qt++;
}
}
static void sort(void *arr, int size, int sizeType, int (*f)(void *, void *))
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size - 1; j++)
{
if (f((char *)arr + j * sizeType, (char *)arr + j * sizeType + sizeType) > 0)
{
swap((char *)arr + j * sizeType, (char *)arr + j * sizeType + sizeType,
sizeType);
}
}
}
}
/* Non-generic code */
static void dump_array(const char *tag, size_t size, int data[size])
{
printf("%s (%zu): ", tag, size);
for (size_t i = 0; i < size; i++)
printf("%5d", data[i]);
putchar('\n');
}
int main(void)
{
int a[] = {17, 2, 7, 8, 1};
int b[] = {3, 6, 5, 14, 11};
int c[] = {12, 9, 10, 1, 4};
printf("Before\n");
dump_array("A", 5, a);
dump_array("B", 5, b);
dump_array("C", 5, c);
gSortAll(sizeof(a) / sizeof(a[0]), sizeof(a[0]), *cmpInt,
(void *)a, (void *)b, (void *)c, (void *)NULL);
printf("After\n");
dump_array("A", 5, a);
dump_array("B", 5, b);
dump_array("C", 5, c);
/* random -n 12 10 99 | commalist -B 4 -w -W3 -n 12 -b 'int w[] = { ' -T ' };' */
int w[] = { 86, 86, 48, 40, 39, 29, 69, 71, 30, 15, 46, 19, };
int x[] = { 21, 43, 11, 85, 82, 81, 41, 46, 33, 32, 15, 43, };
int y[] = { 91, 19, 82, 33, 25, 83, 36, 85, 75, 65, 37, 57, };
int z[] = { 39, 61, 65, 83, 26, 82, 30, 81, 30, 34, 22, 82, };
printf("Before\n");
dump_array("W", 12, w);
dump_array("X", 12, x);
dump_array("Y", 12, y);
dump_array("Z", 12, z);
gSortAll(sizeof(w) / sizeof(w[0]), sizeof(w[0]), *cmpInt,
(void *)w, (void *)x, (void *)y, (void *)z, (void *)NULL);
printf("After\n");
dump_array("W", 12, w);
dump_array("X", 12, x);
dump_array("Y", 12, y);
dump_array("Z", 12, z);
return 0;
}
此输出与之前相同。
有一个 previous version of this question (仅限 10K 用户)最终被混淆和删除(但它是由不同的用户 ID 提交的)。这是我为那个问题写的两个答案之一的扩展——两个是必要的,因为混淆。
关于C - 使用通用函数将多个数组作为一个数组排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51020102/
我正在尝试创建一个包含 int[][] 项的数组 即 int version0Indexes[][4] = { {1,2,3,4}, {5,6,7,8} }; int version1Indexes[
我有一个整数数组: private int array[]; 如果我还有一个名为 add 的方法,那么以下有什么区别: public void add(int value) { array[va
当您尝试在 JavaScript 中将一个数组添加到另一个数组时,它会将其转换为一个字符串。通常,当以另一种语言执行此操作时,列表会合并。 JavaScript [1, 2] + [3, 4] = "
根据我正在阅读的教程,如果您想创建一个包含 5 列和 3 行的表格来表示这样的数据... 45 4 34 99 56 3 23 99 43 2 1 1 0 43 67 ...它说你可以使用下
我通常使用 python 编写脚本/程序,但最近开始使用 JavaScript 进行编程,并且在使用数组时遇到了一些问题。 在 python 中,当我创建一个数组并使用 for x in y 时,我得
我有一个这样的数组: temp = [ 'data1', ['data1_a','data1_b'], ['data2_a','data2_b','data2_c'] ]; // 我想使用 toStr
rent_property (table name) id fullName propertyName 1 A House Name1 2 B
这个问题在这里已经有了答案: 关闭13年前。 Possible Duplicate: In C arrays why is this true? a[5] == 5[a] array[index] 和
使用 Excel 2013。经过多年的寻找和适应,我的第一篇文章。 我正在尝试将当前 App 用户(即“John Smith”)与他的电子邮件地址“jsmith@work.com”进行匹配。 使用两个
当仅在一个边距上操作时,apply 似乎不会重新组装 3D 数组。考虑: arr 1),但对我来说仍然很奇怪,如果一个函数返回一个具有尺寸的对象,那么它们基本上会被忽略。 最佳答案 这是一个不太理
我有一个包含 GPS 坐标的 MySQL 数据库。这是我检索坐标的部分 PHP 代码; $sql = "SELECT lat, lon FROM gps_data"; $stmt=$db->query
我需要找到一种方法来执行这个操作,我有一个形状数组 [批量大小, 150, 1] 代表 batch_size 整数序列,每个序列有 150 个元素长,但在每个序列中都有很多添加的零,以使所有序列具有相
我必须通过 url 中的 json 获取文本。 层次结构如下: 对象>数组>对象>数组>对象。 我想用这段代码获取文本。但是我收到错误 :org.json.JSONException: No valu
enter code here- (void)viewDidLoad { NSMutableArray *imageViewArray= [[NSMutableArray alloc] init];
知道如何对二维字符串数组执行修剪操作,例如使用 Java 流 API 进行 3x3 并将其收集回相同维度的 3x3 数组? 重点是避免使用显式的 for 循环。 当前的解决方案只是简单地执行一个 fo
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我有来自 ASP.NET Web 服务的以下 XML 输出: 1710 1711 1712 1713
如果我有一个对象todo作为您状态的一部分,并且该对象包含数组列表,则列表内部有对象,在这些对象内部还有另一个数组listItems。如何更新数组 listItems 中 id 为“poi098”的对
我想将最大长度为 8 的 bool 数组打包成一个字节,通过网络发送它,然后将其解压回 bool 数组。已经在这里尝试了一些解决方案,但没有用。我正在使用单声道。 我制作了 BitArray,然后尝试
我们的数据库中有这个字段指示一周中的每一天的真/假标志,如下所示:'1111110' 我需要将此值转换为 boolean 数组。 为此,我编写了以下代码: char[] freqs = weekday
我是一名优秀的程序员,十分优秀!