【AI Agent系列】【MetaGPT多智能体学习】6. 多智能体实战 - 基于MetaGPT实现游戏【你说我猜】(附完整代码)

本系列文章跟随《MetaGPT多智能体课程》(https://github.com/datawhalechina/hugging-multi-agent),深入理解并实践多智能体系统的开发。

本文为该课程的第四章(多智能体开发)的第四篇笔记。今天我们来完成第四章的作业:

基于 env 或 team 设计一个你的多智能体团队,尝试让他们完成 你画我猜文字版 ,要求其中含有两个agent,其中一个agent负责接收来自用户提供的物体描述并转告另一个agent,另一个agent将猜测用户给出的物体名称,两个agent将不断交互直到另一个给出正确的答案

系列笔记

  • 【AI Agent系列】【MetaGPT多智能体学习】0. 环境准备 - 升级MetaGPT 0.7.2版本及遇到的坑
  • 【AI Agent系列】【MetaGPT多智能体学习】1. 再理解 AI Agent - 经典案例和热门框架综述
  • 【AI Agent系列】【MetaGPT多智能体学习】2. 重温单智能体开发 - 深入源码,理解单智能体运行框架
  • 【AI Agent系列】【MetaGPT多智能体学习】3. 开发一个简单的多智能体系统,兼看MetaGPT多智能体运行机制
  • 【AI Agent系列】【MetaGPT多智能体学习】4. 基于MetaGPT的Team组件开发你的第一个智能体团队
  • 【AI Agent系列】【MetaGPT多智能体学习】5. 多智能体案例拆解 - 基于MetaGPT的智能体辩论(附完整代码)

文章目录

  • 系列笔记
  • 0. 需求分析
  • 1. 写代码 - 初版
    • 1.1 智能体1 - Describer实现
      • 1.1.1 Action定义 - DescribeWord
      • 1.1.2 Role定义 - Describer
    • 1.2 智能体2 - Guesser实现
      • 1.2.1 Action定义 - GuessWord
      • 1.2.2 Role定义 - Gusser
    • 1.3 定义Team,运行及结果
  • 2. 修改代码 - 效果优化
    • 2.1 存在的问题及分析
    • 2.2 Prompt优化
    • 2.3 回答正确后如何立刻停止游戏
    • 2.4 如何输出“游戏失败”的结果
  • 3. 完整代码
  • 4. 拓展 - 与人交互,人来猜词
  • 5. 总结

0. 需求分析

从上面的需求描述来看,你说我猜 游戏需要两个智能体:

  • 智能体1:Describer,用来接收用户提供的词语,并给出描述
  • 智能体2:Guesser,用来接收智能体1的描述,猜词

1. 写代码 - 初版

1.1 智能体1 - Describer实现

智能体1 Describer的任务是根据用户提供的词语,用自己的话描述出来。

1.1.1 Action定义 - DescribeWord

重点是 Prompt,这里我设置的Prompt接收两个参数,第一个参数word为用户输入的词语,也就是答案。第二个参数是Describer智能体的描述历史,因为在实际游戏过程中,描述是不会与前面的描述重复的。另外还设置了每次描述最多20个字,用来限制token的消耗。

class DescribeWord(Action):
    """Action: Describe a word in your own language"""
    
    PROMPT_TMPL: str = """
    ## 任务
    你现在在玩一个你画我猜的游戏,你需要用你自己的语言来描述"{word}"
    
    ## 描述历史
    之前你的描述历史:
    {context}
    
    ## 你必须遵守的限制
    1. 描述长度不超过20个字
    2. 描述中不能出现"{word}"中的字
    3. 描述不能与描述历史中的任何一条描述相同
    
    """
    
    name: str = "DescribeWord"
    
    async def run(self, context: str, word: str):
        prompt = self.PROMPT_TMPL.format(context=context, word=word)
        logger.info(prompt)
        
        rsp = await self._aask(prompt)
        print(rsp)
        return rsp

1.1.2 Role定义 - Describer

(1)设置其 Action 为 DescribeWord
(2)设置其关注的消息来源为 UserRequirement 和 GuessWord
(3)重点重写了 _act 函数。

因为前面的Prompt中需要历史的描述信息,而描述是其自身发出的,因此历史描述信息的获取为:

if msg.sent_from == self.name:
    context = "\n".join(f"{msg.content}") # 自己的描述历史

另外,也在这里加了判断是否猜对了词语的逻辑:

elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:
    print("回答正确!")
    return Message()

当回答对了之后,直接返回。

完整代码如下:

class Describer(Role):
    name: str = "Describer"
    profile: str = "Describer"
    word: str = ""

    def __init__(self, **data: Any):
        super().__init__(**data)
        self.set_actions([DescribeWord])
        self._watch([UserRequirement, GuessWord])

    async def _act(self) -> Message:
        logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
        todo = self.rc.todo  # An instance of DescribeWord

        memories = self.get_memories() # 获取全部的记忆
        context = ""
        for msg in memories:
            if msg.sent_from == self.name:
                context = "\n".join(f"{msg.content}") # 自己的描述历史
            elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:
                print("回答正确!")
                return Message()
        print(context)

        rsp = await todo.run(context=context, word=self.word)

        msg = Message(
            content=rsp,
            role=self.profile,
            cause_by=type(todo),
            sent_from=self.name,
        )
        self.rc.memory.add(msg)

        return msg

1.2 智能体2 - Guesser实现

智能体2 - Guesser,用来接收智能体1的描述,猜词。

1.2.1 Action定义 - GuessWord

与 DescribeWord Action的Prompt类似,猜词的Prompt接收一个context来表示之前它的猜词历史,避免它老重复猜同一个词,陷入死循环。然后一个description来接收Describer的描述语句。

class GuessWord(Action):
    """Action: Guess a word from the description"""
    
    PROMPT_TMPL: str = """
    ## 背景
    你现在在玩一个你画我猜的游戏,你的任务是根据给定的描述,猜一个词语。
    
    ## 猜测历史
    之前你的猜测历史:
    {context}
    
    ## 轮到你了
    现在轮到你了,你需要根据描述{description}猜测一个词语,并遵循以下限制:
    ### 限制
    1. 猜测词语不超过5个字
    2. 猜测词语不能与猜测历史重复
    3. 只输出猜测的词语,NO other texts
    
    """
    
    name: str = "GuessWord"
    
    async def run(self, context: str, description: str):
        prompt = self.PROMPT_TMPL.format(context=context, description=description)
        logger.info(prompt)
        
        rsp = await self._aask(prompt)
        return rsp

1.2.2 Role定义 - Gusser

(1)设置其 Action 为 GuessWord
(2)设置其关注的消息来源为 DescribeWord
(3)重点重写了 _act 函数。

因为前面的Prompt中需要历史的猜词信息,而猜词是其自身发出的,因此猜词历史信息的获取为:

if msg.sent_from == self.name:
   context = "\n".join(f"{msg.content}")

Describer的描述信息获取为:

elif msg.sent_from == "Describer":
    description = "\n".join(f"{msg.content}")

完整代码如下:


class Gusser(Role):
    name: str = "Gusser"
    profile: str = "Gusser"

    def __init__(self, **data: Any):
        super().__init__(**data)
        self.set_actions([GuessWord])
        self._watch([DescribeWord])

    async def _act(self) -> Message:
        logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
        todo = self.rc.todo  # An instance of DescribeWord

        memories = self.get_memories() # 获取全部的记忆
        context= ""
        description = ""
        for msg in memories:
            if msg.sent_from == self.name:
                context = "\n".join(f"{msg.content}")
            elif msg.sent_from == "Describer":
                description = "\n".join(f"{msg.content}")
        print(context)

        rsp = await todo.run(context=context, description=description)

        msg = Message(
            content=rsp,
            role=self.profile,
            cause_by=type(todo),
            sent_from=self.name,
        )
        self.rc.memory.add(msg)
        
        print(rsp)
        return msg

1.3 定义Team,运行及结果

async def start_game(idea: str, investment: float = 3.0, n_round: int = 10):
    
    team = Team()
    team.hire(
        [
            Describer(word=idea),
            Gusser(), 
        ])
    team.invest(investment)
    team.run_project(idea)
    await team.run(n_round=n_round)

def main(idea: str, investment: float = 3.0, n_round: int = 10):
    if platform.system() == "Windows":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    asyncio.run(start_game(idea, investment, n_round))

if __name__ == "__main__":
    fire.Fire(main("篮球"))

运行结果如下:

智能体产生描述:
在这里插入图片描述

猜词,检测结果:

在这里插入图片描述
可以看到,运行成功了,也能进行简单的交互。但是还是能看出不少问题的。

下面是进一步优化的过程。

2. 修改代码 - 效果优化

2.1 存在的问题及分析

(1)猜对答案后,它后面还是在循环运行,直到运行完刚开始设置的运行轮数:n_round: int = 10。如上面的运行结果,后面一直在输出“回答正确”。

(2)看下图的运行结果,回答了英文,导致一直认为不是正确答案。并且一直在重复这个词,所以,Prompt还需要优化:

在这里插入图片描述

(3)10轮后结束运行,如果这时候没有猜对答案,没有输出“你失败了”类似的文字。

总结下主要问题:

  • 回答正确后如何立刻停止游戏
  • Prompt需要优化
  • 如何输出“游戏失败”的结果

2.2 Prompt优化

Prompt优化的原则是,有啥问题堵啥问题…

(1)它既然输出了英文词语,那就限制它不让它输出英文单词,只输出中文。
(2)它重复输出了之前的猜词,说明猜词历史的限制没有生效,改变话术各种试(没有好的方法,只有各种试)。

修改之后的 Prompt:

class DescribeWord(Action):
    """Action: Describe a word in your own language"""
    
    PROMPT_TMPL: str = """
    ## 任务
    你现在在玩一个你画我猜的游戏,你需要用你自己的语言来描述"{word}"
    
    ## 描述历史
    之前你的描述历史:
    {context}
    
    ## 你必须遵守的限制
    1. 描述长度不超过20个字
    2. 描述中不能出现与"{word}"中的任何一个字相同的字,否则会有严重的惩罚。例如:描述的词为"雨伞",那么生成的描述中不能出现"雨","伞","雨伞"
    3. 描述不能与描述历史中的任何一条描述相同, 例如:描述历史中已经出现过"一种工具",那么生成的描述就不能再是"一种工具"
    
    """
class GuessWord(Action):
    """Action: Guess a word from the description"""
    
    PROMPT_TMPL: str = """
    ## 任务
    你现在在玩一个你画我猜的游戏,你需要根据描述"{description}"猜测出一个词语
    
    ## 猜测历史
    之前你的猜测历史:
    {context}
    
    ### 你必须遵守的限制
    1. 猜测词语不超过5个字,词语必须是中文
    2. 猜测词语不能与猜测历史重复
    3. 只输出猜测的词语,NO other texts
    
    """

优化之后的运行效果,虽然还是有点小问题(描述中出现了重复和出现了答案中的字),但最终效果还行吧… :

在这里插入图片描述

2.3 回答正确后如何立刻停止游戏

await team.run(n_round=n_round) 之后,不运行完 n_round 是不会返回的,而 Team 组件目前也没有接口来设置停止运行。因此想要立刻停止游戏,用Team组件几乎是不可能的(有方法的欢迎指教)。

所以我想了另一种办法:既然无法立刻停止游戏,那就停止两个智能体的行动,让他们一直等待n_round完就行了,就像等待游戏时间结束。

代码修改也很简单:

elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:
    print("回答正确!")
    return ""

只要在回答正确后,直接return一个空字符串就行。为什么这样就可以?看源码:

def publish_message(self, msg):
    """If the role belongs to env, then the role's messages will be broadcast to env"""
    if not msg:
        return

在运行完动作_act后,往环境中放结果消息,如果为空,就不忘环境中放消息了。这样Guesser也就接收不到 Describer 的消息,也就不动作了。剩下的 n_round 就是在那空转了。

看下运行效果:

在这里插入图片描述
可以看到,只输出了一次“回答正确”,之后就没有其余打印了,直到程序结束。

2.4 如何输出“游戏失败”的结果

如果 n_round 运行完之后,还没有猜对结果,就要宣告游戏失败了。怎么获取这个结果呢?

程序运行结束,只能是在这里返回:await team.run(n_round=n_round)

我们将它的返回值打出来看下是什么:

result = await team.run(n_round=n_round)
print(result)

打印结果如下:

在这里插入图片描述
可以看到它的返回结果就是所有的对话历史。那么判断游戏是否失败就好说了,有很多种方法,例如直接比较用户输入的词语是否与这个结果中的最后一行相同:

result = result.split(':')[-1].strip(' ')
if (result.find(idea) != -1):
    print("恭喜你,猜对了!")
else:
    print("很遗憾,你猜错了!")

运行效果:

在这里插入图片描述

3. 完整代码


import asyncio
from typing import Any
import platform

import fire

from metagpt.actions import Action, UserRequirement
from metagpt.logs import logger
from metagpt.roles import Role
from metagpt.schema import Message
from metagpt.team import Team

class DescribeWord(Action):
    """Action: Describe a word in your own language"""
    
    PROMPT_TMPL: str = """
    ## 任务
    你现在在玩一个你画我猜的游戏,你需要用你自己的语言来描述"{word}"
    
    ## 描述历史
    之前你的描述历史:
    {context}
    
    ## 你必须遵守的限制
    1. 描述长度不超过20个字
    2. 描述中不能出现与"{word}"中的任何一个字相同的字,否则会有严重的惩罚。例如:描述的词为"雨伞",那么生成的描述中不能出现"雨","伞","雨伞"
    3. 描述不能与描述历史中的任何一条描述相同, 例如:描述历史中已经出现过"一种工具",那么生成的描述就不能再是"一种工具"
    
    """
    
    name: str = "DescribeWord"
    
    async def run(self, context: str, word: str):
        prompt = self.PROMPT_TMPL.format(context=context, word=word)
        logger.info(prompt)
        
        rsp = await self._aask(prompt)
        # print(rsp)
        return rsp
    
class GuessWord(Action):
    """Action: Guess a word from the description"""
    
    PROMPT_TMPL: str = """
    ## 任务
    你现在在玩一个你画我猜的游戏,你需要根据描述"{description}"猜测出一个词语
    
    ## 猜测历史
    之前你的猜测历史:
    {context}
    
    ### 你必须遵守的限制
    1. 猜测词语不超过5个字,词语必须是中文
    2. 猜测词语不能与猜测历史重复
    3. 只输出猜测的词语,NO other texts
    
    """
    
    name: str = "GuessWord"
    
    async def run(self, context: str, description: str):
        prompt = self.PROMPT_TMPL.format(context=context, description=description)
        logger.info(prompt)
        
        rsp = await self._aask(prompt)
        return rsp

class Describer(Role):
    name: str = "Describer"
    profile: str = "Describer"
    word: str = ""

    def __init__(self, **data: Any):
        super().__init__(**data)
        self.set_actions([DescribeWord])
        self._watch([UserRequirement, GuessWord])

    async def _act(self) -> Message:
        logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
        todo = self.rc.todo  # An instance of DescribeWord

        memories = self.get_memories() # 获取全部的记忆
        context = ""
        for msg in memories:
            if msg.sent_from == self.name:
                context += f"{msg.content}\n" # 自己的描述历史
            elif msg.sent_from == "Gusser" and msg.content.find(self.word) != -1:
                print("回答正确!")
                return ""
        # print(context)

        rsp = await todo.run(context=context, word=self.word)

        msg = Message(
            content=rsp,
            role=self.profile,
            cause_by=type(todo),
            sent_from=self.name,
        )
        self.rc.memory.add(msg)

        return msg
    
class Gusser(Role):
    name: str = "Gusser"
    profile: str = "Gusser"

    def __init__(self, **data: Any):
        super().__init__(**data)
        self.set_actions([GuessWord])
        self._watch([DescribeWord])

    async def _act(self) -> Message:
        logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
        todo = self.rc.todo  # An instance of DescribeWord

        memories = self.get_memories() # 获取全部的记忆
        context= ""
        description = ""
        for msg in memories:
            if msg.sent_from == self.name:
                context += f"{msg.content}\n"
            elif msg.sent_from == "Describer":
                description += f"{msg.content}\n"
        print(context)

        rsp = await todo.run(context=context, description=description)

        msg = Message(
            content=rsp,
            role=self.profile,
            cause_by=type(todo),
            sent_from=self.name,
        )
        self.rc.memory.add(msg)
        
        # print(rsp)

        return msg

async def start_game(idea: str, investment: float = 3.0, n_round: int = 10):
    
    team = Team()
    team.hire(
        [
            Describer(word=idea),
            Gusser(), 
        ])
    team.invest(investment)
    team.run_project(idea)
    result = await team.run(n_round=n_round)
    result = result.split(':')[-1].strip(' ')
    if (result.find(idea) != -1):
        print("恭喜你,猜对了!")
    else:
        print("很遗憾,你猜错了!")

def main(idea: str, investment: float = 3.0, n_round: int = 3):
    if platform.system() == "Windows":
        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
    asyncio.run(start_game(idea, investment, n_round))

if __name__ == "__main__":
    fire.Fire(main("打篮球运行"))

4. 拓展 - 与人交互,人来猜词

可以做下拓展,将猜词的Role换成你自己,你自己来猜词,与智能体进行交互。这实现起来比较简单。

代表人的智能体,只需要在实例化智能体时,将 Role 的 is_human 属性置为 true 即可:

team.hire(
        [
            Describer(word=idea),
            Gusser(is_human=True),  # is_human=True 代表这个角色是人类,需要你的输入
        ])

运行效果:

在这里插入图片描述
还可以引入另一个智能体来自动出词语。大家可以思考下应该怎么实现。

5. 总结

本文我们利用MetaGPT的Team组件实现了一个“你说我猜”的游戏。因为游戏比较简单,所以整体逻辑也比较简单。重点在于Prompt优化比较费劲,还有就是要注意何时结束游戏等细节。最后,也向大家展示了一下如何让人参与到游戏中。


站内文章一览

在这里插入图片描述

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

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

相关文章

深度学习需要掌握哪些数学基础?

《深度学习的数学》这本书再合适不过了。作者罗纳德.T.纽塞尔(Ronald T. Kneusel),拥有超过 20年的机器学习行业经验。 本书适合有一定深度学习基础、了解Python编程语言的读者阅读,也可作为用于拓展深度学习理论的参考书。 为什么…

SQL 术语:Join 中的 Build 和 Probe 是什么意思?

博主历时三年精心创作的《大数据平台架构与原型实现:数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行,点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,…

vue+springboot项目部署服务器

项目仓库:vuespringboot-demo: vuespringboot增删改查的demo (gitee.com) ①vue中修改配置 在public文件夹下新建config.json文件: {"serverUrl": "http://localhost:9090"//这里localhost在打包后记得修改为服务器公网ip } 然后…

Linux: Network: socket: sendto 如果返回0,是否一定代表发送成功?

最近遇到一个问题,虽然应用层使用的系统调用send已经返回成功,而且没有错误日志产生,也没有errno的设置。那是不是代表一定是没有问题?从抓包的结果看,虽然上层应用已经显示发出去,但是实际抓包的时候&…

WP外贸营销型网站模板

WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题,适合时尚服装行业搭建wordpress企业官网使用。 零件配件WordPress外贸建站模板 汽车行业零配件WordPress外贸建站模板,卖配件、零件的外贸公司可以使用的WordPress主题。 https://www.jia…

windows 系统上搭建 Phpstudy 集成环境 + DVWA 靶场!超详细教程!

作为安全测试或渗透测试学习者,需要搭建一些靶场来进行技术练习,靶场类型有很多,搭建方式也支持多样,本文给你详细介绍windows系统下如何通过phpstudy集成环境搭建DVWA靶场! 一、前言 网站是由中间件、网站程序、数据库…

暗九之凶险,更甚于明九

俗话说“逢九必衰”,逢九年是人运程变化的一个过程,这是古人长期以来对于命运的一种总结。“九”是转弯之数,故 “逢九”之人当年的运程容易大起大落、易招变数,若是严重一些,则有可能会殒命在这一年,一定要…

【计算机网络通信】计算机之间的局域网通信和互联网通信方法(附Python和C#代码)

文章目录 前言一、局域网通信1.1 基本原理和方法1.1.1 获取本地ip1.1.2 实现局域网内的广播1.1.3 进行局域网通信 1.2 实现多客户端连接1.3 Python源码1.4 C#源码1.5 可能存在的问题 二、互联网通信2.1 实现原理2.1.1 内网穿透软件2.1.2 实现互联网通信 2.2 Python源码2.3 C#源…

中国电子学会2019年12月份青少年软件编程Scratch图形化等级考试试卷四级真题。

第 1 题 【 单选题 】 1.以下模块,可以“说”出“我喜欢Apple”的是? A: B: C: D: 2.某学校为教师外出提供车辆服务,当外出人数小于5人时,派轿车;当外出人数为5至7人的话…

初阶数据结构:二叉树

目录 1. 树的相关概念1.1 简述:树1.2 树的概念补充 2. 二叉树2.1 二叉树的概念2.2 二叉树的性质2.3 二叉树的存储结构与堆2.3.1 存储结构2.3.2 堆的概念2.3.3 堆的实现2.3.3.1 堆的向上调整法2.3.3.2 堆的向下调整算法2.3.3.3 堆的实现 1. 树的相关概念 1.1 简述&a…

链表基础知识详解(非常详细简单易懂)

概述: 链表作为 C 语言中一种基础的数据结构,在平时写程序的时候用的并不多,但在操作系统里面使用的非常多。不管是RTOS还是Linux等使用非常广泛,所以必须要搞懂链表,链表分为单向链表和双向链表,单向链表很…

[Linux]如何理解kernel、shell、bash

文章目录 概念总览kernelshell&bash 概念总览 内核(kernel) ,外壳(shell) ,bash kernel kernel是指操作系统中的核心部分,用户一般是不能直接使用kernel的。它主要负责管理硬件资源和提供系统服务,如内存管理、进程管理、文件…

国内chatgpt写作软件,chatgpt国内使用

随着人工智能技术的不断发展,国内涌现出了一些基于ChatGPT模型的写作软件,这些软件不仅能够实现智能化的文章写作,还支持批量生成各种类型的文章。本文将深入探讨国内ChatGPT写作软件,以及它们在批量文章创作方面的应用与优势。 C…

如何使用Docker搭建StackEdit编辑器并结合内网穿透实现远程办公

文章目录 前言1. ubuntu安装VNC2. 设置vnc开机启动3. windows 安装VNC viewer连接工具4. 内网穿透4.1 安装cpolar【支持使用一键脚本命令安装】4.2 创建隧道映射4.3 测试公网远程访问 5. 配置固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址5.3 测试…

K线实战分析系列之十七:三法形态——接连犹豫后再次坚定

K线实战分析系列之十七:三法形态——接连犹豫后再次坚定 一、三法形态二、总结三法形态 一、三法形态 前后两根长K线中间夹了三根短小的K线 二、总结三法形态 中间的几根小阴线数量限制没有那么严苛中间小K线的颜色不一定是依次下降的小阴线或小阳线,也…

NOC2023软件创意编程(学而思赛道)python小高组复赛真题

目录 下载原文档打印做题: 软件创意编程 一、参赛范围 1.参赛组别:小学低年级组(1-3 年级)、小学高年级组(4-6 年级)、初中组。 2.参赛人数:1 人。 3.指导教师:1 人(可空缺)。 4.每人限参加 1 个赛项。 组别确定:以地方教育行政主管部门(教委、教育厅、教育局) 认…

【C++】vector的使用和模拟实现(超级详解!!!!)

文章目录 前言1.vector的介绍及使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector 空间增长问题1.2.3 vector 增删查改1.2.4 vector 迭代器失效问题。(重点!!!!!!)1.2.5 vector 在OJ中有关的练习题 2.ve…

朱维群将出席用碳不排碳碳中和顶层科技路线设计开发

演讲嘉宾:朱维群 演讲题目:“用碳不排碳”碳中和顶层科技路线设计开发 简介 姓名:朱维群 性别:男 出生日期:1961-09-09 职称:教授 1998年毕业于大连理工大学精细化工国家重点实验室精细化工专业&…

AWTK 开源串口屏开发(11) - 天气预报

# AWTK 开源串口屏开发 - 天气预报 天气预报是一个很常用的功能,在很多设备上都有这个功能。实现天气预报的功能,不能说很难但是也绝不简单,首先需要从网上获取数据,再解析数据,最后更新到界面上。 在 AWTK 串口屏中…

探索那些能唤起情感共鸣的壁纸

1、方小童在线工具集 网址: 方小童 该网站是一款在线工具集合的网站,目前包含PDF文件在线转换、随机生成美女图片、精美壁纸、电子书搜索等功能,喜欢的可以赶紧去试试!
最新文章