C++11 数据结构6 栈的链式存储,实现,测试

栈顶放在链表的头部

栈顶放在链表的头部还是尾部呢?

需要栈 是特殊的线性表,那么我们回忆一下 线性表的链式存储的插入和删除的写法,就应该能理清线性表的头部做为栈顶 合适  还是 线性表的尾部 作为栈顶合适

插入算法 核心代码

	//正式插入数据,
	int i = 0;
	LinkListNode *curSeqListNode = &(tempseqlist->head);//让curSeqListNode 指向 链表的头部
	for (int i = 0; i < pos; ++i) {
		curSeqListNode = curSeqListNode->next;
	}
	node->next = curSeqListNode->next;
	curSeqListNode->next = node;
	tempseqlist->length++;
	return ret;

删除算法 核心代码

	//辅助指针变量curSeqListNode,指向的位置是链表的头部
	LinkListNode *curSeqListNode = &(tempseqlist->head);//让curSeqListNode 指向 链表的头部
	
    int i = 0;
	for (i = 0; i < pos; ++i) {
		curSeqListNode = curSeqListNode->next;
	}
	retSeqListNode = curSeqListNode->next;	//先将要删除的节点缓存出来
	curSeqListNode->next = retSeqListNode->next;// 删除的节点的next中保存着 “要删除元素的下一个元素”,让curseqlistnode->next 指向
	tempseqlist->length--;
	return retSeqListNode;

从这两个算法都能看出,如果要在pos 位置插入元素 或者 删除元素,那么先要遍历到pos 位置,因此我们在 线性表的头部 做为 栈顶 比较合理。因此不管是插入元素,或者是删除元素,都是对线性表的头部的第一个元素进行处理。

相关代码:

#ifndef __006LINKSTACK_H__
#define __006LINKSTACK_H__

typedef void LinkStack; //链表的返回值,需要使用void *

typedef struct LinkStackNode {  //链表节点
	struct LinkStackNode *next;
}LinkStackNode;

// 初始化,建立一个空的链表 
//返回值不为NULL,表示创建成功。
//返回值为NULL,表示创建失败。
LinkStack* LinkStack_Create();

//销毁该线性表
//返回值为1,表示成功。
//返回值为-1,表示失败。
int LinkStack_Destory(LinkStack *list);

//清空seqlist
//返回值为1,表示成功。
//返回值为-1,表示失败。
int LinkStack_Clear(LinkStack *list);

// 返回线性表List存在的元素个数
//返回值 >=0 表示:该list存在的元素个数
//<0 表示error
int LinkStack_Length(LinkStack *list);



//从LinkStack 中获取栈顶位置的数据,实际上是 栈的第一个链表的数据
//返回值:为存储在该位置的元素
//返回NULL 表示有问题
LinkStackNode* LinkStack_Get(LinkStack *list);


//给LinkStack中指定位置插入数据,
//参数LinkStackNode为要插入的数据
//参数 pos 为要插入的位置
//成功返回1
//失败 返回<0

int LinkStack_Insert(LinkStack *list, LinkStackNode *node);


//从LinkStack 中删除栈顶位置的元素,实际上删除的链表的除了头结点的第一个元素
//参数 pos
//返回值为 删除的元素
//返回NULL 表示出现了error
LinkStackNode* LinkStack_Delete(LinkStack *list);

//判断当前linkstack 是否为null,如果为null,则返回1
//如果不为NULL,则返回-1;
int isEmptyLinkStack(LinkStack *list);
#endif

#include "006linkstack.h"
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

typedef struct LinkStack {
	LinkStackNode head;
	int length;// 该链表的大小
}TLinkStack;

// 初始化,建立一个空的链表 
//返回值不为NULL,表示创建成功。
//返回值为NULL,表示创建失败。
LinkStack* LinkStack_Create() {
	TLinkStack * ts = (TLinkStack *)malloc(sizeof(TLinkStack));
	if (ts == NULL) {
		printf("LinkStack_Create error list==NULL\n");
		return NULL;
	}
	memset(ts, 0, sizeof(TLinkStack));
	ts->head.next = NULL;
	ts->length = 0;

	return ts;
}

//销毁该线性表
//返回值为1,表示成功。
//返回值为-1,表示失败。
int LinkStack_Destory(LinkStack *list) {
	int ret = 1;
	if (list ==NULL) {
		ret = -1;
		printf("func LinkStack_Destory error bacesue list = NULL return ret = -1\n");
		return ret;
	}
	TLinkStack * ts = list;
	free(ts);
	ts = NULL;
	list = NULL;
	return ret;
}

//清空seqlist
//返回值为1,表示成功。
//返回值为-1,表示失败。
int LinkStack_Clear(LinkStack *list) {
	int ret = 1;
	if (list == NULL) {
		ret = -1;
		printf("func LinkStack_Clear error bacesue list = NULL return ret = -1\n");
		return ret;
	}
	TLinkStack * ts = list;
	ts->head.next = NULL;
	ts->length = 0;
	return ret;
}

// 返回线性表List存在的元素个数
//返回值 >=0 表示:该list存在的元素个数
//<0 表示error
int LinkStack_Length(LinkStack *list) {
	int ret = 0;
	if (list == NULL) {
		ret = -1;
		printf("func LinkStack_Length error bacesue list = NULL return ret = -1\n");
		return ret;
	}
	TLinkStack * ts = list;
	return ts->length;
}



//从LinkStack 中获取指定位置的数据
//参数pos:LinkStack中的位置
//返回值:为存储在该位置的元素
//返回NULL 表示有问题
LinkStackNode* LinkStack_Get(LinkStack *list) {
	LinkStackNode* ret = NULL;
	if (list == NULL) {
		ret = NULL;
		printf("func LinkStack_Get error bacesue list = NULL return ret = NULL\n");
		return ret;
	}
	TLinkStack * ts = list;
	if (ts->length==0) {
		ret = NULL;
		printf("func LinkStack_Get error bacesue ts->length = 0 return ret = NULL\n");
		return ret;
	}
	return ts->head.next;
}


//给LinkStack中指定位置插入数据,
//参数LinkStackNode为要插入的数据
//参数 pos 为要插入的位置
//成功返回1
//失败 返回<0

int LinkStack_Insert(LinkStack *list, LinkStackNode *node) {
	int ret = 1;
	if (list == NULL) {
		ret = -1;
		printf("func LinkStack_Insert error bacesue list = NULL return ret = -1\n");
		return ret;
	}
	TLinkStack * ts = list;
	node->next = ts->head.next;
	ts->head.next = node;
	ts->length++;
	return ret;
}


//从LinkList 中删除指定位置的元素
//参数 pos
//返回值为 删除的元素
//返回NULL 表示出现了error
LinkStackNode* LinkStack_Delete(LinkStack *list) {
	LinkStackNode* ret = NULL;
	if (list == NULL) {
		ret = NULL;
		printf("func LinkStack_Delete error bacesue list = NULL return ret = NULL\n");
		return ret;
	}
	TLinkStack * ts = list;
	if (ts->length == 0) {
		ret = NULL;
		printf("func LinkStack_Delete error bacesue ts->length = 0 return ret = NULL\n");
		return ret;
	}
	LinkStackNode * delnode = ts->head.next;
	ts->head.next = delnode->next;
	ts->length--;
	return delnode;

}

//判断当前linkstack 是否为null,如果为null,则返回1
//如果不为NULL,则返回0;
//有error 则返回-1
int isEmptyLinkStack(LinkStack *list) {
	int ret = 0;
	if (list == NULL) {
		ret = -1;
		printf("func isEmptyLinkStack error bacesue list = NULL return ret = -1\n");
		return ret;
	}
	TLinkStack * ts = list;
	int length = ts->length;
	if (length>0) {
		ret = 0;
	}
	else {
		ret = 1;
	}
	return ret;
}

#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC
#include "iostream"
#include <stdio.h>
#include <stdlib.h>

extern "C" {
#include "006linkstack.h"
}

typedef struct Teacher {
	LinkStackNode  linkstacknode;
	int age;
	char name[128];
	char *othername;
	char **stuname; //一个老师下面有5个学生
}Teacher;

int main() {
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口

	int ret = 0;
	//初始化队列,要动态的创建SeqStack,根据user设定的大小创建
//int stacksize ,表示user 要创建栈的大小
//创建失败返回NULL
	LinkStack* linkstack = LinkStack_Create();
	if (linkstack == NULL) {
		ret = -1;
		printf("func LinkStack_Create error because linkstack = NULL return ret =-1\n");
		return ret;
	}
	ret = isEmptyLinkStack(linkstack);
	printf("isEmptyLinkStack = ret %d\n", ret);

	ret = LinkStack_Length(linkstack);
	printf("LinkStack_Length = ret %d\n", ret);

	Teacher tea1;
	tea1.age = 20;
	strcpy(tea1.name, (const char*)"tea1");

	tea1.othername = (char *)malloc(sizeof(char) * 128);
	memset(tea1.othername, 0, sizeof(char) * 128);
	strcpy(tea1.othername, (const char*)"tea1othername");

	tea1.stuname = (char **)malloc(sizeof(char *) * 5);
	memset(tea1.stuname, 0, sizeof(char *) * 5);
	for (size_t i = 0; i < 5; i++)
	{
		tea1.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符
		memset(tea1.stuname[i], 0, sizeof(char) * 128);
		sprintf(tea1.stuname[i], "tea1stuname%d", i + 1);
	}



	Teacher tea2;
	tea2.age = 22;

	strcpy(tea2.name, (const char*)"tea2");

	tea2.othername = (char *)malloc(sizeof(char) * 128);
	memset(tea2.othername, 0, sizeof(char) * 128);
	strcpy(tea2.othername, (const char*)"tea2othername");

	tea2.stuname = (char **)malloc(sizeof(char *) * 5);
	memset(tea2.stuname, 0, sizeof(char *) * 5);
	for (size_t i = 0; i < 5; i++)
	{
		tea2.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符
		memset(tea2.stuname[i], 0, sizeof(char) * 128);
		sprintf(tea2.stuname[i], "tea2stuname%d", i + 1);
	}



	Teacher tea3;
	tea3.age = 33;
	strcpy(tea3.name, (const char*)"tea3");

	tea3.othername = (char *)malloc(sizeof(char) * 128);
	memset(tea3.othername, 0, sizeof(char) * 128);
	strcpy(tea3.othername, (const char*)"tea3othername");

	tea3.stuname = (char **)malloc(sizeof(char *) * 5);
	memset(tea3.stuname, 0, sizeof(char *) * 5);
	for (size_t i = 0; i < 5; i++)
	{
		tea3.stuname[i] = (char *)malloc(sizeof(char) * 128);//每个学生名字也有128个字符
		memset(tea3.stuname[i], 0, sizeof(char) * 128);
		sprintf(tea3.stuname[i], "tea3stuname%d", i + 1);
	}

	ret = LinkStack_Insert(linkstack, (LinkStackNode * )&tea1);
	if (ret < 0) {
		printf("LinkStack_Insert(linkstack, (LinkStackNode * )&tea1) func error ret =%d \n", ret);
		return ret;
	}

	ret = LinkStack_Insert(linkstack, (LinkStackNode *)&tea2);
	if (ret < 0) {
		printf("LinkStack_Insert(linkstack, (LinkStackNode * )&tea2) func error ret =%d \n", ret);
		return ret;
	}

	ret = LinkStack_Insert(linkstack, (LinkStackNode *)&tea3);
	if (ret < 0) {
		printf("LinkStack_Insert(linkstack, (LinkStackNode * )&tea3) func error ret =%d \n", ret);
		return ret;
	}

	printf("-after-\n");
	ret = isEmptyLinkStack(linkstack);
	printf("isEmptyLinkStack = ret %d\n", ret);

	ret = LinkStack_Length(linkstack);
	printf("LinkStack_Length = ret %d\n", ret);



	while (LinkStack_Length(linkstack) > 0) {
		Teacher * temptea = (Teacher *)LinkStack_Get(linkstack);
		if (temptea == NULL) {
			printf("can not get find teacher\n");
		}
		printf("temptea->age = %d,temptea->name = %s,temptea->othername=%s\n",
			temptea->age,
			temptea->name,
			temptea->othername);
		for (size_t j = 0; j < 5; j++)
		{
			printf("temptea->stuname[%d] = %s,  ",
				j, temptea->stuname[j]);
		}
		Teacher * deltea = (Teacher *)LinkStack_Delete(linkstack);
		if (deltea == NULL) {
			printf("LinkStack_Delete seqstack error\n");
		}
		if (deltea->othername != NULL) {
			free(deltea->othername);

		}
		if (deltea->stuname != NULL) {
			for (size_t i = 0; i < 5; i++)
			{
				if (deltea->stuname[i] != NULL) {
					free(deltea->stuname[i]);
				}
			}
			free(deltea->stuname);
			deltea->stuname = NULL;
		}

		printf("\n");
	}
	printf("sss\n");

	//销毁栈
	//成功 返回1 表示成功销毁栈 
	//失败 返回-1 表示该函数执行的时候有问题
	ret = LinkStack_Destory(linkstack);


	return 0;





}

相关应用:实现编译器中的符号成对检测

//几乎所有的编译器都具有检测括号是否匹配的能力,
//那么如何实现编译器中的符号成对检测?如下字符串:
//5 + 5 * (6) + 9 / 3 * 1) - (1 + 3(
//算法思路
//
//从第一个字符开始扫描
//当遇见普通字符时忽略,
//当遇见左括号时压入栈中
//当遇见右括号时从栈中弹出栈顶符号,并进行匹配
//匹配成功:继续读入下一个字符
//匹配失败:立即停止,并报错
//结束:
//成功 : 所有字符扫描完毕,且栈为空
//    失败:匹配失败或所有字符扫描完毕但栈非空

//总结:
//当需要检测成对出现但又互不相邻的事物时可以使用栈“后进先出”的特性

#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC
#include "iostream"
#include <stdio.h>
#include <stdlib.h>


//几乎所有的编译器都具有检测括号是否匹配的能力,
//那么如何实现编译器中的符号成对检测?如下字符串:
//5 + 5 * (6) + 9 / 3 * 1) - (1 + 3(
//算法思路
//
//从第一个字符开始扫描
//当遇见普通字符时忽略,
//当遇见左括号时压入栈中
//当遇见右括号时从栈中弹出栈顶符号,并进行匹配
//匹配成功:继续读入下一个字符
//匹配失败:立即停止,并报错
//结束:
//成功 : 所有字符扫描完毕,且栈为空
//	失败:匹配失败或所有字符扫描完毕但栈非空

//总结:
//当需要检测成对出现但又互不相邻的事物时可以使用栈“后进先出”的特性

char *err1 = (char *)"无法找到对应的右括号的 左括号";
char *err2 = (char *)"该 左括号 没有对应的有括号";

extern "C" {
#include "004seqstack.h"
}

int isLeft( char ch) {
	if ('(' == ch) {
		return 1;
	}
	return 0;
}

int isRight(char ch) {
	if (')' == ch) {
		return 1;
	}
	return 0;
}

void printerror(char* err,char *str, char *ptemp) {
	printf("err start");
	printf(err);
	printf("原始字符串如下\n");
	printf(str);
	printf("\n");
	printf("error位置如下\n");

	int num = ptemp - str;
	while (num > 0 ) {
		printf(" ");
		--num;
	}
	printf("|\n");
	printf("err end");
}

void testchar(char *str) {
	SeqStack * seqstack = createSeqStack(1024);
	if (seqstack ==NULL) {
		printf("func testchar error because seqstack==NULL\n");
		return;
	}

	if (str == NULL) {
		printf("testchar func error because str==NULL\n");
		return;
	}
	char *ptemp = str;//让辅助指针变量指向传递过来的str
	while (*(ptemp) != '\0') {
		if (isLeft(*ptemp)) { 当遇见左括号时压入栈中.判断是否是符号,如果是 左括号 符号,则要进栈,
			push_SeqStack(seqstack,ptemp);

		}
		if (isRight(*ptemp)) {//当遇见右括号时从栈中弹出栈顶符号,并进行匹配
			//如果这时候栈中啥也没有,就有问题,直接break;
			if (size_SeqStack(seqstack) == 0) {
				printerror(err1,str,ptemp);
				break;
			}
			pop_SeqStack(seqstack);
		}
		ptemp++;
	}
	//当将整个字符串都弄完成后,检查栈中是否有元素,如果栈中有元素,说明有左括号没有匹配
	while (size_SeqStack(seqstack) > 0 ) {
		printerror(err2, str, (char *)top_SeqStack(seqstack));
		pop_SeqStack(seqstack);
	}
}

int main() {
	int ret = 0;
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口
	//char* sourcestr = (char *)"5 + 5 * (6) + 9 / 3 * 1) - (1 + 3(";
	char* sourcestr = (char *)"5 + 5 * (6) + 9 / 3 * 1 - (1 + 3(";
	testchar(sourcestr);

	return ret;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

服装厂生产ERP有哪些功能

在当今竞争激烈的服装行业中&#xff0c;企业如何在保证产品质量的同时提高生产效率和市场响应速度?答案在于智能化的生产管理。ERP(企业资源计划)系统作为现代企业管理的核心工具&#xff0c;对于服装厂而言&#xff0c;它的功能不仅需要全面&#xff0c;更要针对性强、操作简…

Python浅谈清朝秋海棠叶版图

1、清朝疆域概述&#xff1a; 清朝是我国最后一个封建王朝&#xff0c;其始于1616年建州女真部努尔哈赤建立后金&#xff0c;此后统一女真各部、东北地区。后又降服漠南蒙古&#xff0c;1644年入关打败农民起义军、灭南明&#xff0c;削三藩&#xff0c;复台湾。后又收外蒙&am…

展馆设计中必不可少的场景

1、一般场景展营造 一般场景是经过对实物进行概括、提炼&#xff0c;进行符号化、审美化的处理后引入展示现场&#xff0c;而并不是将与展品有关联的事物统统罗列其中。 2、复原场景营造 复原场景营造常用于博物馆、纪念馆陈列展示中。运用复原场景就是为了营造历史上曾存在的&…

java中2个List集合值和顺序完全一样,如果判断他们相等

和判断2个字符串是否相等一样&#xff0c;List可以通过equals来判断2个集合是否相等 示例代码如下&#xff1a; 1、相等的示例 2、顺序不一致 3、值不一致

简单使用优雅的程序计数器-StopWatch

一、引入hutool-core 5.8.18包 二、代码 public static void main(String[] args) throws InterruptedException {StopWatch stopWatch new StopWatch("测试StopWatch");stopWatch.start("任务1");// 任务1花费1000毫秒Thread.sleep(1000);stopWatch.st…

Python入门与进阶

基础语法语句 在线python代码运行网址 &#xff08;推荐使用python3网址&#xff09; 基础语法&输入输出 python等号赋值 赋值类型描述示例基本赋值使用等号&#xff08;&#xff09;进行赋值。x10同一个值给多个变量可以使用一个值来赋值给多个变量。xyz10多重赋值可以…

Bentley二次开发教程27-交互窗口-界面开发方法

界面设计概述 引言 在我们掌握了交互式工具的使用方法后&#xff0c;在使用过程中会发现&#xff1a;虽然工具中拥有多种交互的手段&#xff0c;但仅凭工具中鼠标&#xff0c;特殊按键与信息提示等交互方法&#xff0c;没有办法同时对多个信息进行展示&#xff0c;也不够直观…

Redis底层数据结构之IntSet

目录 一、概述二、IntSet结构三、自动升级 redis底层数据结构已完结&#x1f44f;&#x1f44f;&#x1f44f;&#xff1a; ☑️redis底层数据结构之SDS☑️redis底层数据结构之ziplist☑️redis底层数据结构之quicklist☑️redis底层数据结构之Dict☑️redis底层数据结构之Int…

java开发之路——用户管理中心_简单初始化

用户管理中心_简单初始化 (一) 初始化项目1. 使用 Ant Design Pro(现成的管理系统) 进行前端初始化2. 后端初始化三种初始化java项目 (二) 遇到的问题【问题1】Ant design pro页面打不开&#xff0c;一直在budiling控制台出现错误error-./src/components/index.ts【问题2】初始…

ROS python实现乌龟跟随

产生两只乌龟&#xff0c;中间的乌龟(A) 和 左下乌龟(B), B 会自动运行至A的位置&#xff0c;并且键盘控制时&#xff0c;只是控制 A 的运动&#xff0c;但是 B 可以跟随 A 运行 乌龟跟随实现的核心&#xff0c;是乌龟A和B都要发布相对世界坐标系的坐标信息&#xff0c;然后&am…

按钮获取验证码倒计时60秒

把倒计时存在缓存里刷新页面依旧是接着倒计时 <el-buttonsize"large"class"btnStyle":class"btnStyleClass":style"buttonStyle":disabled"countdownActive"click"handleClick">{{ buttonText }}</el-b…

算法-KMP算法

时间复杂度&#xff1a; public int strStr(String haystack, String needle) {int[] next new int[needle.length()];//next数组的生成next[0] 0;int prefixLen 0;//共同前后缀长度int i 1, j 1;//i,j复用while (i < needle.length()) {if (needle.charAt(prefixLen)…

Shader实战(3):贴图像素化风格实现

话不多说&#xff0c;将以下shader赋给材质贴上贴图即可。 Shader "HQY/Shader2" //自己改名 {Properties{_Diffuse ("Diffuse", Color) (1,1,1,1)_MainTex ("MainTex", 2D) "white" {}_Specular("Specular", Color) (…

AI伙伴是什么

AI伙伴&#xff0c;或称为人工智能伙伴&#xff0c;是指能够执行特定任务、协助人类活动&#xff0c;甚至进行社交互动的智能系统。 编辑搜图 请点击输入图片描述&#xff08;最多18字&#xff09; AI伙伴通常是通过集成了先进的技术如语音识别、语义理解和图像识别等来实现与…

ubuntu扩展根目录磁盘空间

ubuntu扩展根目录磁盘空间 扩展虚拟机磁盘空间 查看现有磁盘状态 查询现有分区状态&#xff0c;/dev/sda是我们要扩展的磁盘 fdisk -l 开始进行磁盘空间的扩容 parted /dev/sda#扩展3号分区的空间 resizepart 3刷新分区空间 resize2fs /dev/sda3查询扩展结果&#xff0c;…

Golang GMP解读

概念梳理 1. 1 线程 通常语义中的线程&#xff0c;指的是内核级线程&#xff0c;核心点如下&#xff1a; 是操作系统最小调度单元&#xff1b;创建、销毁、调度交由内核完成&#xff0c;cpu 需完成用户态与内核态间的切换&#xff1b;可充分利用多核&#xff0c;实现并行. …

HTTP 网络协议请求的消息结构,具体详解(2024-04-25)

一、简介 HTTP 是基于客户端/服务端&#xff08;C/S&#xff09;的架构模型&#xff0c;通过一个可靠的链接来交换信息&#xff0c;是一个无状态的请求/响应协议。 HTTP 消息是客户端和服务器之间通信的基础&#xff0c;它们由一系列的文本行组成&#xff0c;遵循特定的格式和…

热门项目!知识付费小程序源码系统 带完整的安装代码包以及安装部署教程

近年来&#xff0c;随着在线教育、知识分享等领域的蓬勃发展&#xff0c;知识付费市场逐渐壮大。越来越多的用户愿意为高质量的知识内容付费&#xff0c;而企业和个人也看到了知识付费的巨大商机。然而&#xff0c;对于许多没有技术背景的用户来说&#xff0c;搭建一个稳定、易…

自定义数据 微调CLIP (结合paper)

CLIP 是 Contrastive Language-Image Pre-training 的缩写&#xff0c;是一个擅长理解文本和图像之间关系的模型&#xff0c;下面是一个简单的介绍&#xff1a; 优点&#xff1a; CLIP 在零样本学习方面特别强大&#xff0c;它可以&#xff08;用自然语言&#xff09;给出图像…

AI Agent新对决:LangGraph与AutoGen的技术角力

AI Agent变革未来&#xff0c;LangGraph对抗AutoGen ©作者|Blaze 来源|神州问学 引言 比尔.盖茨曾在他的博客上发表一篇文章&#xff1a;《AI is about to completely change how you use computers》。在文章中&#xff0c;比尔盖茨探讨AI Agent对我们未来生活的巨大影…