C语言的回调函数(详解sqort函数)

news2024/10/1 5:36:33

在上一篇文章中我们学习了指针与数组之间的关系,学习了指针数组,数组指针变量,函数指针变量和函数指针数组。那么接下来我们要学习的是一个利用函数指针变量去解决和简化各种问题的回调函数。

一、回调函数

回调函数在编程中是一种很常见的概念,它是指将一个函数作为参数传递给另一个函数,并在特定的条件或事件发生时被调用执行的函数回调函数不是直接由函数的实现方所调用,而是在特定的条件或事件发生时,由接收它的函数间接的去调用它。它的作用就好比前段时间热映的影视剧狂飙中,高启强因为某些原因,自己没办法直接下手时,就告诉老默"我想吃鱼了",而老默作为一个接收信号的人,它接收到了高启强给他的信号,于是能够帮助高启强去间接的完成他要做的事。

光举例子肯定是不行,让我们实际操作写一段比较简单的代码,来试着用一下回调函数吧~

int Add(int x, int y)
{
	return x + y;
}
void Calc(int(*num)(int, int))
{
	int a = 0;
	int b = 0;
	printf("请输入两个计算数:>");
	scanf("%d %d", &a, &b);
	int m = num(a, b);
	printf("结果为%d\n", m);
}
int main() 
{
	Calc(Add);
	return 0;
}

在这段代码中,我们创造了一个void类型的函数Calc来接收一个"一个名为num,能够接收两个整形变量的函数"的函数指针作为参数当Calc调用Add函数时,那么此时Add函数就是一个回调函数。61f980161b9f4d5e925b68350d9b7c29.png

而此时可能有人就想发出疑问了:通常情况下我们会直接调用Add函数去计算整数之和,并且与这段代码相比,好像直接使用Add函数会更加快捷简便,那为什么还要使用回调函数呢?回调函数的作用是什么呢?在上一篇文章中,我们写过一个实现计算机的代码,最初的版本有非常多的冗余语句。d3de813c299b475aba4401113f73a462.png

而回调函数就能很好的帮我们规避掉这些冗余的句子,从而实现简化代码的作用。让我们来实际操作一下回调函数简化计算机吧~

int Add(int x, int y)
{
	return x + y;
}
int Sub(int x, int y)
{
	return x - y;
}
int Mul(int x, int y)
{
	return x * y;
}
int Div(int x, int y)
{
	return x / y;
}
void Calc(int(*num)(int, int))
{
	int a = 0;
	int b = 0;
	printf("请输入两个计算数:>");
	scanf("%d %d", &a, &b);
	int m = num(a, b);
	printf("结果为%d\n", m);
}
int main() 
{
	int m;
	int n;
	int tmp = 1;
	do {
		printf("***********************\n");
		printf("**** 1.Add   2.Sub ****\n");
		printf("**** 3.Mul   4.Div ****\n");
		printf("******** 0.quit *******\n");
		printf("***********************\n");
		printf("请选择:>");
		scanf("%d", &tmp);
		switch (tmp)
		{
		case 1:Calc(Add);
			break;
		case 2:Calc(Sub);
			break;
		case 3:Calc(Mul);
			break;
		case 4:Calc(Div);
			break;
		case 0:printf("退出计算机");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (tmp);
	return 0;
}

这样就能够很明显的体现出回调函数的作用了,在一定情况下,它能够一定程度上简化我们的代码,并且解决一些解决不了的问题。

二、库函数strlen与strcmp

在讲sqort函数之前,我们需要先了解一下strlen函数和strcmp函数。它们是在一些对字符型数据进行计算时使用的,用处特别多,用法特别广泛的两个函数。

(两种函数的使用都需要加上头文件 <string.h>)

① strlen

521960f8cbb744b58e582cb5e4078d99.png

strlen的作用是:获取字符串长度,返回C字符串str的长度。

注:c字符串的长度由终止空字符确定,C字符串的长度等于字符串的开头和终止空字符之间的字符数(不包括终止空字符本身)。

比如我们定义了一个char str[100],但我们只为它初始化了11个字符,那么用int num = strlen(str)来获取字符串的长度时,就应该获取带11个字符。c0983826ee0d4f84a73d203358c009c7.png

② strcmp

212a2f6e2e504b7e86bab69ee1c110d5.png

strcmp的作用是:比较两个字符串,将C字符串 str1 与C字符组 str2进行比较。

比较方式为:该函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续进行以下配对,直到字符不同或达到终止空字符。此函数执行字符的二进制比较。

若str1小于str2,则返回负整数,即小于0的数。

若str1和str2相等,则返回0。

若str1大于str2,则返回正整数,即大于0的数。

我们还是来通过代码来进一步的了解一下它的作用效果:

#include <stdio.h>
#include <string.h>
int main() 
{
	char str1[] = "abcdef";
	char str2[] = "abcdefg";
	if (strcmp(str1, str2) > 0)
	{
		printf("str1比str2长\n");
	}
	else if (strcmp(str1, str2) < 0)
	{
		printf("str2比str1长\n");
	}
	else
	{
		printf("str1和str2一样长\n");
	}
	return 0;
}

7a5ac3b9c2e94602bc097522399b4bbe.png

这样就能够实现,通过strcmp来比较两个字符串的大小了。

 

三、qsort函数

通过上面我们对回调函数的解释,大家应该对回调函数的应用有了一定的了解。而说到回调函数的应用,这里我们就不得不提到qsort函数的应用了。

①qsort的参数及原理

qsort函数的作用就是对数据进行排序,比如现在有一组整型数组arr,里面有十个大小不同随意顺序的十个整形变量,那我们就能够通过qsort对它进行大小的排序。在学习qsort之前我们学习过冒泡排序,冒泡排序同样也能够对整型数组中的元素进行大小的排序:9c229f20f2bd441e81ac421af009c84a.png

这样就能够使数组中的元素大小排列了,但是仔细观察我们并不难发现,其实冒泡排序的缺点非常明显:

① 冒泡排序只适用于整型变量的排序。

② 时间复杂度O(n^2)太高,效率慢。

而这次我们要学习的qsort函数就能够完美的避免这两种问题,不仅能适用多种类型变量的排序,并且效率相较于冒泡排序也要大大提高。

qsort函数的格式:

void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

我们来分别了解一下qsort这四个参数:

①void *base:指向需要排序的数组的首元素,该对象转换为void*。

②size_t num:表示数组中元素的个数。

③size_t size:数组中每个元素的大小(以字节为单位)。size_t是无符号整型类型。

④int (*compar)(const void*,const void*):指向比较两个元素的函数。qsort调用这个函数来比较两个元素的大小。函数compar需要接收两个参数(都转换成const void*)并对两个参数进行比较,通过返回值来表示两个元素的大小关系。

Ⅰ— 如果返回值小于 0,表示 a 应该排在 b 的前面。

Ⅱ — 如果返回值等于 0,表示 a 和 b 相等,顺序不变。

Ⅲ — 如果返回值大于 0,表示 a 应该排在 b 的后面。

②qsort对整型数组排列

那么既然已经了解了qsort函数的使用方法,那让我们来利用qsort函数试试实现冒泡排序吧~

int compar(const void* a, const void* b)
{
	return (*(int*)a - *(int*)b);
}
int main() 
{
	int arr[] = { 7,5,3,9,8,4,6,2,1,0, };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

因为数组名代表的就是数组首元素的地址,所以第一个参数直接传arr就行,并且在定义比较函数compar时,返回值的计算需要我们将传入的const void*强制类型转换成int*并解引用,从而就能够计算出数组中两个元素的大小关系了

a697d74bef3d414281f1c7bd8b224d2f.png按照这种写法输出的冒泡排序是升序,那么我们能不能把它变成降序呢?其实很简单,像冒泡排序一样修改大于和小于号一样,我们只需要将return (*(int*)a - *(int*)b)修改成return (*(int*)b - *(int*)a)就好了。b09e582334914b74b3a815b31daa4a90.png

那我们能不能再尝试一下用qsort来为字符型数组排序呢?让我们尝试一下吧~!!

③qsort对字符串排列

在使用qsort对字符型数组排序前,我们需要思考一个问题:整型变量能通过大于号,小于号来进行大小的表示,可是字符型不可以呀,那应该怎么表示两个元素的大小关系呢?嘿嘿~这就体现了我上面讲到的strcmp函数的作用了,strcmp可以用于比较字符之间的大小,并且大于返回>0的数,小于返回<0的数,等于返回0,和qsort中比较函数的返回值也是一样的形式,而获取字符串长度可以使用上面讲到的strlen函数,因为它不会把\0也算进长度。那思路有了,让我们尝试一番吧

int compar(const void* a, const void* b)
{
	return strcmp((char*)a, (char*)b);
}
int main()
{
	char arr[] = "ihfknac";
	int sz = strlen(arr);
	qsort(arr, sz, sizeof(arr[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ", arr[i]);
	}
	return 0;
}

c230f599253f4f2ebc0ae5b875258c9b.png

这样就成功的把字符串也按顺序排列好啦~

④qsort对结构体排列

那么我们再来尝试一次,用字符串按顺序来对结构体进行排列~对结构体排列需要明确我们要排列的元素类型,比如我们现在创造一个结构体:

struct stu
{
	char name[20];
	int age;
};

如果模棱两可的,不知道想要比较哪一个数据,那当我们创造比较函数的时候就会陷入返回值的强制类型转换不知道该怎么写。所以我们要明确自己想要排列的数据才行。比如我们想排列结构体stu中的name,那我们就需要先定义一个结构体数组,然后在比较函数中使用strcmp比较大小(名字也是字符型),让我们动手试试吧:

struct stu
{
	char name[20];
	int age;
};
int compar(const void* a, const void* b)
{
	return strcmp(((struct stu*)a)->name, ((struct stu*)b)->name);
//也可以写作return strcmp((*((struct stu*)a)).name, (*((struct stu*)b)).name);
}
int main()
{
	struct stu s[3] = { {"xiaowang",23} ,{"xiaoli",18}, {"xiaozhang",29} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s ", s[i].name);
	}
	return 0;
}

7d54362e9b6449d9bf52bdf20038cb84.png

前面的xiao都相同,从第五个字符开始w,l,z都不同,于是通过对w,l,z的大小比较来进行排列。由于l<w<z,最后结果则是xiaoli,xiaowang,xiaozhang。那我们再试着对age排序吧~

struct stu
{
	char name[20];
	int age;
};
int compar(const void* a, const void* b)
{
	return (((struct stu*)a)->age) - (((struct stu*)b)->age);
}
int main()
{
	struct stu s[3] = { {"xiaowang",23} ,{"xiaoli",18}, {"xiaozhang",29} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", s[i].age);
	}
	return 0;
}

ed4a31288f9b452ca27cc2436da71d46.png

怎么样,是不是感觉以前很难实现的问题现在使用qsort就能非常轻松简便的解决啦~

四、构造并模拟实现qsort函数

其实我们学到刚刚也只是学会了如何使用qsort,如果想真的弄懂qsort的运作原理,不妨我们尝试一下,以冒泡排序的函数为基底,对冒泡排序函数一步步进行改造,将它变成一个qsort函数呢?

①BubbleSort的函数定义

对于自行构造出一个函数并使它实现qsort的功能,首先我们需要写出函数接收的参数,而参数并不需要什么多余思考,我们只需要借鉴qsort函数的参数就好了。

void BubbleSort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

但是我们需要思考一下:为什么传进BubbleSort函数中的base要定义成void*类型呢?

这是因为想要实现为不同类型的数据进行排序,就要能够做到对各种类型的数据进行接收,如果我们在这里只是单一的写成int*,那么就无法对char*类型进行接收,如果写成char*,又无法对结构体类型进行接收,而void * 为"无类型指针",可以指向任意类型的数据,就是说可以用任意类型的指针对 void 指针赋值。

而后面函数指针中传参的const void*类型也是同样的道理。

②BubbleSort中实现元素互换

在BubbleSort()函数中,我们并无法确定接收到的会是什么类型的数据,因此我们无法像之前的整形冒泡排序一样,直接以一个整形变量tmp间接的转换元素。而我们如果直接使用某种类型来接收,就会导致我们无法接收其他的元素。而此时我们可以选择不去管它传进来的到底是什么类型(因为就算纠结,也还是不知道传进的是什么),就算我们不直接对值进行交换,别忘了我们还学过指针呢~而指针通常以字节为单位,虽然我们不知道传进来的是什么类型的参数,但是我们可以知道一个类型变量占多少个字节,而将两个元素的所有的字节都相互替换,也就能够做到互换两个元素啦~

void swap(char* p1, char* p2, int sz)//用char是因为char只有一个字节
{                                    //这样才能做到每次只跳过一个字节
	int i = 0;                       //从而做到交换每一个字节
	for (i = 0; i < sz; i++)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}

这样就能实现利用指针,一个字节一个字节的交换,实现元素的交换~

③BubbleSort的函数结构体

对于BubbleSort函数的结构,我们就仿照冒泡排序的结构就可以,但我们仍然不清楚传进来的参数是什么类型,所以没办法直接进行对比,还是用字节来一个字节一个字节的进行比较,所以传进compar的两个参数也强制转换成char*类型,对之后的操作也都方便。

void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void* a, const void* b))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}

这样我们就成功的使用BubbleSort函数构造并模拟实现qsort函数的功能啦~!费尽周折终于算是把qsort模拟出来了,那么让我们尝试一下,用我们自己构造的BubbleSort给整型数组排序一下试试看吧~

int compar(const void* a, const void* b)
{
	return *(int*)a - *(int*)b;
}
void swap(char* p1, char* p2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void* a, const void* b))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}
int main()
{
	int arr[] = { 7,8,4,5,1,6,2,9,3,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

61643996610044d8b748ee094c9be573.png

结果是没有问题的呢,那么我们再尝试一下给字符串儿排序。

int compar(const void* a, const void* b)
{
	return strcmp((char*)a, (char*)b);
}
void swap(char* p1, char* p2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void* a, const void* b))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}
int main()
{
	char arr[] = "hdngijedg";
	int sz = sizeof(arr) / sizeof(arr[0]);
	BubbleSort(arr, sz, sizeof(arr[0]), compar);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%c ", arr[i]);
	}
	return 0;
}

99b31a93eed34598bfd7862589823b21.png依然是没有问题的,那么我们再尝试一次性把结构体的name和age都排序输出吧!

struct stu
{
	char name[20];
	int age;
};
int compar1(const void* a, const void* b)
{
	return ((struct stu*)a)->age - ((struct stu*)b)->age;
}
int compar2(const void* a, const void* b)
{
	return strcmp(((struct stu*)a)->name,((struct stu*)b)->name);
}
void swap(char* p1, char* p2, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		char tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
void BubbleSort(void* base, size_t num, size_t size, int (*compar)(const void* a, const void* b))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < num - 1; i++)
	{
		for (j = 0; j < num - 1 - i; j++)
		{
			if (compar((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
			}
		}
	}
}
int main()
{
	struct stu s[3] = { {"xiaowang",19},{"xiaozhang",28},{"xiaoli",12}};
	int sz = sizeof(s) / sizeof(s[0]);
	BubbleSort(s, sz, sizeof(s[0]), compar1);
	BubbleSort(s, sz, sizeof(s[0]), compar2);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%s ", s[i].name);
	}
	printf("\n");
	for (i = 0; i < sz; i++)
	{
		printf("%d ", s[i].age);
	}
	return 0;
}

9bb7e4f88a724cc1846a9d4b41524003.png

也是运行成功啦~这样看来我们的构造并模拟实现qsort函数就大功告成啦,那今天关于回调函数的知识分享就到这里啦,我们下次再见哦~

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1979716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux shell编程学习笔记68: curl 命令行网络数据传输工具 选项数量雷人(上)

0 前言 在网络时代&#xff0c;有经常需要在网络上传输数据&#xff0c;时我们需要通过网络下载文件&#xff0c;为了满足这种时代需要&#xff0c;Linux提供了众多网络命令&#xff0c;我们今天先研究curl命令。例如&#xff0c;我们可以使用 curl 从 URL 下载文件&#xff0…

QT百度智能云API鉴权,查询 文心一言 服务调用情况

百度智能云API鉴权 做了一个利用Qt实现调用文字大模型的API 小软件 AI.xyz。 想通过api直接访问国产语言大模型的调用情况&#xff0c;翻了半天 豆包、通义、文心 的官方文档。最后只找到百度提供通过api读取访问的功能。 一开始只看到 python 的sdk&#xff0c;试了试还可以…

Java常用类和数据结构与算法

1. 其他常用类 1.1. Math类 java.lang.Math提供了一系列静态方法用于科学计算&#xff1b;其方法的参数和返回值一般为double型。如果需要更加强大的数学运算能力&#xff0c;可以使用apache commons下面的Math类库 public class TestMath {public static void main(String[…

python 图片爬虫记录

看了2-3个小时的奥运会&#xff0c; 感觉内心空虚。 写点代码。 不知道做什么&#xff0c;随便搞一下爬虫&#xff0c;积累一点经验&#xff0c; 写篇博客&#xff0c;记录一下。 1. 注意检查响应头 情况描述: 对于这样一个 图片的 url https://blogger.googleusercontent.…

基于FPGA的数字信号处理(20)--半减器和全减器

目录 1、前言 2、半减器 3、全减器 4、减法器 文章总目录点这里&#xff1a;《基于FPGA的数字信号处理》专栏的导航与说明 1、前言 既然有半加器和全加器&#xff0c;那自然也有半减器和全减器了。尽管在电路中减法的实现基本都是 补码 加法 的形式&#xff0c;但是正所谓…

Hadoop搭建集群

Hadoop搭建集群 前言一、环境配置1.配置JDK2.配置Hadoop环境 二、Hadoop本地运行三、Hadoop集群部署1.准备三台服务器2.节点规划3.环境配置4.无秘登录5.配置核心文件1&#xff09;修改core-site.xml2&#xff09;修改hdfs-site.xml3&#xff09;修改yarn-site.xml4&#xff09;…

【linux】【操作系统】内核之sched.c源码阅读

sched.c提供的代码片段包含了与操作系统内核中的进程调度和管理相关的多个函数。schedule函数首先对所有任务&#xff08;进程&#xff09;进行检测&#xff0c;唤醒任何一个已经得到信号的任务。具体方法是针对任务数组中的每个任务&#xff0c;检查其报警定时值alam。如果任务…

Midjourney咒语之手机壁纸国画艺术

手机壁纸 Mountains, surfaces, mysterious landscapes --ar 9:16 Abstract shapes of billowing flowing colorful gauze fabric, --ar 9:16 国画艺术 Peony is

如何快速看完一个网页上的视频

如何快速看完一个视频 懂的都懂。 Edge浏览器 添加下面两个书签&#xff1a; javascript:document.querySelector("video").dispatchEvent(new Event("ended"))javascript:var vdocument.querySelector("video");if(v){v.mutedtrue;v.playba…

从艺术创作到作物生长,农业AI迎来“GPT“时刻

&#xff08;于景鑫 国家农业信息化工程技术研究中心&#xff09;"GPT"一词早已不再神秘,其在文本、图像生成领域掀起的风暴正以摧枯拉朽之势席卷全球。人们惊叹于ChatGPT对话之智能、思维之敏捷,更对Stable Diffusion、Midjourney创作的艺术画作赞叹不已。而大语言模…

无代码开发AI服务 - 利用向量库Kendra和Llama大模型在亚马逊云科技AWS上创建RAG知识库

简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 上次我们介绍了我们利用ElasticSearch作为向量…

网鼎杯comment二次注入

靶机网址&#xff1a;BUUCTF在线评测 进来就是这个界面&#xff0c;点击发帖后需要进行登录。 从界面可以看出用户是zhangwei&#xff0c;密码是zhangwei***&#xff0c;密码的最后三位需要进行暴力破解。 这里需要用到工具Burp Suite进行抓包。 这就是抓到的包&#xff0c;我…

【大模型从入门到精通8】openAI API 提升机器推理:高级策略2

这里写目录标题 示例定义处理输入的函数链式思考提示示例&#xff1a;结构化系统和用户提示获取并展示模型的回答实现内心独白结论与最佳实践 示例 设置环境 在深入实施之前&#xff0c;设置必要的环境至关重要。这包括加载 OpenAI API 密钥并导入相关的 Python 库。以下代码块…

Chapter 25 面向对象

欢迎大家订阅【Python从入门到精通】专栏&#xff0c;一起探索Python的无限可能&#xff01; 文章目录 前言一、初识对象二、成员方法三、类和对象 前言 面向对象编程&#xff08;OOP&#xff09;是Python编程中的一个核心概念&#xff0c;它能帮助程序员更好地组织和管理代码…

01 计算机系统基础-2

操作系统 进程管理 进程管理是操作系统的核心&#xff0c;但如果设计不当&#xff0c;就会出现死锁的问题。如果一个进程在等待一件不可能发生的事&#xff0c;则进程就死锁了。而如果一个或多个进程产生死锁&#xff0c;就会造成系统死锁。基于死锁产生机制及解决方案&#…

LeetCode Hard|【460. LFU 缓存】

力扣题目链接 LFU全称是最不经常使用算法&#xff08;Least Frequently Used&#xff09;&#xff0c;LFU算法的基本思想和所有的缓存算法一样&#xff0c;一定时期内被访问次数最少的页&#xff0c;在将来被访问到的几率也是最小的。 相较于 LRU 算法&#xff0c;LFU 更加注重…

MATLAB霍夫曼表盘识别系统

MATLAB霍夫曼表盘识别系统 一、介绍 本设计为基于MATLAB的表盘指针识别&#xff0c;算法原理是基于hough变换。可检测压力表&#xff0c;石英手表&#xff0c;电表刻度&#xff0c;气压表等带指针刻度的表盘。通过hough检测直线和圆的关系&#xff0c;得出指针夹角&#xff0…

保形分位数回归(CQR)

目录 简介1 介绍提纲式总结 分位数回归从数据中估计分位数 3 共性预测4 保形分位数回归(CQR)两个定理 6 实验7 结论 简介 保形预测是一种构造在有限样本中获得有效覆盖的预测区间的技术&#xff0c;无需进行分布假设。尽管有这种吸引力&#xff0c;但现有的保形方法可能是不必…

(C题老外游中国)2024年华数杯大学生数学建模竞赛解题思路完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

Open3D 三维重建-Delaunay Triangulation (德劳内三角剖分)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2重建后点云 Open3D点云算法汇总及实战案例汇总的目录地址&#xff1a; Open3D点云算法与点云深度学习案例汇总&#xff08;长期更新&#xff09;-CSD…