【正点原子STM32连载】第五十八章 T9拼音输入法实验摘自【正点原子】STM32F103 战舰开发指南V1.2

news2025/2/4 16:00:25

1)实验平台:正点原子stm32f103战舰开发板V4
2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420
3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html#

第五十八章 T9拼音输入法实验

本章,我们将介绍如何在STM32板子上实现一个简单的T9中文拼音输入法。本章分为如下几个小节:
58.1 拼音输入法简介
58.2 硬件设计
58.3 程序设计
58.4 下载验证

58.1 拼音输入法简介
在计算机上汉字的输入法有很多种,比如拼音输入法、五笔输入法、笔画输入法、区位输入法等。其中,又以拼音输入法用的最多。拼音输入法又可以分为很多类,比如全拼输入、双拼输入等。
而在手机上,用的最多的应该算是T9拼音输入法了,T9输入法全名为智能输入法,字库容量九千多字,支持十多种语言。T9输入法是由美国特捷通讯(Tegic Communications)软件公司开发的,该输入法解决了小型掌上设备的文字输入问题,已经成为全球手机文字输入的标准之一。
一般情况下,手机拼音输入键盘如图58.1.1所示:
在这里插入图片描述

图58.1.1 手机拼音输入键盘
在这个键盘上,我们对比下传统的输入法和 T9 输入法,输入“中国”两个字需要的按键次数。传统的方法,先按4次9,输入字母z,再按2次4,输入字母 h,再按3次6,输入字母o,再按2次6,输入字母n,最后按1次4,输入字母g。这样,输入“中”字,要按键12 次,接着同样的方法,输入“国”字,需要按6次,总共就是18次按键。
如果是T9,我们输入“中”字,只需要输入:9、4、6、6、4,即可实现输入“中”字,在选择“中”字之后,T9会联想出一系列同“中”字组合的词,如:文、国、断、山等。这样输入“国”字,我们直接选择即可,所以输入“国”字按键0次,这样使用T9输入法总共只需要5次按键。
这就是T9智能输入法的优越之处。正因为T9输入法高效便捷的输入方式得到了众多手机厂商的采用,以至于T9成为了使用频率最高知名度最大的手机输入法。
在本实验中,我们实现的T9拼音输入法,没有真正的T9那么强大,我们这里仅实现输入部分,不支持词组联想。
58.2 硬件设计

  1. 例程功能
    开机的时候先检测字库,然后显示提示信息和绘制拼音输入表,之后进入等待输入状态。此时用户可以通过屏幕上的拼音输入表输入拼音数字串(通过DEL可以实现退格),然后程序自动检测与之对应的拼音和汉字,并显示在屏幕上(同时输出到串口)。如果有多个匹配的拼音,则通过KEY_UP和KEY1进行选择。按键KEY0用于清除一次输入,按键KEY2用于触摸屏校准。LED0闪烁用于提示程序正在运行。
  2. 硬件资源
    1)LED灯
    LED0 – PB5
    2)独立按键
    KEY0 – PE4
    KEY1 – PE3
    WK_UP – PA0
    3)串口1
    4)正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
    5)NOR FLASH,通过SPI2驱动,我们需要里面的汉字库
    58.3 程序设计
    58.3.1 程序流程图
    在这里插入图片描述

图58.3.1.1 T9拼音输入法实验程序流程图
我们通过LCD的绘制算法生成一个9宫格输入法,采集到对应的合法输入点后,我们把这些信息传给解码库进行解码,识别出对应的拼音,并调用汉字库显示对应的匹配汉字。
58.3.2 程序解析
1.T9拼音输入法代码
这里我们只讲解核心代码,详细的源码请大家参考光盘本实验对应源码,T9拼音输入法的驱动源码包括pyinput.c、pyinput.h和pymb.h三个文件。
首先我们先介绍一下定义在pymb.h中的拼音索引。先介绍一下汉字排列表,该表将汉字拼音所有可能的组合都列出来了,如下所示:
/* 汉字排列表 */

const uint8_t PY_mb_space 	[]={""};
const uint8_t PY_mb_a     	[]={"啊阿腌吖锕厑嗄錒呵腌"};
const uint8_t PY_mb_ai    	[]={"爱埃挨哎唉哀皑癌蔼矮艾碍隘捱嗳嗌嫒瑷暧砹锿霭"};
…………此处省略N多个组合…………
const uint8_t PY_mb_zu    	[]={"足组卒族租祖诅阻俎菹镞"};
const uint8_t PY_mb_zuan  	[]={"钻攥纂缵躜"};
const uint8_t PY_mb_zui   	[]={"最罪嘴醉蕞觜"};
const uint8_t PY_mb_zun   	[]={"尊遵樽鳟撙"};
const uint8_t PY_mb_zuo   	[]={"左佐做作坐座昨撮唑柞阼琢嘬怍胙祚砟酢"};

这里我们只列出了部分组合,我们将这些组合称之为码表,然后将这些码表和其对应的数字串对应起来,组成一个拼音索引表,如下所示:
/* 拼音索引表 */

const py_index py_index3[]=
{
{"" ,"",(uint8_t*)PY_mb_space},
{"2","a",(uint8_t*)PY_mb_a},
{"3","e",(uint8_t*)PY_mb_e},
{"6","o",(uint8_t*)PY_mb_o},
{"24","ai",(uint8_t*)PY_mb_ai},
…………此处省略N多个组合…………
{"94664","zhong",(uint8_t*)PY_mb_zhong},
{"94824","zhuai",(uint8_t*)PY_mb_zhuai},
{"94826","zhuan",(uint8_t*)PY_mb_zhuan},
{"248264","chuang",(uint8_t*)PY_mb_chuang},
{"748264","shuang",(uint8_t*)PY_mb_shuang},
{"948264","zhuang",(uint8_t*)PY_mb_zhuang},
};
其中py_index是一个结构体,定义如下:
/* 拼音码表与拼音的对应表 */
typedef struct
{
  uint8_t *py_input;    	/* 输入的字符串 */
  uint8_t *py;          	/* 对应的拼音 */
  uint8_t *pymb;        	/* 码表 */
}py_index;

其中py_input,即与拼音对应的数字串,比如“94824”。py,即与py_input数字串对应的拼音,如果py_input = “94824”,那么py就是“zhuai”。最后pymb就是我们前面说到的码表。注意,一个数字串可以对应多个拼音,也可以对应多个码表。
有了这个拼音索引表(py_index3)之后,我们只需要将输入的数字串和py_index3索引表里面所有成员的py_input对比,将所有完全匹配的情况记录下来,用户要输入的汉字就被确定了,然后由用户选择可能的拼音组成(假设有多个匹配的项目),再选择对应的汉字,即完成一次汉字输入。
当然还可能是找遍了索引表,也没有发现一个完全符合要求的成员,那么我们会统计匹配数最多的情况,作为最佳结果,反馈给用户。比如,用户输入“323”,找不到完全匹配的情况,那么我们就将能和“32”匹配的结果返回给用户。这样,用户还是可以得到输入结果,同时还可以知道输入有问题,提示用户需要检查输入是否正确。
我们归纳一下一个完整的T9拼音输入步骤:
1)输入拼音数字串
我们用到的T9拼音输入法的核心思想就是对比用户输入的拼音数字串,所以必须先由用户输入拼音数字串。
2)在拼音索引表里面查找和输入字符串匹配的项,并记录
在得到用户输入的拼音数字串之后,在拼音索引表里面查找所有匹配的项目,如果有完全匹配的项目,就全部记录下来,如果没有完全匹配的项目,则记录匹配情况最好的一个项目。
3)显示匹配清单里面所有可能的文字,供用户选择
将匹配项目的拼音和对应的汉字显示出来,供用户选择。如果有多个匹配项(一个数字串对应多个拼音的情况),则用户还需要选择拼音。
4)用户选择匹配项,并选择对应的汉字
用户对匹配的拼音和汉字进行选择,选中其真正想输入的拼音和汉字,实现一次拼音输入。
下面介绍一下pyinput.c中比较核心的函数get_matched_pymb,代码如下:

/**
 * @brief       获取匹配的拼音码表
 * @param       strin     : 输入的字符串,形如:"726"
 * @param       matchlist : 输出的匹配表
 * @retval      匹配状态
 *              [7]  , 0,表示完全匹配;1,表示部分匹配(仅在没有完全匹配的时候才会出现)
 *              [6:0], 完全匹配的时候,表示完全匹配的拼音个数
 *                     部分匹配的时候,表示有效匹配的位数
 */
uint8_t get_matched_pymb(uint8_t *strin, py_index **matchlist)
{
    py_index *bestmatch = 0;    								/* 最佳匹配 */
    uint16_t pyindex_len = 0;
    uint16_t i = 0;
    uint8_t temp, mcnt = 0, bmcnt = 0;
    
    bestmatch = (py_index *)&py_index3[0];  				/* 默认为a的匹配 */
    pyindex_len = sizeof(py_index3) / sizeof(py_index3[0]);/*得到py索引表的大小*/

    for (i = 0; i < pyindex_len; i++)
    {
        temp = str_match(strin, (uint8_t *)py_index3[i].py_input);

        if (temp)
        {
            if (temp == 0XFF)
            {
                matchlist[mcnt++] = (py_index *)&py_index3[i];
            }
            else if (temp > bmcnt)  						/* 找最佳匹配 */
            {
                bmcnt = temp;
                bestmatch = (py_index *)&py_index3[i];  	/* 最好的匹配 */
            }
        }
    }

    if (mcnt == 0 && bmcnt)     	/* 没有完全匹配的结果,但是有部分匹配的结果 */
    {
        matchlist[0] = bestmatch;
        mcnt = bmcnt | 0X80;    	/* 返回部分匹配的有效位数 */
    }
    return mcnt;    				/* 返回匹配的个数 */
}

该函数实现的是将用户输入拼音数字串同拼音索引表里面的各个项对比,找出匹配结果,并将完全匹配的项目存放在matchlist里面,同时记录匹配数。对于那些没有完全匹配的输入串,则查找与其最佳匹配的项目,并将匹配的长度返回。
其中该文件还有一个函数test_py,提供给usmart调用,实现串口测试,在串口测试的时候才能用到,如果不使用的话,可以去掉。本实验也是加入usmart控制,大家可以通过该函数实现串口调试拼音输入法。
其他两个函数比较简单,这里就不细说了。
前面提及的matchlist,其定义在pyinput.h中,代码如下:

/* 拼音输入法 */
typedef struct
{
   uint8_t(*getpymb)(uint8_t *instr);	/* 字符串到码表获取函数 */
   py_index *pymb[MAX_MATCH_PYMB];		/* 码表存放位置 */
}pyinput;

该结构体提供了两个成员,一个成员就是字符串到码表获取函数,另外一个成员也就是码表的存放位置。另外一个结构体py_index,已经在前面讲解了,这里就不作展开。
2. main.c代码
在main.c文件下,除了main函数之外,还有py_load_ui、py_key_staset、py_get_keynum和py_show_result函数。其中,py_load_ui函数是用于加载输入键盘,在LCD上显示我们输入拼音数字串的虚拟键盘。py_key_staset函数用于与设置虚拟键盘某个按键的状态(按下/松开)。py_get_keynum函数用于得到触摸屏当前按下的按键键值,通过该函数实现拼音数字串的获取。py_show_result函数用于显示输入串的匹配结果,并将结果打印到串口。这部分代码就不列出来了,大家可以自行理解。
下面看一下main主函数的代码:

int main(void)
{
    uint8_t i = 0;
    uint8_t result_num;
    uint8_t cur_index;
    uint8_t key;
    uint8_t temp;
    uint8_t inputstr[7];					/* 最大输入6个字符+结束符 */
    uint8_t inputlen;                           /* 输入长度 */
    
    HAL_Init();                                 	/* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);		/* 设置时钟, 72Mhz */
    delay_init(72);                        		/* 延时初始化 */
    usart_init(115200);                  		/* 串口初始化为115200 */
    usmart_dev.init(72);                		/* 初始化USMART */
    led_init();                                 	/* 初始化LED */
    lcd_init();                                 	/* 初始化LCD */
    key_init();                                 	/* 初始化按键 */
    tp_dev.init();                              	/* 初始化触摸屏 */
    sram_init();                                	/* SRAM初始化 */
    norflash_init();                            	/* 初始化NORFLASH */
    my_mem_init(SRAMIN);                       /* 初始化内部SRAM内存池 */
    my_mem_init(SRAMEX);                       	/* 初始化外部SRAM内存池 */

    exfuns_init();                             	/* 为fatfs相关变量申请内存 */
    f_mount(fs[0], "0:", 1);                 	/* 挂载SD卡 */
    f_mount(fs[1], "1:", 1);                 	/* 挂载FLASH */
RESTART:
    while (fonts_init())                      	/* 检查字库 */
    {
        lcd_show_string(60, 50, 200, 16, 16, "Font Error!", RED);
        delay_ms(200);
        lcd_fill(60, 50, 240, 66, WHITE);   	/* 清除显示 */
        delay_ms(200);
    }

    text_show_string(30, 5, 200, 16, "正点原子STM32开发板", 16, 0, RED);
    text_show_string(30, 25, 200, 16, "拼音输入法实验", 16, 0, RED);
    text_show_string(30, 45, 200, 16, "正点原子@ALIENTEK", 16, 0, RED);
    text_show_string(30, 65, 200, 16, "KEY_UP:校准", 16, 0, RED);
    text_show_string(30, 85, 200, 16, "KEY0:翻页  KEY1:清除", 16, 0, RED);
    text_show_string(30, 105, 200, 16, "输入:        匹配:  ", 16, 0, RED);
    text_show_string(30, 125, 200, 16, "拼音:        当前:  ", 16, 0, RED);
    text_show_string(30, 145, 210, 32, "结果:", 16, 0, RED);

    /* 根据LCD分辨率设置按键大小 */
    if (lcddev.id == 0X5310)
    {
        kbdxsize = 86;    
        kbdysize = 43;
    }
    else if (lcddev.id == 0X5510)
    {
        kbdxsize = 140;
        kbdysize = 70;
    }
    else
    {
        kbdxsize = 60;
        kbdysize = 40;
    }

    py_load_ui(30, 195);
    my_mem_set(inputstr, 0, 7); /* 全部清零 */
    inputlen = 0;   /* 输入长度为0 */
    result_num = 0; /* 总匹配数清零 */
    cur_index = 0;

    while (1)
    {
        i++;
        delay_ms(10);
        key = py_get_keynum(30, 195);

        if (key)
        {
            if (key == 1)   /* 删除 */
            {
                if (inputlen)inputlen--;
                inputstr[inputlen] = '\0';      /* 添加结束符 */
            }
            else
            {
                inputstr[inputlen] = key + '0'; /* 输入字符 */
                if (inputlen < 7)inputlen++;
            }

            if (inputstr[0] != NULL)
            {
                temp = t9.getpymb(inputstr);     	/* 得到匹配的结果数 */
                if (temp)   						/* 有部分匹配/完全匹配的结果 */
                {
                    result_num = temp & 0X7F;   	/* 总匹配结果 */
                    cur_index = 1;              		/* 当前为第一个索引 */

                    if (temp & 0X80)            		/* 是部分匹配 */
                    {
                        inputlen = temp & 0X7F; 	/* 有效匹配位数 */
                        inputstr[inputlen] = '\0';  /* 不匹配的位数去掉 */
                        if (inputlen > 1)
                        {
                            temp = t9.getpymb(inputstr);    /* 重新获取完全匹配字符数 */
/* 如果还是部分匹配, 直接匹配数为0, 否则表示匹配数量 */
                            result_num = (temp & 0X80)? 0 : (temp & 0X7F); 
                        }
                    }
                }
                else    /* 没有任何匹配 */
                {
                    inputlen--;
                    inputstr[inputlen] = '\0';
                }
            }
            else
            {
                cur_index = 0;
                result_num = 0;
            }
            lcd_fill(30 + 40, 105,30 + 40 + 48,110 + 16, WHITE);/* 清除之前的显示 */
            lcd_show_num(30 + 144, 105, result_num, 1, 16,BLUE);/*显示匹配的结果数*/
/* 显示有效的数字串 */
            text_show_string(30 + 40, 105, 200, 16, (char *)inputstr, 16,0,BLUE);
            py_show_result(cur_index);  /* 显示第cur_index的匹配结果 */
        }

        key = key_scan(0);
        if (key == WKUP_PRES && tp_dev.touchtype == 0)  /* KEYUP按下,且是电阻屏 */
        {
            tp_dev.adjust();
            lcd_clear(WHITE);
            goto RESTART;
        }

        switch (key)
        {
case KEY0_PRES: /* 下翻 */
                  if (result_num) /* 存在匹配的结果 */
                  {
                    if (cur_index < result_num)cur_index++;
                    else cur_index = 1;
/* 显示第cur_index的匹配结果 */                                     
                    py_show_result(cur_index);  
                   }
                  break;
            case KEY1_PRES: /* 清除输入 */
/* 清除之前的显示 */
                  lcd_fill(30 + 40, 145, lcddev.width - 1, 145 + 48, WHITE); 
                  goto RESTART;
        }

        if (i == 30)
        {
            i = 0;
            LED0_TOGGLE();
        }
    }
}

在main函数里,实现了我们在58.2.1小节所说的功能,也是按照它表述的逻辑进行实现。在这里我们并没有实现汉字选择功能,但是由本例程作为基础,再实现汉字选择功能就比较简单了,大家自行实现即可。注意:kbdxsize和kbdysize代表虚拟键盘按键宽度和高度,程序根据LCD分辨率不同而自动设置这两个参数,以达到较好的输入效果。
58.4 下载验证
将程序下载到开发板后,可以看到LED0不停的闪烁,提示程序已经在运行了。LCD显示的内容如图58.4.1所示:
在这里插入图片描述

图58.4.1 汉字输入法界面图
此时,我们在虚拟键盘上输入拼音数字串,即可实现拼音输入,如图58.4.2所示:
在这里插入图片描述

图58.4.2 实现拼音输入
如果发现输入错误了,可以通过屏幕上的DEL按键,来退格。如果有多个匹配的情况(匹配值大于1),则可以通过KEY_UP和KEY1来选择拼音。通过按下KEY0,可以KEY_UP和KEY1来选择拼音。通过按下KEY0,可以清除当前输入,通过按下KEY2,可以实现触摸屏校准(仅限电阻屏,电容屏无需校准)。
触摸输入的匹配项可以通过串口调试助手打印出来:
在这里插入图片描述

图58.4.2 拼音输入有匹配结果时打印
本章,我们还可以借助USMART调用test_py来实现输入法调试,如图58.4.3所示:
在这里插入图片描述

图58.4.2 USMART测试T9拼音输入法图

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

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

相关文章

Kubernetes - HPA-VPA - metrics介绍和安装 - HPA实验

目录 参考文章&#xff1a;(97条消息) Kubernetes-自动扩展器HPA、VPA、CA_hpa vpa_SRE运维充电站的博客-CSDN博客 HPA VPA 官方网址&#xff1a;autoscaler/vertical-pod-autoscaler at master kubernetes/autoscaler GitHub HPA和VPA进行扩缩容的区别&#xff1a; me…

绿水青山,节水护水我先行

为了树立人人珍惜水&#xff0c;人人节约水的良好风尚 绿萝志愿团队在7月16日在常庄刺猬河开展了2023年卫生环保志愿活动主要项目是宣传节水&#xff0c;护水志愿活动。 早上志愿者们早早的来到刺猬河旁&#xff0c;用自己带的工具准备清理河道旁的垃圾。志愿者们顶着炎炎的烈日…

Servlet 开发技术

文章目录 前言创建Servlet项目处理请求并响应处理请求text/plain&#xff0c;纯文本text/html&#xff0c;html代码application/json&#xff0c;JSON格式字符串 Servlet 生命周期Servlet在整个生命周期中被调用的方法Servlet运行原理 CORS跨域设置 前言 提示&#xff1a;这里…

rust的cargo和基本数据类型

一、cargo 1、cargo 比较大的项目就不适合用rustc进行编译了&#xff0c;此时就需要使用cargo 在安装包的时候&#xff0c;会遇到网速慢卡住的问题&#xff0c;这时候就要更换国内源或者设置代理 方法一&#xff1a;设置命令行代理 方法二&#xff1a;换源 进入用户目录下的…

linux 安装redis、配置密码及简单使用

1&#xff1a;官网下载压缩包 这里我下载的是6.2.13版本。 2&#xff1a;上传到linux服务器 a:创建redis文件夹 b:进入当前redis文件夹 c:解压缩文件 d:进入 redis-6.2.713 e:使用make 命令进行编译将.c文件编译成.o文件 编译成功之后会出现“Its a good idea to run make test…

微信原生实现一个简易的图片上传功能

一、实现原理 wx.showActionSheet()&#xff1a;显示操作菜单&#xff0c;选择是从相册选择还是相机拍摄照片wx.chooseImage()&#xff1a;从本地相册选择图片或使用相机拍照。wx.uploadFile()&#xff1a;将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求&#xff0c…

在自定义数据集上微调Alpaca和LLaMA

本文将介绍使用LoRa在本地机器上微调Alpaca和LLaMA&#xff0c;我们将介绍在特定数据集上对Alpaca LoRa进行微调的整个过程&#xff0c;本文将涵盖数据处理、模型训练和使用流行的自然语言处理库(如Transformers和hugs Face)进行评估。此外还将介绍如何使用grado应用程序部署和…

分型(一)

一点想法&#xff1a; 坐标系本来就是人头脑当中的东西&#xff0c;可以根据需要动态调整&#xff0c;图像处理中&#xff0c;用动态的波看静态的图像&#xff0c;进而找出图像的特征&#xff0c;分型是不是把动态的过程呈现出静态的特征呢&#xff1f; 芒德布罗集&#xff1…

Python(十五)数据类型——bool型

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【动手学深度学习】--08.实战:Kaggle房价预测

文章目录 实战&#xff1a;Kaggle房价预测1.访问和读取数据集2.数据预处理2.1标准化数据2.2离散数据处理 3.训练4.K折交叉验证5.模型选择 实战&#xff1a;Kaggle房价预测 1.访问和读取数据集 # 如果没有安装pandas&#xff0c;请取消下一行的注释 # !pip install pandas%matp…

华为云CodeArts产品体验的心得体会及想法

文章目录 前言CodeArts 的产品优势一站式软件开发生产线研发安全Built-In华为多年研发实践能力及规范外溢高质高效敏捷交付 功能特性说明体验感受问题描述完结 前言 华为云作为一家全球领先的云计算服务提供商&#xff0c;致力于为企业和个人用户提供高效、安全、可靠的云服务。…

基于SpringBoot+vue的在线答疑系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

《实战AI低代码》:普元智能化低代码开发平台发布,结合专有模型大幅提升软件生产力

在7月6日举办的“低代码+AI”产品战略发布会上,普元智能化低代码开发平台正式发布。该平台融合了普元自主研发的专有模型,同时也接入了多款AI大模型的功能。它提供了一系列低代码产品,包括中间件、业务分析、应用开发、数据中台和业务流程自动化等,旨在简化企业的复杂软件生…

Linux网络基础 — 传输层

目录 再谈端口号 端口号范围划分 认识知名端口号 netstat pidof UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 几个问题&#xff1a; 确认应答(ACK)机制 6个标记位 超时重传机制 连接…

rust 引用怎么用

本来好好的引用&#xff0c;被 rust 玩坏了&#xff0c;搞得自己都不会使用引用了&#xff0c;我们还是从简单的例子入手&#xff0c;来探索使用引用可能遇到额问题。 下面的示例代码编译不通过&#xff0c;在 s1 赋值给变量 s2 的过程中&#xff0c;字符串 neojos 值的所有权…

webGPT浏览器安装

edge点击“获取” https://microsoftedge.microsoft.com/addons/detail/wetab%E5%85%8D%E8%B4%B9chatgpt%E6%96%B0%E6%A0%87%E7%AD%BE%E9%A1%B5/bpelnogcookhocnaokfpoeinibimbeff?utm_sourceSteamDB # 其他浏览器安装教程如下&#xff1a; https://www.wetab.link/

springcloud gateway 介绍与使用

定义 该项目提供了一个用于在 Spring WebFlux 之上构建 API 网关的库。Spring Cloud Gateway 旨在提供一种简单而有效的方法来路由到 API&#xff0c;并为它们提供横切关注点&#xff0c;例如&#xff1a;安全性、监控/指标和弹性 特征 Spring Cloud Gateway 特性&#xff1a;…

Smartbi 身份认证绕过漏洞

0x00 简介 Smartbi是广州思迈特软件有限公司旗下的商业智能BI和数据分析产品&#xff0c;致力于为企业客户提供一站式商业智能解决方案。 0x01 漏洞概述 Smartbi在安装时会内置三个用户&#xff08;public、service、system&#xff09;&#xff0c;在使用特定接口时&#x…

只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(上)

目录 前言 settimeout/setinterval requestAnimationFrame 基本用法 时间戳参数 帧数与时间戳计算 自动暂停 JS中的贝塞尔曲线 概念 公式 二次贝塞尔 三次贝塞尔 N次贝塞尔 贝塞尔曲线动画 动画类 在动画中使用贝塞尔 总结 相关代码&#xff1a; 贝塞尔曲线相…

【深度学习】:《PyTorch入门到项目实战》(十五):三大经典卷积神经网络架构:LeNet、AlexNet、VGG

【深度学习】&#xff1a;《PyTorch入门到项目实战》(十五)&#xff1a;三大经典卷积神经网络架构&#xff1a;LeNet、AlexNet、VGG&#xff08;代码实现及实际案例比较&#xff09; ✨本文收录于【深度学习】&#xff1a;《PyTorch入门到项目实战》专栏&#xff0c;此专栏主要…