- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在 Xcode 中遇到一些奇怪的错误 - 线程 1:在下面的代码段中的 EXC_BAD_ACCESS
while(*w1 != '\0' && *w2 != '\0')
这里是快速排序的实现和比较方法:
void quicksort(char ***words, int start, int end){ //start is pivot
if(start >= end){
return;
}
int left = start;
int right = end;
int comp;
while( left <= right ){
do{
char* w1 = (*words)[++left];
char* w2 = (*words)[start];
comp = compare(w1, w2);
}while(comp < start); //while current left less than pivot
do{
char* w1= (*words)[--right];
char* w2= (*words)[start];
comp = compare(w1, w2);
}while(comp >= start); //while current right is more or equal to pivot
if(left < right){
swap(words, left, right);
}
}
swap(words, start, --left);
quicksort(words, 0, left-1);
quicksort(words, left+1, end);
}
int compare(char *w1, char *w2){
while(*w1 != '\0' && *w2 != '\0'){
if( *w1 < *w2 ){
return -1;
}else if( *w1 > *w2 ){
return 1;
}else{
w1++;
w2++;
}
}
if(*w1 == *w2)
return 0;
else if(*w1 == '\0')
return -1;
else return 1;
}
这是完整代码 http://ideone.com/MZFaFO
我假设问题的原因可能在 do-while 之间。我用指针做的很糟糕..我将非常感谢你的帮助。我刚开始学习 C,它完全杀死了我。 :(
最佳答案
有很多错误(稍后会详细介绍),但我必须以这个开头:
不要为快速排序实现传递右/左索引标记。你不需要它们,它们给通用算法带来的复杂性是不值得的。这是 C。这样你就可以免费进行指针运算。用它; Revel 其中。这样一来,您的算法就减少到一个完成偏移魔术的地方。剩下的就变得微不足道了。
但首先,从您的比较器开始,进行一些一般性的内务处理。这是否更简单,由您来判断:
int compare(char const *w1, char const *w2)
{
while(*w1 && *w2)
{
if (*w1 < *w2)
return -1;
if (*w2++ < *w1++)
return 1;
}
return *w2 ? -1 : (*w1 != 0);
}
这里唯一值得一提的是最后一个子句,它说:“如果我们完成 w2
仍然指向某物,它必须比 w1
长,所以 w1
是“less”,我们返回 -1。否则,w2
必须在字符串末尾,所以如果 w1
是,则返回 1不是(因此“更大”),否则返回 0(它们都在字符串末尾)。
关于 swap
元素。您所做的只是交换指针数组中的指针 值(地址)。因此……
void swap_ptrs(char **lhs, char **rhs)
{
char *tmp = *lhs;
*lhs = *rhs;
*rhs = tmp;
}
关于您的问题的实质(有多个)。首先,您到底想用这个完成什么:
do{
char* w1 = (*words)[++left];
char* w2 = (*words)[start];
comp = compare(w1, w2);
}while(comp < start)
start
是指针数组的索引,comp
是比较的结果。它不返回索引,它返回 -1
、0
或 1
。他们之间确实没有关系。同样的问题发生在你的第二个 while 循环中。此外,您正在递增 left
(并在另一个循环中递减 right
)过早地。简而言之,这根本无法快速排序
。
利用前面提到的指针数学以及提供的比较器和交换例程,这是一种对相关分区进行快速排序的方法。请注意,我们只需要两个参数:数组的基地址和我们希望排序的序列的长度。递归使用指针算法在需要时提供正确的起点和长度。
void quicksort(char **words, size_t len)
{
if (len < 2)
return;
char const *pvt = words[len/2];
size_t lhs = 0, rhs=len-1;
while( lhs < rhs )
{
while (compare(words[lhs], pvt) < 0)
++lhs;
while (compare(words[rhs], pvt) > 0)
--rhs;
if (lhs <= rhs)
swap_ptrs(words+lhs++, words+rhs--);
}
quicksort(words, rhs+1);
quicksort(words+lhs, len-lhs);
}
为了测试这个,一个简单的 random-string-generationg 实现:
int main()
{
srand((unsigned int)time(NULL));
// allocate a string bed of 100 pointers
static const size_t len = 100;
char **arr = malloc(sizeof(*arr) * len);
// populate with random strings ranging from 5 to 8 chars.
for (size_t i=0; i<len; ++i)
{
int siz = 5 + rand() % 4;
arr[i] = malloc(siz+1);
for (size_t j=0; j<siz; ++j)
arr[i][j] = 'A' + rand() % 26;
arr[i][siz] = 0;
}
quicksort(arr, len);
for (size_t i=0; i<len; ++i)
{
printf("%s\n", arr[i]);
free(arr[i]);
}
free(arr);
}
输出(显然不同)
ARSXTGA
ATQYX
BCFNHSN
BEDYEW
BGTYDCK
BSYNEB
BYQXH
BYXVID
CHXQVEVG
CLRLYLO
DEXTPQO
DXHAIP
ECLMAD
EPYCQJ
EPZGNCG
EUUWTXOI
FEABB
FFMCTK
FYOIIKX
FZQWIQ
GDDUOMO
GFJNWEKP
GGMHDPA
GQMSEU
HTPCU
HULIENC
IGNHGIMM
ITFPMUAM
IYHBOWJ
IYTDAOEE
JEQVXRZ
JMUCWRV
JUDMWMS
KHVKN
KJOJXNL
KQIVURG
KVIGK
KVUYIER
LACVY
LCEKGER
LGELOIY
MILDEFJI
MNZDX
MOBOAPYL
MOLDKACO
MUJXDGH
NDZZLRQD
NEZTSBPC
NLDHM
OAZSW
OLPKKL
OZOBK
PBIOISM
PCYHNYQ
PEZMH
PFWEJQI
PIXNQ
PZATCAIK
QJUYGNID
QKGDXI
QLGORE
QULGW
RBEDK
ROYSAPGH
RQTVMO
RTBGDBXM
SLHUOE
SLTBOETM
SNRIGY
SRBPOF
STGPU
STUOQ
SXZFPRR
TBRFT
TELZYQ
TJKWLLE
TKLSNN
TNATOPFQ
UJXGWM
UNQZSF
VCLZUWSV
VPJVAEP
WBVBY
WDVWTEF
WEPRL
WFTJSFIQ
WUIJQS
WWPOAQQ
XLASZMI
XOQTSPZ
XQZZSZ
YFHXA
YFXMKAC
YPPUC
YRLVS
YTGHWVU
YWXOWXL
ZLVTUL
ZUNMCE
ZUUQZXLX
关于c - 需要帮助查找 C 中快速排序实现错误的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24874209/
我对cassandra并使用1.2.10非常陌生。我有一个时间戳数据类型的主键列。现在,我正在尝试检索日期范围的数据。由于我们知道不能在cassandra中使用,因此我使用的是大于()来获取日期范围。
我正在尝试进行有条件的转场。但我得到: Terminating app due to uncaught exception 'NSInvalidArgumentException', reas
我有一个游戏项目,在调试和发布模式下在设备上运行得非常好。我有两个版本。旧版本和新版本具有更多(后来我添加了)功能,并且两者的 bundle ID、版本相同。当我构建旧版本时,之前没有安装“myGam
这个问题已经有答案了: 奥 git _a (2 个回答) 已关闭 5 年前。 我正在获取 ClassCastException 。这两个类来自不同的 jar,但是JettyContinuationPr
以下代码行抛出异常: HttpResponse response = client.execute(request); // actual HTTP request 我能够捕获它并打印: Log
就目前情况而言,这个问题不太适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、民意调查或扩展讨论。如果您觉得这个问题可以改进并可能重新开放,visit
public class TwoThreads { private static Object resource = new Object(); private static void
当我输入 6 (int) 作为值时,运行此命令会出现段错误 (gcc filename.c -lm)。请帮助我解决这个问题。预期的功能尚未实现,但我需要知道为什么我已经陷入段错误。 谢谢! #incl
所以,过去一周半我一直在研究这个 .OBJ/.MTL 网格解析器。在这段时间里,我一直在追踪/修复很多错误、清理代码、记录代码等等。 问题是,每修复一个错误,仍然会出现这个问题,而且一张图片胜过一千个
我正在运行一个代码,它基本上围绕 3 个维度旋转一个大数据数组(5000 万行)。但是,我遇到了一个奇怪的问题,我已将其缩小到如何评估旋转矩阵。基本上,对于除绕 x 轴以外的任何旋转,python 代
就在你说这是重复之前,我已经看到了其他问题,但我仍然想发布这个。 所以我正在阅读 Thinking in Java -Bruce Eckel 这篇文章是关于小写命名约定的: In Java 1.0 a
我想在我的应用程序中使用 REST API。它为我从这个应用程序发出的所有请求抛出 SocketTimeoutException。 Logcat 输出:(您也可以在此处看到带有漂亮格式的输出:http
我知道 raise ... from None 并已阅读 How can I more easily suppress previous exceptions when I raise my own
在未能找到各种Unix工具(例如xargs和whatnot)的最新独立二进制文件(this version很好,但需要外部DLL)后,我承担了自己进行编译的挑战。 ...这是痛苦的。 最终,尽管如此,
我有一个用PHP编写的流套接字服务器。 为了查看一次可以处理多少个连接,我用C语言编写了一个模拟器来创建1000个不同的客户端以连接到服务器。 stream_socket_accept几次返回fals
我的Android Studio昨天运行良好,但是今天当我启动Android Studio并想在移动设备上运行应用程序时,发生了以下错误, 我在互联网和stackoverflow上进行了搜索,但没有解
默认情况下,grails似乎为Java域对象的toString()返回:。那当然不是我想要的,所以我尝试@Override toString()返回我想要的。当我尝试grails generate-a
尝试通过LDAP通过LDAP对用户进行身份验证时,出现以下错误。 Reason: Cannot pass null or empty values to constructor. 谁能告诉我做错了什么
我正在尝试使用应用程序附带的 Houdini Python 模块,该模块是 Houdini 安装文件夹的一部分,位于标准 Python 路径之外。按照安装说明操作后,运行 Houdini Termin
简单地说,我正在为基本数据库编写单链表的原始实现。当用户请求打印索引下列出的元素高于数据库中当前记录数量时,我不断出现段错误,但仅当差值为 1 时。对于更高的数字,它只会触发我在那里编写的错误系统。
我是一名优秀的程序员,十分优秀!