C算法-QSORT&BSEARCH

leetcode139题,单词拆分。
思路是按照之前博客提到的老思路来的,贪心/回溯/剪枝(最后还是会超时的,放弃了)。有个bug是我不会对char **长相的内容处理快排。如下仔细讲解,参考大牛的帖子,帖子无法粘贴。
leetcode820题。单词的压缩编码。对单词按照需要的想法完成compare函数进行排序。

int (*compare)(const void , const void))
void qsort(void *base, size_t nitems, size_t size,

1、对一维数组快排
qsort入参(整个数组起始地址,数组大小,数组每个元素大小,快排功能)
comp函数(转化为int的指针,取指针的值)

注意:对double类型的数组排序,需要 return *(double *)b - *(double *)a ? 1 : -1

int mycmp(const void *a1,const void *a2) {  
	return *(int *)a2 -  *(int *)a1; //降序 
}  
int data[10]= {2,4,5,8,1,3,9,4,6,10};
qsort(data,10,sizeof(int),mycmp); 

2、对二维数组快排,与一维类似,其实就是个一维连续的,但是size需要扩充
qsort入参(整个数组起始地址,二维数组大小(3*10),数组每个元素大小,快排功能)
comp函数(转化为int的指针,取指针的值)

int mycmp(const void *a1,const void *a2) {  
	return *(int *)a2 -  *(int *)a1; //降序 
}  
int data[3][10]= {{2,14,5,58,1,23,39,14,6,210},{22,34,5,18,1,73,9,4,66,10},{2,4,35,8,21,36,9,44,6,110}};  
qsort(data,3*10,sizeof(int),mycmp);

我们可以看到aa的地址是连续的
在这里插入图片描述

3、对指向指针的指针数组快排
qsort入参(整个数组起始地址,数组大小,数组每个元素大小,快排功能)
comp函数(转化为char**的指针,取指针的值)

int Comp(const void *a, const void *b) {
	char * aa = *(char **)a;
	char * bb = *(char **)b;
	return strlen(bb) - strlen(aa);
}
qsort(wordDict, wordDictSize, sizeof(char*), Comp);


/*PS.刚leetcode820就用类似的方法做了,激动。如下*/
int Comp(const void *a, const void *b) {
	char *aa = *(char**)a;
	char *bb = *(char**)b;
	int tmp1 = strlen(aa);
	int tmp2 = strlen(bb);

	while (tmp1 != 0 && tmp2 != 0) {
		if (aa[tmp1 - 1] != bb[tmp2 - 1]) {
			return aa[tmp1 -1] - bb[tmp2 - 1];
		}
		tmp1 --;
		tmp2 --;
	}
	if (tmp1 == 0) {
		return 1;
	} 
	return -1;
}

qsort(words, wordsSize, sizeof(char*), Comp);

4、对结构体进行快排
qsort入参(整个数组起始地址,数组大小,数组每个元素大小,快排功能)
comp函数(转化为NationPoint*的指针,这个没有取值了,而是直接->,都可以的)

int comp(const void *a, const void *b) {
    NationPoint * aa = (NationPoint *)a;
    NationPoint * bb = (NationPoint *)b;
    if (aa->gold != bb->gold) {
        return bb->gold - aa->gold;
    }
    if (aa->silver != bb->silver) {
        return bb->silver - aa->silver;
    }
    if (aa->bronze != bb->bronze) {
        return bb->bronze - aa->bronze;
    }
    return strcmp(aa->name, bb->name);
}
qsort(total,n,sizeof(NationPoint),comp);

5、使用BSEARCH查找
1、取地址查找的元素
2、升序数组
3、数组大小
4、元素所占字节
5、比较函数
返回查找的元素的地址

    int *ret = malloc(sizeof(int)*arrSize);
    int *tmp;
    for (i = 0; i < arrSize; i++) {
        tmp = (int *)bsearch(&arr[i], rank, count, sizeof(int), comp);
        ret[i] = tmp - rank + 1;
    }

附录1331

int comp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b;
}
int* arrayRankTransform(int* arr, int arrSize, int* returnSize){
    if (arr == NULL || arrSize == 0) {
        *returnSize = 0;
        return NULL;
    }
    int arrtmp[arrSize];
    memcpy(arrtmp,arr,sizeof(int)*arrSize);
    qsort(arrtmp, arrSize, sizeof(int), comp);

    int rank[arrSize];
    int i, j, count;
    count = 0;
    for (i = 0; i < arrSize; i++) {
        if (i > 0 && arrtmp[i] == arrtmp[i-1]) {
            continue;
        }
        rank[count++] = arrtmp[i];
    }

    int *ret = malloc(sizeof(int)*arrSize);
    int *tmp;
    for (i = 0; i < arrSize; i++) {
        tmp = (int *)bsearch(&arr[i], rank, count, sizeof(int), comp);
        ret[i] = tmp - rank + 1;
    }
    *returnSize = arrSize;
    return ret;
}

附录820

int Comp(const void *a, const void *b)
{
    char *aa = *(char**)a;
    char *bb = *(char**)b;
    int lena, lenb, i;
    lena = strlen(aa); 
    lenb = strlen(bb);
    i = 0;
    while (i < lena && i < lenb) {
        if (aa[lena - 1 - i] != bb[lenb - 1 - i] ) {
            return aa[lena - 1 - i] - bb[lenb - 1 - i] ; 
        }
        i++;
    }
    return lenb - lena;
}

int minimumLengthEncoding(char ** words, int wordsSize){
    if (wordsSize == 0) {
        return 0;
    }
     if (wordsSize == 1) {
        return strlen(words[0]) + 1;
    }   
    qsort(words, wordsSize, sizeof(char*), Comp);
    int start, end, slen, elen, count;
    count = strlen(words[0]) + 1;
    start = 0;
    end = start + 1;
    while (end < wordsSize) {
        slen = strlen(words[start]);
        elen = strlen(words[end]);
        if (slen >= elen && (strcmp(words[start] + slen - elen, words[end]) == 0) ) {
            end++;
            continue;
        } 
        count += elen + 1;
        start = end;
        end = end + 1;
    }
    return count;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值