C K&;R |排序程序不';t在字符串中的下一个位置继续
很抱歉,又有一个关于K&R计划的问题打扰您。 但有些事情我还是不清楚。 下面的程序用于对readlines函数保存的行进行排序(真的保存了吗?),为此,我们创建了一个指向这些行的指针数组 问题: [1] 为什么我们要通过C K&;R |排序程序不';t在字符串中的下一个位置继续,c,pointers,qsort,kernighan-and-ritchie,C,Pointers,Qsort,Kernighan And Ritchie,很抱歉,又有一个关于K&R计划的问题打扰您。 但有些事情我还是不清楚。 下面的程序用于对readlines函数保存的行进行排序(真的保存了吗?),为此,我们创建了一个指向这些行的指针数组 问题: [1] 为什么我们要通过qsort(lineptr,0,nlines-1)我指的是nlines-1,而不仅仅是nlines [2] 假设我输入了两行: 好极了 阿尔法 现在,它们是从数组中指向的(我将进行可视化,这样就不会因为看到括号中的字符而生气;) *v[]=[lineptr[0]-指向布拉沃的指针
qsort(lineptr,0,nlines-1)代码>我指的是nlines-1,而不仅仅是nlines
[2] 假设我输入了两行:
好极了
阿尔法
现在,它们是从数组中指向的(我将进行可视化,这样就不会因为看到括号中的字符而生气;)
*v[]=[lineptr[0]-指向布拉沃的指针][lineptr[1]-指向阿尔法的指针]
根据算法:lineptr[0]是枢轴,所以我们交换它们;last=0;为循环输入-lineptr[1]的strcmp在词汇上不小于lineptr[0];递增i已经完成,所以我们退出循环。现在我们将last=0与left=0交换,所以什么也不会发生。它们已经就位了
但是,如果它们以同一个字母开头,例如abravo和alfa,那么如果qsort只从左到右操作数组的索引,表示不同的行数,而不是所检查字符串中的下一个字符,那么qsort将如何继续到下一个字母呢
请纠正我,因为那些指针快把我逼疯了
整个代码:
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* max #lines to be sorted */
char *lineptr[MAXLINES]; /* pointers to text lines */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int right);
/* sort input lines */
main()
{
int nlines;
/* number of input lines read */
if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {
qsort(lineptr, 0, nlines-1);
writelines(lineptr, nlines);
return 0;
} else {
printf("error: input too big to sort\n");
return 1;
}
}
#define MAXLEN 1000 /* max length of any input line */
int getline(char *, int);
char *alloc(int);
/* readlines: read input lines */
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
if (nlines >= maxlines || p = alloc(len) == NULL)
return -1;
else {
line[len-1] = '\0'; /* delete newline */
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}
/* writelines: write output lines */
void writelines(char *lineptr[], int nlines)
{
int i;
for (i = 0; i < nlines; i++)
printf("%s\n", lineptr[i]);
}
/* qsort: sort v[left]...v[right] into increasing order */
void qsort(char *v[], int left, int right)
{
int i, last;
void swap(char *v[], int i, int j);
if (left >= right) /* do nothing if array contains */
return;
/* fewer than two elements */
swap(v, left, (left + right)/2);
last = left;
for (i = left+1; i <= right; i++)
if (strcmp(v[i], v[left]) < 0)
swap(v, ++last, i);
swap(v, left, last);
qsort(v, left, last-1);
qsort(v, last+1, right);
}
#包括
#包括
#定义要排序的最大行数5000/*最大行数*/
char*lineptr[MAXLINES];/*指向文本行的指针*/
int readlines(char*lineptr[],int nlines);
无效写入线(字符*lineptr[],整数行);
void qsort(char*lineptr[],左整数,右整数);
/*对输入行排序*/
main()
{
国际在线;
/*读取的输入行数*/
如果((nlines=readlines(lineptr,MAXLINES))>=0){
qsort(lineptr,0,nlines-1);
写入线(行PTR、行nlines);
返回0;
}否则{
printf(“错误:输入太大,无法排序\n”);
返回1;
}
}
#定义MAXLEN 1000/*任何输入行的最大长度*/
int getline(字符*,int);
字符*alloc(int);
/*读取行:读取输入行*/
int readlines(char*lineptr[],int maxlines)
{
国际在线;
char*p,行[MAXLEN];
nlines=0;
而((len=getline(line,MAXLEN))>0)
如果(nlines>=maxlines | | p=alloc(len)==NULL)
返回-1;
否则{
行[len-1]='\0';/*删除换行符*/
strcpy(p,line);
lineptr[nlines++]=p;
}
返回在线;
}
/*写入线:写入输出线*/
无效写线(字符*lineptr[],整数行)
{
int i;
对于(i=0;i=右)/*如果数组包含*/
返回;
/*少于两个元素*/
交换(v,左,(左+右)/2);
最后=左;
for(i=left+1;istrcmp
比较两个字符串的字典顺序。这将考虑使用整个字符串进行比较,而不仅仅是第一个字符
参数right
取最右边索引的索引进行排序。如果数组长度为10,则第一个元素为0,最后一个元素为9(即10-1,即right-1
)。线索位于(i=left+1;i当stdlib中有一个函数被称为同一个函数,但有另一个签名时,您将函数命名为qsort有点令人困惑。+1@AndersK:他没有包含
,所以他可以使用标识符qsort
,不管他想要什么……但这是个坏主意(见K&R第108页)…因为稍后添加一个包含可能会以微妙的方式破坏以前的工作代码,这可能会让人非常困惑。远离标准定义的标识符。同意,这是一个坏主意,特别是因为stdlib是一个非常标准的库。但他实现它只是为了课本作业,如果他我想写一些‘真实’的东西,他会使用stdlib的快速排序。非常感谢!你能检查一下我写的文本是否正确吗?“*v[]==[lineptr[0]-指向bravo的指针][lineptr[1]-指向alfa的指针]根据算法:lineptr[0]是枢轴,所以我们交换它们;last=0;输入for循环:strcmp of-lineptr[1]在词汇上不小于lineptr[0];递增i已经完成,因此我们退出循环。”“我很好奇指针数组中的行是如何标记的,因为在交换之后,我确信我们不能这样命名lineptr[1],因为if现在在数组中的位置[0]