Linux C语言基础 day7

news2025/2/25 18:06:09

目录

思维导图:

学习目标:

学习内容:

1. 数组

1.1 对数组元素的常规操作

1.1.1 逆序

1.1.2 挑选数据

1.1.3 排序

1. 冒泡排序

2. 选择排序

2. 二维数组

2.1 二维数组的概念

2.1.1. 定义格式

2.2.2.初始化

2.2 二维数组的相关操作

2.2.1.  输入输出

2.2.2 求和、均值、最值

2.2.3 转置

3. 字符数组

3.1 一维字符数组

3.1.1. 定义格式

3.1.2. 字符数组初始化

1.单字符处理字符数组

2. 字符串的形式初始化

3.2 strlen

3.3 strcpy

3.4 strcat

3.5 stcmp

例如:

课内练习:

课外作业:


思维导图:

学习目标:

  • 一周掌握C基础知识

学习内容:

1. 数组

1.1 对数组元素的常规操作

1.1.1 逆序

        所谓逆序,就是将数据进行首尾交换,例如,数组原型:1,2,3,4,5。逆序后的数组为:5,4,3,2,1。

总结套路:

        1、需要进行首尾交换的次数是 MAX/2 (MAX表示数组的长度)

        2、交换双方:arr[i] arr[MAX-1-i]

        3、交换三部曲

例如:

//将数组进行逆序

for(int i=0; i<MAX/2; i++) //只需遍历前一半数组

{ //交换三部曲

        int temp = score[i];

        score[i] = score[MAX-1-i];

        score[MAX-1-i] = temp;

} //输出逆序后的数组

printf("逆序后的结果为:");

for(int i=0; i<MAX; i++) {

        printf("%d\t", score[i]);

}

putchar(10);

1.1.2 挑选数据

 int k=0;
    for(i=0;i<MAX;i++)
    {
        if(score[i]>=90){
                arr[k]=score[i];
                k++;
        }
    }
    for(i=0;i<MAX;i++)
{
    printf("%d\t",arr[i]);
}

1.1.3 排序

1. 冒泡排序

        将较大或者较小的数据,经由交换后,慢慢“浮到”数组顶端,如同水中的气泡一样,故名冒泡排序 原理:不断进行相邻的两个数据进行比较,如果满足条件,则进行交换,每一轮都会将一个最值数据"浮到"对应位置 对于每一轮重复上述操作,直到所有数据排序结束

 例如:

for(i=0;i< MAX-1;i++){
        for(int j=0;j<MAX-i-1;j++){
            if(score[j]>score[j+1]){
                int temp=score[j];
                score[j]=score[j+1];
                score[j+1]=temp;
            }
        }
    }printf("排序后的结果为:");
    for(i=0;i<MAX;i++)
{
    printf("%d\t",score[i]);
}
 

2. 选择排序

        将要排序的序列分为已排序序列和待排序序列 不断从待排序序列中找到最值,放入已排序序列的最后位置,随着待排序序列不断减少,已排序序列不断增长 直到待排序序列没有元素,排序结束。

例如:

int maxj=0;
for(i=0;i<MAX;i++)
{   
    maxj=i;
    for(int j=i+1;j<MAX;j++){
        if(score[maxj] < score[j]){
            maxj=j;
        }
    }
    if(maxj != i){
        int temp=score[i];
                score[i]=score[maxj];
                score[maxj]=temp;
    }
}
printf("排序后的结果为:");
    for(i=0;i<MAX;i++)
{
    printf("%d\t",score[i]);
}

2. 二维数组

2.1 二维数组的概念

2.1.1. 定义格式

数据类型 数组名[常量1][常量2];

2.2.2.初始化

1、按行初始化:定义数组时,每一个一维数组的值使用一个花括号括起来 int arr[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,9,9,9} };

2、按行部分初始化:每个一维数组中,可以不填满,没有初始化的部分用0补齐 int arr[3][4] = { {1,2}, {8}}; //1,2,0,0 8,0,0,0 0 ,0, 0, 0

3、按数组排列初始化:数组存储数据时,默认是按顺序存储,第一行存储满了,存第二行 int arr[3][4] = { 1,2,3,4,5,6,7,8, 9}; //1,2,3,4 5,6,7,8, 9,0,0,0

4、特殊初始化:定义二维数组并初始化时,可以不指定第一维的大小,由初始化总个数除以列数向上取整,得到行数 int arr[][4] = { 1,2,3,4,5,6}; // 1,2,3,4 5,6,0,0

5、注意:定义二维数组时,无论任何时候,第二维都不能省略

2.2 二维数组的相关操作

2.2.1.  输入输出

        对于二维数组而言,是有行有列的元素集合,需要使用双重循环来进行定位横标和纵标

        在双重循环中,找到任意一个元素 arr[i][j] 来对其进行输入输出

例如:

#include <stdio.h>
#define M 3
#define N 4
int main(int argc, char const *argv[])
{
    int i=0,j=0;
    int s[M][N];
    for(int i=0;i<M;i++){
        for(int j=0;j<N;j++){
            printf("请输入第%d行第%d列的元素:",i+1,j+1);
            scanf("%d",&s[i][j]);
        }
        printf("\n");
    }
    printf("数组分别是:\n");
    for(int i=0;i<M;i++){
        for(int j=0;j<N;j++){
            printf("%d\t",s[i][j]);
        }
        printf("\n");
    }

2.2.2 求和、均值、最值

        1、整体求和就是将任意一个元素进行累加

        2、求每一行的和:将每一行的数据进行累加,求出结果后,可以放入一个新数组

        3、求整体最值:先将第一个当做最值,然后遍历所有的元素,进行比较,给定比较条件后,适当更新最值

        4、求每一行的最值:在外层循环内,先将当前行的第一个当做最值,然后遍历当前行的所有数据,进行比较和更新

例如:

int a[3]={0};
    for(i=0;i<M;i++){
        for(j=0;j<N;j++){
            a[i]+=s[i][j];
        }
    }
    printf("每一行的和分别是:\n");
    for(i=0;i<M;i++){
        printf("%d\t",a[i]);
    }
    printf("\n");
    int max=s[0][0];
    int maxi=0;
    int maxj=0;
    for ( i = 0; i < M; i++)
    {
        for (j = 0;j < N; j++)
        {
           if(max<s[i][j]){
               max = s[i][j];
               maxi = i+1;
               maxj = j+1;
           }
        }
    }
    printf("最大值为第%d行,第%d列,值为%d",maxi,maxj,max);
    printf("\n");
    int max1={0};
    for(i=0;i<M;i++){
        max1=s[i][0];
        for ( j = 0; j < N; j++)
        {
           if (max1 < s[i][j])
           {
               max1 = s[i][j];
           }
        }
        printf("第%d行的最大值为:%d\n", i+1,max1);
    }
    printf("\n");

2.2.3 转置

        1、所谓转置,就是将二维数组行列互换

        2、完成转置,需要使用一个新数组

        3、转置核心代码:brr[j][i] = arr[i][j]

例如:
    int brr[N][M] = {0};
    for(int i=0; i<M; i++)         //外行
    {
        //找到当前行的任意一个元素
        for(int j=0; j<N; j++)
        {
            //在此处找到了任意一个元素 arr[i][j]
            brr[j][i] = s[i][j];
        }
    }

    //输出转置后的结果
    printf("上述二维数组转置后的结果如下:\n");
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<M; j++)
        {
            printf("%d\t", brr[i][j]);
        }
        printf("\n");
    }

3. 字符数组

3.1 一维字符数组

3.1.1. 定义格式

char 数组名[常量];

3.1.2. 字符数组初始化

1.单字符处理字符数组

        全部初始化:char arr[5] = {'h', 'e', 'l', 'l', 'o'};

        部分初始化:char arr[5] = {'h', 'e', 'l'}; //没有初始化的部分用 0('\0') 补齐

        特殊初始化:char arr[] = {'h', 'e', 'l', 'l', 'o'}; //此时字符数组的长度为 5

2. 字符串的形式初始化

        整体初始化:char arr[10] = {"hello"}; //或者 char arr[6] = "hello";

        特殊字符串初始化: char arr[] = "ni hao"; //此时,数组的实际长度7 但是,字符串实际长度为6

3.2 strlen

        格式:#include <string.h> size_t strlen(const char *s);

        功能:计算字符串的长度,不包括结尾的'\0'

        参数:要计算长度的字符串的首地址

        返回值:计算的结果

3.3 strcpy

        格式:#include <string.h> char *strcpy(char *dest, const char *src);

        功能:将src指向的字符串复制到dest指向的缓冲区里

        参数: dest:目标字符串 src :源字符串         

        返回值: 同dest

        注意: 要保证dest足够大,否则会出现越界访问的问题!!!

3.4 strcat

        格式:#include <string.h> char *strcat(char *dest, const char *src);

        功能:将src指向的字符串追加到dest指向的字符串后面 回复覆盖 dest 结尾的 '\0'

        参数:

                dest:目标字符串

                src :源字符串

        返回值: 同dest

        注意:要保证 dest 足够大

3.5 stcmp

        格式:#include <string.h> int strcmp(const char *s1, const char *s2);

        功能:比较两个字符串

        参数: s1 和 s2 就是要参与比较的两个字符串 //是逐个比较两个字符串中字符的ascii码

        返回值:

                >0 s1>s2

                ==0 s1==s2

                <0 s1<s2

例如:

#include<stdio.h>
#include<string.h>
int main(int argc, const char *argv[])
{
    //定义两个字符数组初始化字符串
    char str1[20] = "hello world";
    char str2[] = "I Love China";

    //测试strlen
    int len = strlen(str2);           //求字符串2的实际长度
    printf("len = %d\n", len);           //12
    int size = sizeof(str2);          //求字符串所占字符数组的长度
    printf("size = %d\n", size);         //13
    size = sizeof(str1);             //求字符数组1的大小
    printf("size = %d\n", size);         //20

    //比较两个字符串的大小
    if(strcmp(str1, str2) >0)
    {
        printf("%s大\n", str1);
    }else if(strcmp(str1, str2) < 0)
    {
        printf("%s小\n", str1);
    }else
    {
        printf("一样大\n");
    }

    //完成两个字符串的赋值,将str2赋值给str1
    strcpy(str1, str2);             // str1 = str2
    printf("拷贝后:str1 = %s, str2 = %s\n", str1, str2);

    //完成两个字符串的连接, 将str2连接到str1后面
    strcat(str1, str2);
    printf("连接后:str1 = %s, str2 = %s\n", str1, str2);
    
    


    return 0;
}


课内练习:

杨辉三角

解析:


课外作业:

1.提示并输入一个字符串,统计该字符串中字母、数字、空格以及其他字符的个数

解析:

#include<stdio.h>>

#include<string.h>

int main(int argc, char const *argv[])

{

        char s[1001]={0};

        int i=0;

        int zimu=0;

        int kg=0;

        int dight=0;

        int other=0;

        printf("请输入字符串:");

        gets(s);

        while (s[i] != '\n' && s[i] != '\0') {

            if((s[i]>='A' && s[i]<='Z') || (s[i]>='a' && s[i]<='z')){

                zimu++;

            }else if (s[i]>='0' && s[i]<='9')

            {

                dight++;

            }else if (s[i] == ' ')

            {

                kg++;

            }else

            {other++;}

            i++;

        }

        printf("该字符串中字母有%d个、数字有%d个、空格有%d个,其他字符有%d个",zimu,dight,kg,other);

    return 0;

}

2.提示并输入一个字符串,求出该字符串中所有数字的总和

解析:

#include<stdio.h>>

#include<string.h>

int main(int argc, char const *argv[])

{

        char s[1001]={0};

        int i=0;

        int sum=0;

        printf("请输入字符串:");

        gets(s);

        while (s[i] != '\n' && s[i] != '\0') {

        if (s[i]>='0' && s[i]<='9')

        {

            sum=sum+(s[i]- '0');

        }

        i++;

        }

        printf("%d",sum);

    return 0;

}

3.定义一个4*3的二维整形数组,完成对二维数组的输入、输出。并将该二维数组中每一行的最值放入到一个一维数组中,并对该一维数组进行升序排序后输出。

解析:

#include <stdio.h>
int main(int argc, char const *argv[])
{
      int s[4][3]={0};
        int a[4]={0};
        int i=0,j=0;
        int temp=0; 
        for(i=0;i<4;i++){
            for ( j = 0; j < 3; j++)
            {
                printf("请输入第%d行第%d列的元素:",i+1,j+1);
                scanf("%d",&s[i][j]);
            }
            printf("\n");
        }
        printf("数组分别是:\n");
        for(i=0;i<4;i++){   
            for ( j = 0; j < 3; j++)
            {
                printf("%d\t",s[i][j]);
            }
            printf("\n");
        }
        for(i=0;i<4;i++){
            a[i]=s[i][0];
            for(j=0;j<3;j++){
                if(a[i] < s[i][j]){
                    a[i]=s[i][j];
                }
            }
        }
        printf("该一维数组进行升序排序后输出为:");
        for(i=1;i<4;i++){
            for(j=0;j<4-i;j++){
            if(a[j] > a[j+1]){
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
                 }
            }
        }
        for(i=0;i<4;i++)
            {
                printf("%d\t",a[i]);
            }
            printf("\n");
    return 0;
}

4.提示并输入两个一维整形数组,求这两个数组的交集。

解析:

    #include <stdio.h>

    #include <string.h>

    #define M 30

    int main(int argc, const char *argv[])

    {

    int arr[M]={0};

    int brr[M]={0};

    int crr[M]={0};

    int N=0;

    int count=0;

    printf("请输入两个一维数组的长度:\n");

    scanf("%d",&N);

    printf("请输入第一个数组的数字:\n");

    for(int i=0;i<N;i++){

        printf("第%d个:",i+1);

        scanf("%d",&arr[i]);

        putchar(10);

    }

    printf("请输入第二个数组的数字:\n");

    for(int i=0;i<N;i++){

        printf("第%d个:",i+1);

        scanf("%d",&brr[i]);

        putchar(10);

    }

    int k=0;

    for(int i=0;i<N;i++){

        for(int j=0;j<N;j++){

            if(arr[i]==brr[j]){

                crr[k]=arr[i];

                k++;

                count++;

                break;

            }

        }

    }

    int temp=0;

    for(int i=0;i<N;i++){

        for(int j=i+1;j<N;j++){

            if(crr[i]==crr[j]){

                for(temp = j;temp<N-1;temp++)

                    crr[temp]=crr[temp+1];  

                j--;    

                N--;    

            }

        }

    }

    printf("两个数组的交集为:\n");

    for(int i=0;i<N;i++){

        if (count == 0) {

        printf("没有交集。\n");

    }else

        printf("%d\t",crr[i]);

    }

    putchar(10);

    // 如果交集中没有元素,输出相应的信息

   

    return 0;

}

5.完成注册和登录功能:使用两个一维字符数组存储账户和密码

注册:完成对账号和密码的输入

登录:将登录账号和密码跟注册的账号和密码进行匹配,如果相等,则登录成功,否则,登录失败

解析:

#include<stdio.h>

int main(int argc, const char *argv[])
{
    //定义变量存储菜单选项
    int menu = 0;

    //定义变成存储注册账号和密码,以及登录账号和密码
    char sign_usrName[20] = "";       //注册账号
    char sign_pwd[20] = "";           //注册密码
    char login_usrName[20] = "";      //登录账号
    char login_pwd[20] = "";          //登录密码

    while(1)
    {
        printf("\t\t======XXX管理系统========\n");
        printf("\t\t1、注册\n");
        printf("\t\t2、登录\n");
        printf("\t\t0、退出\n");

        printf("请输入操作码:");
        scanf("%d", &menu);
        getchar();                //吸收回车

        //对操作码多分支选择
        switch(menu)
        {
        case 1:
            {
                //提示用户输入账号和密码
                while(1)
                {
                    printf("请输入注册账号:");
                    gets(sign_usrName);
                    printf("请输入注册密码:");
                    gets(sign_pwd);

                    //判断账号和密码是否合格
                    if( !(strlen(sign_usrName)>=6 && strlen(sign_pwd)>=6) )
                    {
                        printf("注册失败,请重新注册\n");
                        continue;
                    }
                    break;           //表示注册成功
                }

            }
            break;
        case 2:
            {
                //提示并输入登录账号和密码
                printf("请输入登录账号:");
                gets(login_usrName);
                printf("请输入登录密码:");
                gets(login_pwd);

                //判断是否登录成功
                if(strcmp(sign_usrName,login_usrName)==0 && strcmp(sign_pwd,login_pwd)==0)
                {
                    printf("登录成功\n");
                    exit(0);           //退出程序
                }else
                {
                    printf("账号或密码错误\n");
                }

            }
            break;
        case 0:goto END;
        default:printf("您输入的功能有误,请重新输入\n");
        }

    }

END:

    return 0;
}

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

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

相关文章

深度学习pytorch多机多卡网络配置桥接方法

1 安装pdsh&#xff08;Parallel Distributed Shell&#xff09; sudo apt install pdsh sudo -s # 切换超级用户身份 …

Vscode ssh远程连接Linux服务器登录时密码password无法输入

问题 最近在用Vscode远程连接Linux服务器时&#xff0c;在终端提示输入密码password的时候用键盘输入没有反应。 以为是键盘坏了&#xff0c;然后尝试复制粘贴没有用。 后来找到了原因以及解决方法&#xff0c;感谢原帖作者&#xff08;原贴链接粘在下面&#xff09; 原因 …

Java 多继承与接口

Java 多继承与接口 1、为什么Java不支持多继承&#xff1f;2、使用接口实现多继承2.1 接口的定义与实现 3、接口的优点4、结论 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 多继承是指一个类可以继承多个父类&#xff0c;从而获得多个父类…

RHCE-autofs自动挂载

要求 一、在主机上提供web&#xff0c;dns服务 服务端 IP&#xff1a;172.25.250.131/24 dns&#xff1a;172.25.250.131 [rootlocalhost ~]# cd /etc/httpd/conf.d[rootlocalhost conf.d]# vim vhost.conf [rootlocalhost conf.d]# mkdir /nfs/rhce -p[rootlocalhost conf…

基于企业微信第三方接口开发,移除群成员通知

移除群成员通知 返回示例 {"flag": 0, "receiver": 0, "sender_name": "", "is_room": 1, "server_id": 15318083, "send_time": 1687688952, "sender": 1688855749266556, "referid&…

根据视图矩阵, 恢复相机的世界空间的位置

根据视图矩阵, 恢复相机的世界空间的位置 一、方法1 glsl 实现: // 从本地局部坐标系(相机空间) 到 世界空间的旋转变换 mat3 getLocal2WorldRotation() {mat3 world2localRotation mat3(viewMatrix[0].xyz,viewMatrix[1].xyz,viewMatrix[2].xyz);return inverse(world2loca…

推出新的LMK6x 低抖动高性能 BAW 振荡器(器件编号包括LMK6DA、LMK6HA)标准时钟振荡器

前言 体声波 (BAW) 是一种微谐振器技术&#xff0c;能够将高精度 BAW 谐振器直接集成到具有超低抖动时钟电路的封装中。 相关型号&#xff1a;LMK6DA05184ADLER LMK6DA10000ADLFR LMK6DA12288ADLER LMK6HA10000ADLER LMK6HA10000ADLFR LMK6HA10000BDLFR 概述 LMK6x 器件是一…

nsightcompute进阶

一、定义 1 python 代码测试 2 roofline analysis 屋檐模型分析 3 summary 分析 4 Speed of light throughput 分析 5 带宽分析 6 内存分析 二、实现 python 代码测试 2. >>ncu --version 3. >>ncu --list-sets #查看set 类型 4. >>ncu --set full -…

IP 地址:优化网络游戏

IP地址和网络游戏 在现代网络游戏中&#xff0c;IP地址不仅用于服务器分配&#xff0c;还能针对性进行玩家匹配与优化网络延迟。本文将探讨IP地址在网络游戏中的具体应用。 *服务器分配* 全球服务器分布&#xff1a; 网络游戏需要在全球范围内提供快速、稳定的连接&#xff…

3D工艺大师快速生成装配动画,驱动汽车工业装配流程革新

在现代制造业的一般生产流程中&#xff0c;车间装配环节是产品由蓝图迈向市场前至关重要的一道工序。随着产品结构的日益复杂化和个性化需求的不断增长&#xff0c;车间装配工作面临着前所未有的挑战。高精密度的装配要求、错综复杂的组件关系以及频繁变更的生产计划&#xff0…

flutter 列表下拉框加搜索

1.使用控件搜索加下拉框dropdown_search: ^0.4.9和获取中文拼音lpinyin: ^1.1.1 2.加入中文查询和首字查询 在当中找到相应的packages&#xff0c;再在SelectDialog.dart当中加入引入拼音搜索 import package:lpinyin/lpinyin.dart; 更改匹配方法manageItemsByFilter使其可…

一文读懂DNS和CDN

一.什么是DNS DNS&#xff08;Domain Name System&#xff09;全称为域名系统&#xff0c;是一个将域名和IP地址相互映射的分布式服务&#xff0c;他的作用就是把一个域名解析成为IP地址。我们平时输入的网址&#xff08;或者域名&#xff09;不能被计算机直接识别&#xff0c;…

oracle控制文件详解以及新增控制文件

文章目录 oracle控制文件1、 控制文件包含的主要信息如下&#xff1a;2、查看目前系统的控制文件信息&#xff0c;主要是查看相关的字典视图 oracle新增控制文件 oracle控制文件 控制文件是一个很小的二进制文件(10MB左右)&#xff0c;含有数据库结构信息&#xff0c;包括数据…

数据结构(Java):单链表面试OJ题

1、题一&#xff1a;获取链表倒数第k个节点 . - 力扣&#xff08;LeetCode&#xff09; 1.1 思路解析 此题我们使用双指针法求解。 首先&#xff0c;我们要知道&#xff0c;倒数的第k个节点&#xff0c;距离倒数第一个节点还需要移动k-1次。 1.那么我们可以定义出两个指针&a…

设计模式-工厂模式的完整代码示例及测试验证

工厂模式 工厂模式 什么是工厂模式&#xff1f; 工厂模式是一种创建对象的设计模式&#xff0c;用来替代传统的 如 A anew A() 创建对象的方式&#xff0c;提供了一种 统一的接口来创建对象&#xff0c; 封装创建的过程&#xff0c;达到解耦的目的。 优缺点 优点 封装对象的创…

pytorch官网examples 实现

Getting started with transforms v2 — Torchvision 0.18 documentation (pytorch.org) 官网我导入包都报错官网代码如下&#xff1a; 不太理解所以我自己写了一段修改之后的代码&#xff0c;效果是一样的 import torch from torchvision.io import read_image import mat…

X用户最多的国家排名统计报告

数据为DataReportal发布的Twitter在各个国家的用户数统计。 2022年&#xff0c;Twitter用户最多的国家是美国&#xff0c;有7690万用户。 数据统计单位为&#xff1a;万人 数据说明&#xff1a; 数据截止时间为2022年1月 Twitter在各个国家的用户情况 2022年&#xff0c;Twit…

【TES807】 基于XCKU115 FPGA的双FMC接口万兆光纤传输信号处理平台

板卡概述 TES807是一款基于千兆或者万兆以太网传输的双FMC接口信号处理平台。该平台采用XILINX的Kintex UltraSacle系列FPGA&#xff1a;XCKU115-2FLVF1924I作为主处理器&#xff0c;FPGA外挂两组72位DDR4 SDRAM&#xff0c;用来实现超大容量数据缓存&#xff0c;DDR4的最高数据…

RIP路由协议概述

RIP【Routing Information Protocol】 RIP是为TCP/IP 环境中开发的第一个路由选择协议标准 RIP是一个【距离——矢量】路由选择协议 当路由器的更新周期为30s到来时&#xff0c;向邻居发送路由表 RIP以跳数作为唯一度量值 RIP工作原理 RIP路由协议向邻居发送整个路由表信息RI…

《昇思25天学习打卡营第1天|QuickStart》

说在前面 曾经接触过华为的910B服务级显卡&#xff0c;当时基于910B做了一些开发的工作&#xff0c;但是总感觉做的事情太低层&#xff0c;想要能自顶向下的了解下&#xff0c;因此开始了MindSpore的学习。另外也想给予提供的显卡&#xff0c;简单尝试下llm模型的训练&#xf…