这来自我正在使用的"神奇"数组库.
void
sort(magic_list *l, int (*compare)(const void **a, const void **b))
{
qsort(l->list, l->num_used, sizeof(void*),
(int (*)(const void *,const void *))compare);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:究竟什么是qsort做的最后一个论点?
(int (*)(const void *, const void*))compare)
Run Code Online (Sandbox Code Playgroud)
qsort采用int (*comp_fn)(const void *,const void *)比较器参数,但此sort函数采用带双指针的比较器.不知何故,上面的行将双指针版本转换为单指针版本.有人可以解释一下吗?
以下是我的代码,Qsort产生奇怪的结果:
#include <stdio.h>
#include <stdlib.h>
char values[] = { 0x02,0x04,0x0b,0x16,0x24,0x30,0x48,0x6c};
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main ()
{
int i;
qsort (values, 8, sizeof(char), compare);
for (i = 0; i < 8; i++)
{
printf ("%0x ",values[ i ]);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这个程序的输出是:
虽然它应该与输入相同.有人可以解释为什么会这样,以及我如何纠正它?
在C++中,qsort()标准库提供了两个版本:
extern "C" void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
extern "C++" void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));
Run Code Online (Sandbox Code Playgroud)
bsearch() 差不多.
我的问题是,调用时重载解析如何工作qsort()?它是否根据作为最后一个参数传递的函数指针的链接类型("C"或"C++")自动链接到相应的函数?或者调用者需要使用某种额外的语法明确指定?
(让我们放下诱惑,呼唤std::sort一秒......)
我只是在golang中进行排序,我在stackoverflow上找到了一个qsort函数.它的运行速度似乎是golang中本机排序函数的两倍.我尝试过不同的输入尺寸并测试它的工作原理.
谁能解释为什么会这样?
以下是您可以在PC上测试的代码:
package main
import (
"fmt"
"math/rand"
"sort"
"time"
)
func qsort(a []int) []int {
if len(a) < 2 {
return a
}
left, right := 0, len(a)-1
// Pick a pivot
pivotIndex := rand.Int() % len(a)
// Move the pivot to the right
a[pivotIndex], a[right] = a[right], a[pivotIndex]
// Pile elements smaller than the pivot on the left
for i := range a {
if a[i] < a[right] {
a[i], a[left] = a[left], a[i]
left++
}
} …Run Code Online (Sandbox Code Playgroud) 我为一个结构写了一个(qsort兼容的)比较函数,里面有一些无符号字段:
typedef struct {
int a;
unsigned b;
} T;
int cmp(T t1, T t2)
{
// Decreasing order in "a"
if (t1.a < t2.a) return +1;
if (t1.a > t2.a) return -1;
// Increasing order in "b"
if (t1.b < t2.b) return -1;
if (t1.b > t2.b) return +1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法编写这个函数,而不需要每个字段进行两次比较?我不能使用这个t1.b - t2.b技巧,因为无符号整数的减法包装.
我愿意接受使用GCC扩展的答案.
我正在制作C动态数组库,有点像.请注意,我在空闲时间这样做是为了好玩,所以请不要推荐数百万现有的库.
我开始实施排序.该数组具有任意元素大小,定义为struct:
typedef struct {
//[PRIVATE] Pointer to array data
void *array;
//[READONLY] How many elements are in array
size_t length;
//[PRIVATE] How many elements can further fit in array (allocated memory)
size_t size;
//[PRIVATE] Bytes per element
size_t elm_size;
} Array;
Run Code Online (Sandbox Code Playgroud)
我最初准备这个以sort函数开始:
/** sorts the array using provided comparator method
* if metod not provided, memcmp is used
* Comparator signature
* int my_comparator ( const void * ptr1, const void * ptr2, size_t type_size …Run Code Online (Sandbox Code Playgroud) 如何长的双打比较
qsort(),并就不是一个数?
在排序可能包含非数字的数组时,我想将所有这些放在NAN已排序数组的一端.
qsort() 对比较功能施加了一些限制.
如果第一个参数被认为分别小于,等于或大于第二个参数,则该函数应返回小于,等于或大于零的整数.
C11dr§7.22.5.23当相同的对象...不止一次传递给比较函数时,结果应该彼此一致.也就是说,因为
qsort它们应该在数组上定义一个总排序,......同一个对象应始终以相同的方式与密钥进行比较.
§7.22.54
a > b当a <= b或如果a不是数字或b不是数字时,则为false .所以a > b是不一样的!(a <= b),因为他们有相反的结果,如果他们中的一个是NaN.
如果比较函数使用return (a > b) - (a < b);,代码将返回0,如果一个或两个 a或是bNaN.数组不会按照需要排序,它会丢失总排序要求.
在long double使用分类功能,如当这种方式是很重要的int isnan(real-floating x);或int isfinite(real-floating x);.我知道isfinite( finite_long_double_more_than_DBL_MAX)可能会回归虚假.所以我担心isnan(some_long_double)会发生什么意外的事情.
我试过以下.它显然按需要排序.
子问题:是否compare() …
我正在对quicksort(来自c++ STL的qsort)算法进行分析,代码为:
#include <iostream>
#include <fstream>
#include <ctime>
#include <bits/stdc++.h>
#include <cstdlib>
#include <iomanip>
#define MIN_ARRAY 256000
#define MAX_ARRAY 1000000000
#define MAX_RUNS 100
using namespace std;
int* random_array(int size) {
int* array = new int[size];
for (int c = 0; c < size; c++) {
array[c] = rand()*rand() % 1000000;
}
return array;
}
int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main()
{
ofstream fout;
fout.open("data.csv");
fout << "array size,";
srand(time(NULL));
int size; …Run Code Online (Sandbox Code Playgroud) 编写一个程序,在Mac上用C++演示不同的排序算法.我找到了两个quicksort实现,qsort和qsort_b.
第一个当然是老式的,随处可见的qsort.但是有qsort_b,它采用块而不是函数.这是我的代码:
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdio>
#include <ctime>
#define DATA 1000000
using namespace std;
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b;
}
int main(int argc, char *argv[])
{
int* array = new int[DATA];
srand(time(0));
for ( int i = 0 ; i < DATA ; ++ i )
{
array[i] = rand() % 2147483647;
}
clock_t begin = clock();
qsort(array, DATA, sizeof(array[0]), compare);
//qsort_b(array, DATA, sizeof(array[0]), ^(const void* a, const void* …Run Code Online (Sandbox Code Playgroud) 我想使用qsort函数使用C++对字符串中的字符进行排序.
#include<iostream>
#include<string>
#include<cstdlib>
using namespace std;
int compare_str(void const *a,void const *b){
char const *aa=(char const *)a;
char const *bb=(char const *)b;
if(*aa==*bb) return 0;
else if(*aa>*bb) return 1;
else return -1;
}
int main(){
string str="cake";
int len=str.length();
qsort(str,len,sizeof(str[0]),compare_str);
cout<<str;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但它抛出:
20 42 [Error] cannot convert 'std::string {aka std::basic_string<char>}' to 'void*' for argument '1' to 'void qsort(void*, size_t, size_t, int (*)(const void*, const void*))'
Run Code Online (Sandbox Code Playgroud)
如果有人能提供一种有效的方法来做到这一点会很棒.