初识C语言·字符(串)函数

news2024/11/28 3:28:12

目录

1 字符分类函数

2 字符转换函数

3 strlen的模拟实现

4 strcpy的使用和模拟实现

5 strcat的使用和模拟实现

6 strcmp的使用和模拟实现

7 strncpy strncat strncmp的使用和模拟实现

8 strstr的使用和模拟实现

9 strerror的使用

10 strtok的使用



1 字符分类函数

C语言有一类函数是专门做字符分类的,即一个字符是属于什么类型的。

这些函数的使用都需要引用头文件ctype.h,现在将这些函数一一列举。

这些就是C语言中专门做字符分类的函数了,从英文的角度来看是很好理解的,比如isspace就是

is (是)space(空格),判断是不是空格,很好理解。同理,digit是十进制数字,xdigit是十六进制数字,upper就是大写,lower就是小写,都是挺好理解的,alpha就是字母,alnum就是alpha num的总和,punct就是标点符号了,所以英文学一点对C语言的函数还是有点用的。

如果判断结果为真的话就是返回为真的值,但是不一定是1,像这样。


2 字符转换函数

有字符识别函数也会有转化函数,C语言中提供了两个字符转化函数。

大写转小写,小写转大写咯,结合英文就是很好记的了。

也是要引用头文件ctype的。小小的示范一下。

int main()
{
	char arr[] = "abcEFGhi";
	char* p = arr;
	while (*p)
	{
		*p = tolower(*p);
		p++;
	}
	printf("%s", arr);
	return 0;
}


3 strlen的模拟实现

有关strlen的使用相信大家都知道了,我们现在要学习的是模拟实现strlen函数,函数章节提及学习一个函数的最好方法有模拟实现它,试试咯。

法1:

我们知道strlen函数的原理就是找'\0',所以我们可以找一次就+1,找到了就不加了再返回值就行。

int Count(char* pa)
{
	int count = 0;
	while (*pa)
	{
		count++;
		pa++;
	}
	return count;
}
int main()
{
	char arr[] = "abcdefg";
	int ret = Count(arr);
	printf("%d ", ret);
	return 0;
}

这里可以巧用while循环,如果*pa是'\0'的话,刚好while循环就停止了,也就不会再count++了,最后返回count的值就行。

法2;

前面讲解指针的时候,我们提及在同一块空间中,指针-指针是中间的元素个数,那么也使用这里。

int Count(char* pa)
{
	char* pb = pa;
	while (*pa++)
	{
		;
	}
	return pa - pb - 1;
}
int main()
{
	char arr[] = "abcdefg";
	int ret = Count(arr);
	printf("%d ", ret);
	return 0;
}

因为是指针- 指针,所以在最开始的时候我们应该创建一个指针变量用来存放最开始的地址,利用while循环是pa指向的是斜杠0,因为指向的是'\0',所以相减的时候要多减1,这样才避免了因为'\0'导致的数多了。

法3:

你看,1 + 2 + 3 + 4 + 5是不是可以用递归,计数的我们都可以用递归,strlen何尝不是一种计数呢?所以我们同样可以使用递归实现。

int Count(const char* pa)
{
	assert(pa);
	if (*pa == '\0')
		return 0;
	else
		return 1 + Count(pa + 1);
}
int main()
{
	char arr[] = "abcdefg";
	int ret = Count(arr);
	printf("%d ", ret);
	return 0;
}

至于为什么加const,因为我们只是计算长度,不希望字符串的内容被修改,所以加个const修饰一下,结合前面的递归知识,这个是很好理解的。


4 strcpy的使用和模拟实现

学习一个函数我们可以先去cplusplus里面看看。

引用的头文件是string,返回类型是char*,根据Return Value我们可以得知是目的地字符串被返回,参数类型是目标字符串的地址和被复制的字符串的地址,因为被复制的字符串我们是不期望被修改的,所以用const修饰。

那么使用的话,我们先举个例子。

int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "gf";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

提问,打印的结果是什么?

是gf?还是gfbcefg?这里涉及到的就是斜杠0有没有被打印了。

看,斜杠0也是被拷贝过去了的,这是重点。

int main()
{
	char arr1[] = "abcdefg";
	char arr2[] = "gf";
	strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

但是如果这样写的话,arr2的空间是2,就会导致越界访问,就报错了,所以[]里面最好写上给它多少空间。

那知道了strcpy是用来复制字符串的,并且会复制斜杠0,且不希望修改被复制的字符串的内容,我们就可以开始模拟实现了。

char* my_strcpy(char* dest, const char* sou)
{
    assert(dest);
    assert(sou);
	char* p1 = dest;
	while (*sou)
	{
		*dest = *sou;
		dest++, sou++;
	}
	*dest = '\0';
	return p1;
}
int main()
{
	char arr1[100] = "abcdefg";
	char arr2[100] = "gf";
	char* pa = my_strcpy(arr1, arr2);
	printf("%s\n", pa);
	return 0;
}

这是最基础的写法,为什么基础呢?因为代码量多了点,先看为什么返回值是p1而不是dest,因为根据cpiusplus的记叙我们返回的应该是最开始的目的字符串的地址,所以我们先暂存一下,在返回。

我们要简洁一下代码量的话就应该从while循环里面入手,因为循环判断条件总是比循环体次数多执行一次,所以我们可以把循环体的内容放在循环条件里面执行。

char* my_strcpy(char* dest, const char* sou)
{
	assert(dest);
	assert(sou);
	char* p1 = dest;
	while (*dest++ = *sou++)
	{
		;
	}
	return p1;
}
int main()
{
	char arr1[100] = "abcdefg";
	char arr2[100] = "gf";
	char* pa = my_strcpy(arr1, arr2);
	printf("%s\n", pa);
	return 0;
}

像这样,代码量一下就少了很多,而且还不用单独赋值'\0',但是分号是必须写的,就是空语句的意思而已,当然有兴趣的话,你也可以使用for循环来完成。


5 strcat的使用和模拟实现

strcat这个函数是用来连接字符串的,根据cplusplus

我们得知,引用的头文件是string,返回值是目的字符串的地址,返回类型是char*,参数有两个,目的字符串的地址和来源字符串的地址,简单的使用一下。

int main()
{
	char arr1[100] = "abc";
	strcat(arr1, "def");
	char arr2[100] = "ghi";
	strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

这里可以注意到的就是两个字符数组我都是指定了空间大小的,如果不指定空间大小是很容易出现越界访问的问题的,其次就是目的字符串不能是常量字符串,因为常量字符串是不能被修改的。

有个值得注意的点就是这个函数复制的时候是斜杠0在哪里就从哪里开始复制,如果复制的是\0提前了也就不会继续复制了。

那么基本原理我们知道了现在来实现这个函数。

实现这个函数我们首先要找的目的函数的结束标志,那么可以模仿strlen的while循环来找到结束标志,找到了之后就是根据来源字符串的结束标志决定循环的次数,所以while里面是*pb,当然你用for循环都是可以实现的,循环体内就是赋值的过程,赋值好之后就是指针指向的空间往后跳一个的操作,最后赋值完成,因为pb最后指向的是\0,但是pa是没有赋值到\0的,所以我们需要手动给它一个\0。

char* my_strcat(char* pa, const char* pb)
{
	char* p1 = pa;
	while (*pa)
	{
		pa++;
	}
	while (*pb)
	{
		*pa++ = *pb++;
	}
	*pa = '\0';
	return p1;
}
int main()
{
	char arr1[100] = "a\0bc";
	char* p1 = my_strcat(arr1, "de\0f");
	char arr2[100] = "ghi";
	p1 = my_strcat(arr1, arr2);
	printf("%s\n", p1);
	return 0;
}

如果不初始化,还不手动给\0,那么结果就是这样的。


6 strcmp的使用和模拟实现

strcmp就是string compare,意思是字符串比较的意思,那么这个比较不是我们一般理解的比较长度什么的,这个是比较的大小,比如abc acc比较,后者就大一点,该函数遍历字符串,相同的部分就跳过,直到指向不一样的字符串,根据ASCII码值来比较。abc aaaa比较的话是abc大一点,也就是说它比较到一个字符不相等就返回值了。

根据cplusplus的记载,头文件是string,返回值是int类型的,实际上返回的时候只会返回1 0 -1,在前面的qsort的模拟实现的时候我们也利用了这点,参数是两个字符串的地址,因为我们只是比较不希望改变值,所以加const修饰,简单是使用一下。

int main()
{
	char arr1[100] = "abcd";
	char arr2[100] = "aaaa";
	int ret = strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}

我们用ret来接收值,因为abcd > aaaa,所以ret的值是1。

实现它我们只需要做到让指针指向两个字符不相同的地方,可以使用if while,不同了一个if语句就解决了,所以这个函数还是挺好实现的。

int my_strcmp(const char* p1, const char* p2)
{
    assert(p1);
    assert(p2);
	while (1)
	{
		if (*p1 == *p2)
		{
			p1++, p2++;
		}
		else
		{
			break;
		}
	}
	if (*p1 > *p2)
	{
		return 1;
	}
	else if(*p1 < *p2)
	{
		return -1;
	}
	else
	{
		return 0;
	}
}
int main()
{
	char arr1[100] = "abcd";
	char arr2[100] = "aaaa";
	int ret = my_strcmp(arr1, arr2);
	printf("%d\n", ret);
	return 0;
}
int my_strcmp (const char * str1, const char * str2)
{
 int ret = 0 ;
 assert(src != NULL);
 assert(dest != NULL);
 while(*str1 == *str2)
 {
 if(*str1 == '\0')
 return 0;
 str1++;
 str2++;
 }
 return *str1-*str2;
}

这串代码是升级版,别看是指针减去指针,实际结果还是1 0 -1,但是这串代码确实很简洁,也更加验证了return 的妙用。


7 strncpy strncat strncmp的使用和模拟实现

熟悉吧?好像就是前面的三个函数加了个n,那么,物以类聚人以群分,我们通过一个函数的学习,自然就可以掌握其他相同的两个。

函数的返回值返回类型都没有变,唯独变化的是参数部分,多了一个size_t类型的num

多了一个n,参数就多了一个num嘛,很正常咯。实际上该函数就是指定了连接字符的个数,n就是num,数字的意思,这里就不免提到了为什么strcpy ctrcat strcmp被称为危险函数了,因为没有数字的限制,是有出现越界的可能性的,scanf也是的,所以在vs里面给它们加上_s的后缀,至于为什么,问vs咯。

现在我们就模拟实现一下三个函数,无非就是加一个循环条件而已。

模拟实现strncpy

char* my_strncpy(char* p1, char* p2, size_t num)
{
	char* ret = p1;
	while (num)
	{
		*p1 = *p2;
		p1++, p2++;
		if ('\0' == *p2)
		{
			break;
		}
		num--;
	}
	*p1 = '\0';
	return ret;
}
int main()
{
	char arr1[100] = "abcdefg";
	char arr2[100] = "gf\0xy";
	//strncpy(arr1, arr2, 4);
	char* ret = my_strncpy(arr1, arr2, 4);
	printf("%s\n", arr1);
	return 0;
}

代码部分并没有差多少,稍加思索就理解了的,那么其他两个函数应该就不用进行解释了吧?

相信你可以自己独立完成!


8 strstr的使用和模拟实现

strstr就是string string咯,这个函数的功能是在A字符串中寻找B字符串第一次出现的位置,并返回该函数的指针,如果没有找到,返回的就是空指针。

参数有两个,两个字符串的地址,参数要用const修饰的话,就全都用const修饰咯,毕竟我们只是想要找位置,并不是想要修改。

根据Parameters我们可以知道,通过扫描字符串str1,来匹配字符串str2。

根据Return Value我们可以知道,如果找到了就返回匹配成功的那个首元素地址,没有成功就返回NULL,那你可能问了,成功找到的话是返回字符串的首元素地址吗?那打印的不就是字符串2了吗?当然不是,你可以看看如下例子。

int main()
{
	char arr1[100] = "Happy is so simple";
	char arr2[100] = " ";
	char* ret = strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

我要在字符串1中寻找空格这个字符,在y的后面就找到了,于是ret就接收了这个地址,并在str1中开始打印,直到碰到'\0'。

int main()
{
	char arr1[100] = "Happy is so simple";
	char arr2[100] = "1";
	char* ret = strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

如果我是在字符串1中寻找1字符,看来就找不到了,所以返回的是空指针,打印的结果就是如此。

那么以下代码阁下该如歌应对呢?

int main()
{
	char arr1[100] = "Happy is so simple";
	char arr2[100] = "\0";
	char* ret = strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

在arr1里面找结束标志,最后的结果是不是结束标志呢?显然不是。

是整个arr1数组,那么可不可以理解为strstr寻找的时候,是以arr2的'\0'作为比较的结束标志呢?要验证很简单。

int main()
{
	char arr1[100] = "Happy is so simple";
	char arr2[100] = "s\0o";
	char* ret = strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

如果是以'\0'作为标志的话,那么结果应该是s so simple。

猜想成立,所以比较的时候使用arr2的'\0'作为标志的。

使用我们会了,现在就是模拟实现了。

模拟实现的时候我们要考虑一下几种情况,1 字符2数组首元素为'\0',2 找得到 3 前半段有一样的但是没有完全一样。

第一种情况很简单,就一个if return完成了,我们侧重找得到和找不到,它比较就是从字符1数组每个元素挨个挨个的比较,所以我们可以用字符1数组的元素作为循环变量,如果遍历完字符1数组还没有满足条件的,就返回return NULL,那么循环体里面的东西怎么写呢?

第三种情况是有相似的但不完全相似,比如字符1数组是so1 so2 simple,字符2数组是so2,那么最开始返回的指针会落在第一个s上面,但是到后面不满足这个条件了,我们就需要重置它,所以在每次循环结束后,需要重置两个东西,分别是返回的指针变量和字符数组2的临时变量,因为每次循环完它们的值都改变了。

当两个临时变量都不是结束标志的时候,并且它们相等,就让他们的指向的位置一直往后移,直到这两个不相等了或者是某个变量已经是结束标志了,这里有个很巧妙的判断它们是否相等,对他们相减的结果进行取反,如果相等,相减就是0,取反了就是1,while循环继续下去,循环体内的内容就是s1++,s2++,最后跳出循环的时候判断一下s2指向的内容是不是'\0',如果是的话,返回这个时候的字符1中的临时变量,最后如果整个while循环过去了都没有找到,就直接返回NULL就行了。

所以模拟实现strstr的时候是需要5个临时变量的,字符1数组的地址,字符数组2的地址,用于遍历字符2数组的变量,用于遍历字符1数组的变量,用于重置遍历字符1数组的指针变量。

代码如下。

const* my_strstr(const char* str1, const char* str2)
{
	char* cp = str1;
	char* s1, * s2;
	if (!*str2)
		return str1;
	while (*cp)
	{
		s1 = cp;
		s2 = str2;
		while (*s1 && *s2 && !(*s1 - *s2))
			s1++, s2++;
		if (!*s2)
			return cp;
		cp++;
	}
}
int main()
{
	char arr1[100] = "Happy is si1 simple";
	char arr2[100] = "si";
	char* ret = my_strstr(arr1, arr2);
	printf("%s\n", ret);
	return 0;
}

9 strerror的使用

现在讲的函数就不进行模拟实现了,因为点啥呢?你想,printf不能被模拟实现吧?这个也是,我们只是可以看到它的参数,功能,返回值,返回类型等,实现就不是我们的事儿了。

按照前面的方法,了解这个函数还是比较容易的,那么这个函数的功能是什么呢?

strerror函数可以把参数部分错误码对应的错误信息的字符串地址返回来,比如参数部分是0,那么就没有出错,这是规定的,所有错误码都是放在error的头文件里面的,在这个头文件里面,0代表的是No error,也就是没有错误,所以我们现在想main函数为什么要返回0,为什么C语言认为返回0就是程序正常,就是因为这个咯。

每个错误都是有自己对应的错误码的,但是程序报错的时候不可能就给你一个1或者2什么的,strerror通过错误码,返回错误码对应的那串字符串,我们现在就打印1-10对应的错误码试试。

int main()
{
	for (int i = 0; i <= 10; i++)
	{
		printf("%s\n", strerror(i));
	}
	return 0;
}

这就是打印结果,我们可以看到0对应的就是No error,再次验证了0是正常,因为返回类型是char*的,也就是那串字符串的首元素地址,所以我们用%s打印。


10 strtok的使用

先看一段记载,啊,好多,看不懂,好,那我介绍介绍。

返回值是指针,第一个参数是指向字符串的指针,第二个参数是指针,指向的是分隔符,分隔符是什么?先不管,直接上代码可能更容易理解。

int main()
{
	char arr[] = "198.168.6.111";
	char* sep = ".";
	char* str = NULL;
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	return 0;
}

最基本的情况就是这个,我们令.是分隔符,那么str接收函数返回的地址,这个函数的功能就是遍历传过去的字符串,在里面找分隔符,从第一个元素开始找,如果找到了,就使那一个分隔符变成\0,然后返回起始位置的地址,然后进行第二次寻找,第三次,直到找了\0,函数就结束了。

注意:这个函数是会修改字符串的,所以传进去的不能是常量字符串,也不能用const修饰

调试的结果,不出所料的所有.都变成了\0,那如果分隔符变多了呢?比如多个分隔符在一起了。

int main()
{
	char arr[] = "198..168..6..111";
	char* sep = ".";
	char* str = NULL;
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	return 0;
}

事实上,多个分隔符在一起的时候只会修改第一个分隔符,但是实际打印的时候,分割符是不会被打印的。

int main()
{
	char arr[] = "1981686111";
	char* sep = ".";
	char* str = NULL;
	/*
	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
	{
		printf("%s\n", str);
	}
	*/
	str = strtok(arr, sep);
	printf("%s\n", str);
	return 0;
}

但是如果分隔符,那么就跟打印字符串一样了。

如果首元素是\0,循环就直接结束了,可以自行试试。

还有一个要注意的点就是如果strtok的第一个参数是NULL的话,那么分割的位置就是从上一次分割完的位置继续遍历的,代码如下。

int main()
{
	char str[] = "apple,bnanan,cherry,grape";
	char* token;
	token = strtok(str, ",");
	while (token != NULL)
	{
		printf("%s\n", token);
		token = strtok(NULL, ",");
	}
	return 0;
}

以上就是常用的字符类函数的介绍,感谢阅读!

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

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

相关文章

Java ArrayList在遍历时删除元素

文章目录 1. Arrays.asList()获取到的ArrayList只能遍历&#xff0c;不能增加或删除元素2. java.util.ArrayList.SubList有实现add()、remove()方法3. 遍历集合时对元素重新赋值、对元素中的属性赋值、删除元素、新增元素3.1 普通for循环3.2 增强for循环3.3 forEach循环3.4 str…

Qt(二):使用udp发送与接收图片

使用Qt来通过UDP协议发送和接收图片可以分为几个步骤。以下是一个基本的指南&#xff1a; 发送图片准备图片数据&#xff1a;首先&#xff0c;你需要将图片转换为可以在网络上传输的数据格式。通常&#xff0c;这涉及到将图片转换为字节数组。设置UDP套接字&#xff1a;在Qt中…

Go 泛型之泛型约束

Go 泛型之泛型约束 文章目录 Go 泛型之泛型约束一、引入二、最宽松的约束&#xff1a;any三、支持比较操作的内置约束&#xff1a;comparable四、自定义约束五、类型集合&#xff08;type set&#xff09;六、简化版的约束形式七、约束的类型推断八、小结 一、引入 虽然泛型是…

水果软件2024FL Studio21.3mac苹果中文版

FL STUDIO21发布&#xff0c;提供您一直在等待的出色工作流程功能。通过新效果、多个播放列表曲目选择和无所畏惧的撤消一切编辑&#xff0c;将您的音乐带入2024年。FL Studio21中文完整版是一个功能齐全、开放式架构的PC音乐创作和制作环境。它具有基于音乐音序器的图形用户界…

uniapp:实现手机端APP登录强制更新,从本地服务器下载新的apk更新,并使用WebSocket,实时强制在线用户更新

实现登录即更新&#xff0c;或实时监听更新 本文介绍的是在App打开启动的时候调用更新&#xff0c;点击下方链接&#xff0c;查看使用WebSocket实现实时通知在线用户更新。 uniapp&#xff1a;全局消息是推送&#xff0c;实现app在线更新&#xff0c;WebSocket&#xff0c;ap…

白话机器学习的数学-1-回归

1、设置问题 投入的广告费越多&#xff0c;广告的点击量就越高&#xff0c;进而带来访问数的增加。 2、定义模型 定义一个函数&#xff1a;一次函数 y ax b &#xff08;a 是斜率、b 是截距&#xff09; 定义函数&#xff1a; 3、最小二乘法 例子&#xff1a; 用随便确定的参…

常见HTTP 500错误发生原因及解决办法剖析

​  对于网站运营者来说&#xff0c;提到500内部服务器错误并不陌生。互联网行业对它的称呼有好几种&#xff0c;如“500内部服务器错误”、“HTTP 500 - 内部服务器错误”、“临时错误 (500)”、“内部服务器错误”。尽管叫法不同&#xff0c;但根本问题是相同的。 目前&…

【Shell编程练习】通过位置变量创建 Linux 系统账户及密码

系列文章目录 输出Hello World 系列文章目录位置变量代码实现运行结果 位置变量 位置变量将以数字方式对变量进行命名&#xff0c;可将命令行参数的值存储到脚本中。要从命令行、函数或脚本执行等处传递参数时&#xff0c;就需要在 Shell 脚本中使用位置参数变量。下表为常用…

git unable to create temporary file: No space left on device(git报错)

1.问题 1.1 vscode中npm run serve跑项目的时候&#xff0c;进度达到95%的时候一直卡着无进度&#xff1b; 1.2 git命令提交代码报错&#xff1b; 2.具体解决 这个错误通常表示你的磁盘空间已经满了&#xff0c;导致 Git 无法在临时目录中创建文件。2.1 清理磁盘空间&#xf…

硅像素传感器文献调研(五)

写在前面之文献检索 —————————————————————————————————————————— 首先感慨一下sci-hub强大的检索能力。这篇论文在学校的数据库都没有搜到 来源是上篇论文的引用部分&#xff0c;截图如下&#xff1a; 先在谷歌学术镜像找到了&a…

数据结构 day6 栈+队列+二分查找+插入排序

插入排序 #include <stdio.h> #include<string.h> #include<stdlib.h> int main(int argc, const char *argv[]) {int a[]{41,50,66,38,32,49,18};int nsizeof(a)/sizeof(a[0]);int i,j,t;for(i1;i<n;i){int ta[i];for(ji-1;j>0;j--){if(t<a[j]){a…

flutter学习-day21-使用permission_handler进行系统权限的申请和操作

文章目录 1. 介绍2. 环境准备2-1. Android2-2. iOS 3. 使用 1. 介绍 在大多数操作系统上&#xff0c;权限不是在安装时才授予应用程序的。相反&#xff0c;开发人员必须在应用程序运行时请求用户的许可。在 flutter 开发中&#xff0c;则需要一个跨平台(iOS, Android)的 API 来…

跨境电商卖家一般用海外云手机做什么?

近些年&#xff0c;海外云手机在跨境电商领域已经逐渐流行开来&#xff0c;但是对于许多人来说海外云手机还是比较陌生&#xff0c;它有什么作用&#xff1f;它可以用于哪些场景&#xff1f;在本文中&#xff0c;我们将详细跨境电商卖家一般是怎样使用海外云手机的。 1. 海外网…

算法导论复习(七) 动态规划

动态规划一般用来求解最优化问题 设计一个动态规划算法一般有以下四步&#xff1a; 描述一个最优解的结构特征。递归地定义最优解的值。计算最优解的值&#xff0c;通常采用自底向上的方法。利用计算出的信息构造出一个最优解。 钢条切割问题 体现了动态规划的一个重要性质&a…

如何开发一个google插件(二)

前言 在上一篇文章如何开发一个google插件(一)里主要介绍了google插件的基本结构。 在这篇文章中主要结合reactwebpack进行一个代码演示&#xff0c;源码地址&#xff1a;源码地址 下载源码后打开浏览器的扩展程序管理->加载已解压的扩展程序&#xff0c;即可调试插件 此…

软件测试/测试开发丨学习笔记之Python运算符

运算符的作用 Python基础语法的内容通常表示不同数据或变量之间的关系 算数运算符 运算符描述加-减*乘/除%取模**幂//取整除 取模与取余区别 概念上&#xff1a;取模是计算机术语&#xff0c;取余属于数学概念&#xff1b; 结果上&#xff1a;当同号的两个数相除&#xff…

软件测试/测试开发丨Python内置库学习笔记

内置库 一、内置库OS 1、os概述 os: Operating Systemos 模块的常用功能跨平台的差异 2、os使用 导入 os 模块查看 os 模块使用文档 help(os)dir(os) import os# 查看os模块说明文档 help(os)# 查看os模块的属性和方法 print(dir(os))3、os 常用方法 &#xff08;1&…

浅谈WPF之控件模板Control Template和数据模板Data Template

WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计&#xff0c;同时还推出了以模板为核心的新一代设计理念。在WPF中&#xff0c;通过引入模板&#xff0c;将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类&#xff1a;数据模板【Data Template】和控…

仪表盘、数据分析新增分享功能及应用服务下新增服务实例菜单

近期&#xff0c;博睿数据根据一体化智能可观测平台 Bonree ONE 产品本身&#xff0c;以及用户反馈进行持续的更新和优化。以下为 Bonree ONE 产品功能更新报告第03期内容&#xff0c;更多探索&#xff0c;未完待续。 本次迭代的更新集中在平台的仪表盘、数据分析新增分享功能&…

JS + CSS 实现高亮关键词(不侵入DOM)

之前在做关键词检索高亮功能的时候&#xff0c;研究了下目前前端实现高亮的几种方式&#xff0c;第一就是替换dom元素实现高亮&#xff0c;第二就是利用浏览器新特性Css.highlights结合js选区与光标与CSS高亮伪类实现&#xff0c;实现功能如下&#xff1a; 一、页面布局 一个…