C++青少年简明教程:字符类型、字符数组和字符串

C++青少年简明教程:字符类型、字符数组和字符串

在 C++ 语言中,处理文本数据的基础是字符类型 char,字符数组,以及标凌库中的字符串类 std::string。

C++中的char类型占用 1 字节的内存空间,用于存储单个ASCII字符。例如,字符'A'在ASCII编码中对应的值是65。

字符数组是一个可以存储多个字符的连续内存空间。你可以使用字符数组来存储一个字符串(即一系列字符,以空字符'\0'结尾)。如:

char str[10] = "Hello"; // 注意,这里实际上存储了"Hello\0",即字符串后有一个空字符作为结束符

字符数组可以通过循环逐个访问其元素,但在处理时必须小心维护 '\0' 结束符,以防止出现越界错误。字符数组通常被称为 C-风格字符串(C-style strings)。这种字符串表示方式来源于 C 语言,在 C++ 中仍然被广泛支持,主要因为历史兼容性和操作系统接口的要求。

字符串类,在C++中,std::string是一个类,用于处理字符串。它是C++标准库中的一部分,提供了许多方便的方法来操作字符串,如连接、比较、查找等。使用 std::string 类可以大大简化字符串的操作,并提高代码的安全性和可读性。

字符类型

在C++中,字符类型使用关键字char来定义。字符类型表示单个字符,包括数字、字母、符号等。字符类型的大小是一个字节(8位)。

字符类型变量只能存储一个字符,例如:

char c = 'A'; // 定义字符类型变量c,存储值为'A'

注意使用字符类型数据确实使用单引号(' ')。

空字符的 ASCII 码值为 0,因此,可以使用以下语句来表示空字符:

char c = '\0';

字符数组

字符数组是由字符组成的一维数组,包含多个字符元素。字符数组也有一维、二维、三维之分。

一维字符数组

c++中,可以使用字符类型数组来存储多个字符。字符类型数组是由多个字符类型变量组成的有序集合,即一串字符。可以使用花括号和逗号分隔符来初始化字符类型数组,也可以使用双引号来初始化字符类型数组,这样可以更容易地输入一串字符,而无需逐个输入每个字符。例如:

char str1[] = {'H', 'e', 'l', 'l', 'o'}; // 定义字符类型数组str1,但不是一个字符串

char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'}; // 定义字符类型数组str2,并且是一个字符串

char str3[] = "Hello"; // 定义并双引号进行初始化字符类型数组str3,并且是一个字符串

str2和str3是等价的。

字符类型数组可以用来存储字符串,字符数组以空字符('\0')作为结尾标识,表示字符串的结束。在使用双引号进行初始化时,编译器会自动在字符数组末尾添加一个空字符'\0',也就是说使用字符串字面值来初始化字符类型数组时,不需要明确地添加空字符。

一维字符数组和字符串的不同点:

1.字符串以空字符('\0')作为字符串的结束符,而字符数组没有特定的结束符。

2.字符串可以使用双引号("")来初始化,例如char str[] = "hello",而字符数组则需依次赋值,例如char arr[] = {'h', 'e', 'l', 'l', 'o'}或者char arr[] = "hello";(这种方式会在数组的末尾自动添加一个空字符)。

3.字符串可以使用一些针对字符串类型的函数,例如strlen()、strcpy()、strcmp()等等。字符数组也可以使用这些函数,但是需要对其具体的长度、空字符进行处理。

尽管字符数组可以用来处理字符串,但在C++中,通常推荐使用string类。

一维字符数组初始化

1.使用字符串字面值进行初始化:

char str[] = "Hello";

这会创建一个字符数组str,并将字符串字面值"Hello"复制到该数组中。注意,字符数组的大小会根据字符串的长度自动确定。

2.使用花括号初始化列表进行初始化:

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};

这里使用花括号{}来指定字符数组的初始元素,包括最后一个null字符('\0')。

3.逐个赋值:

char str[6];
str[0] = 'H';
str[1] = 'e';
str[2] = 'l';
str[3] = 'l';
str[4] = 'o';
str[5] = '\0';

这种方式需要逐个给字符数组的元素赋值,并确保最后一个元素是null字符('\0')。

4.使用strcpy函数进行赋值(需要包含头文件<cstring>):

char str[6];
strcpy(str, "Hello");

注意,无论使用哪种方式,都需要保证字符数组的容量足够大,能够容纳赋值的字符串。另外,字符串赋值时要确保最后一个字符是字符串的结尾符 '\0'即null字符。

一维字符数组和字符串(string)的关系

在C/C++中,字符串实际上是以字符数组的形式存储的,以null字符('\0')作为字符串的结束标志。因此,可以说字符串是字符数组的一种特殊情况。一维字符数组可以用于存储任意的字符序列,而字符串则是一个以null字符结尾的字符数组。

字符数组可以通过初始化或赋值来定义,而字符串只能通过初始化来定义。字符数组是定长的,而字符串长度可变。

注意,下面两句是有区别的:

char str[6] = {'H', 'e', 'l', 'l', 'o'};

char str[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

都是合法的。

第一种写法定义了一个包含5个字符的字符数组,初始化为指定的字符序列,但没有明确指定空字符('\0')。如果将其作为字符串使用,可能会导致访问越界或其他错误。

第二种写法定义了一个包含5个字符和一个空字符的字符数组,并且明确地将最后一个元素设置为空字符('\0')。这样就确保了数组以空字符结尾,可以被正确地当作字符串来处理。

【顺便提示:C语言中只有一种方式来表示字符串,那就是使用C-style string的字符数组(char array)。

C++中处理字符串的两种都可以:

1.C-style string的字符数组(char array):使用字符数组来表示和处理字符串。字符数组以null字符 '\0' 结尾,可以使用C风格的字符串函数来进行操作。这种方式需要手动管理内存,并且对于较长的字符串长度可能会有限制。

2.使用 string 类型:C++标准库提供了 string 类型(std::string),它是一个类模板。可以通过包含 <string> 头文件来使用 string 类型。string 类型提供了许多方便的字符串操作方法,它为字符串的处理提供了更高级的抽象和功能。】

一维字符数组简单示例:

#include <iostream>
using namespace std;

int main() {
    char str[] = "Hello, World!"; //长度自动确定
    cout << str << endl;  // 输出:Hello, World!

    return 0;
}

使用标准库函数printf、scanf、puts、gets等完成字符数组的输入输出需要引入<cstdio>头文件。该头文件是对<stdio.h>头文件的C++版本支持,其中包含了许多对输入输出操作有用的函数及变量。详情可参考 “C++的输入输出”一节。

★使用printf和scanf完成字符数组的输入输出:

#include <cstdio>

int main() {
    char str[50];

    // 从标准输入读取一个字符串到字符数组中
    printf("请输入字符串:");
    scanf("%s", str);

    // 将字符数组的内容打印到标准输出中
    printf("您输入的字符串是:%s\n", str);

    return 0;
}

★使用puts和gets完成字符数组的输入输出

#include <cstdio>

int main() {
    char str[50];

    // 从标准输入读取一个字符串到字符数组中
    printf("请输入字符串:");
    gets(str);

    // 将字符数组的内容打印到标准输出中
    puts("您输入的字符串是:");
    puts(str);

    return 0;
}

C++ 标准库提供了一些函数用来处理以 null 结尾的字符数组(C 风格字符串)。这些函数包括在 <cstring>(或 <string.h>)头文件中。常用的如:

strlen :用于返回指定字符串的长度(不包括空字符)。

strcpy :用于将一个字符串复制到另一个字符数组中。

strcat :用于将两个字符串进行拼接。

strcmp :用于比较两个字符串,并返回它们之间的区别。

strchr :用于在字符串中查找给定字符的第一个出现位置。

strstr :用于在字符串中查找给定字符串的第一个出现位置。

提示:这些函数需要引入 <cstring> (或 <string.h>)头文件。该头文件包含了 C++标准库中与C语言字符串操作相关的函数的声明。

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    // 定义两个C风格字符串
    char str1[] = "Hello, World!";
    char str2[] = "C++";

    // 使用strlen计算字符串长度
    int length1 = strlen(str1);
    int length2 = strlen(str2);
    cout << "字符串1长度: " << length1 << endl;
    cout << "字符串2长度: " << length2 << endl;

    // 使用strcpy复制字符串
    char str3[100];
    strcpy(str3, str1);
    cout << "复制后的字符串: " << str3 << endl;

    // 使用strcat拼接字符串
    char str4[100];
    strcpy(str4, str1);
    strcat(str4, ", ");
    strcat(str4, str2);
    cout << "拼接后的字符串: " << str4 << endl;

    // 使用strcmp比较字符串
    if (strcmp(str1, str2) == 0) {
        cout << "两个字符串相等" << endl;
    } else {
        cout << "两个字符串不相等" << endl;
    }

    // 使用strchr查找字符
    char* found = strchr(str1, 'W');
    if (found != nullptr) {
        cout << "找到字符: " << *found << endl;
    } else {
        cout << "未找到字符" << endl;
    }

    // 使用strstr查找字符串
    char* found2 = strstr(str1, str2);
    if (found2 != nullptr) {
        cout << "找到字符串: " << found2 << endl;
    } else {
        cout << "未找到字符串" << endl;
    }

    return 0;
}

运行输出:

字符串1长度: 13
字符串2长度: 3
复制后的字符串: Hello, World!
拼接后的字符串: Hello, World!, C++
两个字符串不相等
找到字符: W
未找到字符串

对于字符数组重点掌握一维字符数组,下面简要介绍二维字符数组。

二维字符数组最常见的初始化方式

1:逐个初始化

    char charArray1[2][3] = {{'a', 'b', 'c'}, {'d', 'e', 'f'}};

2:使用字符串字面值初始化

    char charArray2[2][3] = {"ab", "cd"};

二维字符数组简单示例

#include <iostream>
using namespace std;

int main() {
     // 二维字符数组
    char str[][10] = {"Hello", "World"}; // 大小为2x10
    cout << "str[0]: " << str[0] << endl;
    cout << "str[1]: " << str[1] << endl;

    return 0;
}

输出:

str[0]: Hello
str[1]: World

字符串类(std::string

一般推荐在 C++ 程序中使用 std::string 类来处理字符串,除非有特定的性能要求或者需要与旧的 C 代码库互操作。利用 std::string 提高开发效率和程序的安全性。

要使用 std::string 类,你需要引入的是 <string> 头文件。

在C++中,string类是标准库提供的字符串类,它在<string>头文件中定义。string类提供了一系列成员函数和操作符,用于处理和操作字符串。string不属于STL(Standard Template Library)中的容器类,而是C++标准库(Standard Library)中的一个类,用于表示和操作字符串。

你可以很方便地使用string类进行字符串的赋值、拼接、查找、替换等操作,而不需要手动管理内存或考虑字符串长度的限制。

赋值和拼接:可以使用=操作符进行字符串的赋值,也可以使用+操作符进行字符串的拼接。

访问字符:可以使用下标操作符[]来访问字符串中的单个字符,并可以修改它们。

字符串长度:使用length()或size()成员函数可以获取字符串的长度。

比较字符串:可以使用==、!=、<、>、<=、>=等操作符进行字符串的比较。

查找和替换:string类提供了find()、rfind()、replace()等成员函数,用于在字符串中查找指定的子串并进行替换。

【https://cplusplus.com/reference/string/string/ 】

可以使用不同的构造函数(constructor)【注:C++中,构造函数是一种特殊的成员函数,它在创建类的对象时被自动调用。构造函数的主要目的是初始化对象的数据成员】来创建不同的字符串。这些是一些常见的方法示例:

☆默认构造函数(无参构造函数):例如:

string str; //创建一个空的string对象。

string str = "Hello World!"; //创建一个的string对象并赋值初始化

☆带字符串参数的构造函数:创建一个string对象,并将其初始化为一个给定的字符串。例如:

string str("Hello");

☆带字符参数和个数的构造函数:创建一个string对象,并将其初始化为指定个数的相同字符。例如:

string str(5, 'a');  // str = "aaaaa"

☆拷贝构造函数:使用一个已有的string对象创建一个新的string对象。例如:

string str1("Hello");

string str2(str1);  // str2 = "Hello"

下面介绍string 类中提供的 getline 函数。

getline()函数语法如下:

istream& getline (istream& is, string& str, char delim);

其中,is是输入流对象;str是目标字符串对象;delim是可选参数,表示定界符(分隔符,默认为换行符)。

使用getline()函数时,它会从输入流中读取一行文本,并将读取到的内容存储到目标字符串str中,直到遇到定界符(或文件结尾)为止。如果指定了定界符delim,则getline()函数会在遇到该字符时停止读取,否则默认为换行符。

#include <iostream>
#include <string>
using namespace std;

int main() {
  
    string str;
    cout << "请输入名字:";
    getline(cin, str);  //cin >> str;
    
     // 检查字符串是否为空
    if (str.empty()) {
        cout << "The string is empty." << endl;
    } else {
        cout << "The string is not empty." << endl;
    }
    
    return 0;
}

运行效果:

 特别说明:c++中,cin >> str 和 string类的getline(cin, str) 用来读取用户输入的两种不同方式的不同点:

数据类型不同:cin >> str是用来读取字符串类型的单个单词或数字型数据(整数、实数等),而getline(cin, str)则是用来读取整行的字符串。

分隔符:使用cin >> str时,输入被空白字符(如空格、制表符、换行符)分隔为不同的字符串,并将第一个非空白字符开始的连续字符序列存储到str中,剩余部分将会留在输入队列中;而getline(cin, str)则会读取整行输入,包括空白字符,在遇到换行符之前将其存储到str中。

输入限制:cin >> str只能读取到空白字符之前的内容,因此无法读取含有空格的字符串,一次只能读取一个单词或数字。而getline(cin, str)可以读取包含空格的完整行,因此可以读取多个单词或整行文本。

换行符处理:cin >> str读取后会将换行符留在输入流中,可以影响下一次读取操作。相比之下,getline(cin, str)会将换行符从输入流中移除,以防止影响后续读取操作。
【空白字符是指在文本中没有可见形式的字符,主要包括空格、制表符和换行符。它们在文本处理中具有不同的作用。

空格(Space):表示一个可见的空间,在文本中起到分隔单词或字符的作用。多个连续的空格会被视为一个空格。

制表符(Tab):通常用\t来表示,在文本中占据一个固定的宽度,经常用于对齐文本中的内容。

换行符(Newline):表示换行的特殊字符,在不同的操作系统中可能有不同的表示方式。在Unix和Linux系统中,换行符用\n表示;在Windows系统中,换行符由两个字符组成,即回车符(Carriage Return)和换行符,用\r\n表示。

这些空白字符在输入和输出操作中都需要注意处理。在C++中,空白字符通常用于分隔不同的数据项,而换行符用于标识一行的结束。了解和正确处理这些字符对于正确解析和处理用户输入以及生成正确格式的输出非常重要。】

2、演示了如何连接字符串、获取字符串长度、检查字符串是否为空、访问和修改字符串中的字符、查找子字符串的位置以及提取子字符串。您可以根据需要进一步使用std::string执行其他操作,例如插入、删除、比较等等。

#include <iostream>
#include <string>
using namespace std;

int main() {
    string str1 = "Hello";
    string str2 = " world!";
    
    // 连接两个字符串
    string result = str1 + str2;
    cout << "Concatenated string: " << result << endl;
    
    // 获取字符串长度
    cout << "Length of the string: " << result.length() << endl;
    
    // 检查字符串是否为空
    if (result.empty()) {
        cout << "The string is empty." << endl;
    } else {
        cout << "The string is not empty." << endl;
    }
    
    // 访问字符串中的字符
    char c = result[0];
    cout << "First character of the string: " << c << endl;
    
    // 修改字符串中的字符
    result[0] = 'h';  // 将第一个字符修改为小写 'h'
    cout << "Modified string: " << result << endl;
    
    // 查找子字符串的位置
    size_t pos = result.find("world");
    if (pos != string::npos) {
        cout << "Substring 'world' found at position: " << pos << endl;
    } else {
        cout << "Substring not found." << endl;
    }
    
    // 提取子字符串
    string sub = result.substr(6, 5);  // 从位置 6 开始,提取长度为 5 的子字符串
    cout << "Substring: " << sub << endl;
    
    return 0;
}

你可以编译运行试试看。

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

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

相关文章

ChatTTS web应用;基于文本指导的图像生成;使用Groq和Llama3在几秒内生成整本书;协作机器人画家,可以根据语言描述或图像在画布上作画

✨ 1: ChatTTS-Nuxt3 Webui ChatTTS-Nuxt3 WebUI是基于ChatTTS开发的文本转语音Web应用&#xff0c;支持详细参数调整和移动视图。 ChatTTS-Nuxt3 Webui 基于 ChatTTS 项目开发&#xff0c;由 2noise 创建&#xff0c;WebUI 开发则由 Gouryella 完成。你可以在 这里 免费试用…

C语言数字全排列生成器

前言 从0开始记录我的学习历程&#xff0c;我会尽我所能&#xff0c;写出最最大白话的文章&#xff0c;希望能够帮到你&#xff0c;谢谢。 提示&#xff1a;文章作者为初学者&#xff0c;有问题请评论指正&#xff0c;感谢。 这个代码的功能是生成并打印出从1到N的所有整数的…

zdppy_amauth 实现给角色批量绑定权限

新增接口 api.resp.post("/auth/role_auth", amauth.role.add_auths)如何测试 如何测试能不能给指定的角色批量的添加权限呢&#xff1f; 1、需要新建一个角色2、需要拿到这个角色的ID3、需要新增三个权限4、需要拿到新增的三个权限的ID5、拿着角色ID和权限ID列表…

通信技术振幅键控(ASK)调制与解调硬件实验

一、实验目的 1. 掌握用键控法产生ASK信号的方法&#xff1b; 2. 掌握ASK非相干解调的原理。 二、实验内容 1. 观察ASK已调信号的波形&#xff1b; 2. 观察ASK解调信号的波形。 三、实验器材 1. 双踪示波器&#xff1b; 2. 通信原理实验箱信号源模块、③、④、⑦号模块。…

输出流--6.6

代码以及解释&#xff1a; package java2;import java.io.File; import java.io.FileWriter; import java.io.IOException;public class Test02 {public static void main(String[] args) throws IOException {String str "flag{hello_ctf}";//1.封装File fnew Fil…

Locality-aware subgraphs for inductive link prediction in knowledge graphs

Locality-aware subgraphs for inductive link prediction in knowledge graphs a b s t r a c t 最近的知识图&#xff08;KG&#xff09;归纳推理方法将链接预测问题转化为图分类任务。 他们首先根据目标实体的 k 跳邻域提取每个目标链接周围的子图&#xff0c;使用图神经网…

鸿蒙轻内核M核源码分析系列六 任务及任务调度(2)任务模块

任务是操作系统一个重要的概念&#xff0c;是竞争系统资源的最小运行单元。任务可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它任务运行。鸿蒙轻内核的任务模块可以给用户提供多个任务&#xff0c;实现任务间的切换&#xff0c;帮助用户管理业务程序流程。…

鸿蒙北向开发 IDE DevEco Studio 3.1 傻瓜式安装闭坑指南

首先下载 安装IDE 本体程序 DevEco Studio 下载链接 当前最新版本是3.1.1,下载windows版本的 下载下来后是一个压缩包, 解压解锁包后会出现一个exe安装程序 双击运行安装程序 一路 next ( 这里涉及安装文件目录,我因为C盘够大所以全部默认了,各位根据自己情况选择自己的文件…

我的创作纪念日--我和CSDN一起走过的1825天

机缘 第一次在CSDN写文章&#xff0c;是自己在记录学习Java8新特性中Lambda表达式的内容过程中收获的学习心得。之前也有记录工作和生活中的心得体会、难点的解决办法、bug的排查处理过程等等。一直都用的有道笔记&#xff0c;没有去和大家区分享的想法&#xff0c;是一起的朋…

MotionEditor_ 通过内容感知扩散编辑视频运动

图1. MotionEditor&#xff1a;一种基于扩散的视频编辑方法&#xff0c;旨在将参考视频的运动转移到源视频中。 摘要 现有的基于扩散的视频编辑模型在随时间编辑源视频的属性方面取得了显著进展&#xff0c;但在修改运动信息的同时保持原始主角的外观和背景方面存在困难。为…

WordPress 插件推荐:菜单缓存插件——Menu Caching

今天在缙哥哥博客上发现了一个 WordPress 速度优化插件的优化感觉很不错&#xff0c;明月自己装上也体验了一番&#xff0c; WordPress 菜单的载入速度无论是 PC 端和移动端都非常不错&#xff0c;并且这个叫 Menu Caching 的菜单缓存插件还完美的兼容 WPRocket&#xff0c;W3 …

三.一布局和布局切换的实践与探索

在前端开发中&#xff0c;灵活的布局切换是一项非常实用的功能。今天&#xff0c;我想和大家分享一下如何在主组件中通过更换 Layout 目录下的组件来实现布局切换。 首先&#xff0c;我们有一个主组件 index.vue&#xff0c;它承担着整个页面的主要逻辑和展示。 而在 Layout …

PHP序列化、反序列化

目录 一、PHP序列化&#xff1a;serialize() 1.对象序列化 2.pop链序列化 3.数组序列化 二、反序列化&#xff1a;unserialize() 三、魔术方法 ​四、NSSCTF相关简单题目 1.[SWPUCTF 2021 新生赛]ez_unserialize 2.[SWPUCTF 2021 新生赛]no_wakeup 学习参考&#xff1…

使用 Logback.xml 配置文件输出日志信息

官方链接&#xff1a;Chapter 3: Configurationhttps://logback.qos.ch/manual/configuration.html 配置使用 logback 的方式有很多种&#xff0c;而使用配置文件是较为简单的一种方式&#xff0c;下述就是简单描述一个 logback 配置文件基本的配置项&#xff1a; 由于 logba…

优化 mac 储存空间的方法 只需一招为你的苹果电脑提速

在职场中&#xff0c;许多人都对苹果电脑情有独钟。苹果电脑以其简洁美观的设计、流畅稳定的性能以及出色的用户体验&#xff0c;成为了众多职场人士的得力助手。无论是处理文档、制作演示文稿&#xff0c;还是进行创意设计等工作&#xff0c;苹果电脑都能展现出其独特的优势&a…

HCIP-Datacom-ARST自选题库__多种协议简答【11道题】

1.BGP/MPLSIP VPN的典型组网场景如图所示&#xff0c;PE1和PE2通过LoopbackO建立MP-IBGP&#xff0c;PE1和PE2之间只传递VPN路由&#xff0c;其中PE1BGP进程的部分配置已在图中标出&#xff0c;则编号为0的命令不是必须的。(填写阿拉伯数字) 3 2.在如图所示的Hub&amp;Spok…

蒙层(css)

如何在 Vue 中实现一个包含图像和蒙层效果的组件&#xff1f;这个组件根据某个条件显示或隐藏蒙层&#xff0c;用于表示图像是否已读。 1. 创建基础模板 首先&#xff0c;我们在模板中使用 div 包裹我们的图像组件 GraphImage&#xff0c;并为最外层 div 设置 position: relat…

OTTO、亚马逊、Temu卖家如何运用测评补单来提高购买率?

在跨境电商的广阔舞台上&#xff0c;测评补单无疑是一股不可或缺的强劲动力。商家们深知&#xff0c;通过补单这一手段&#xff0c;能够快速为产品注入活力&#xff0c;使销量迅猛攀升&#xff0c;评论如潮涌至&#xff0c;进而在激烈的竞争中脱颖而出&#xff0c;勇攀销量之巅…

【Python数据预处理系列】Pandas 数据操作实战:掌握 .loc[] 方法进行高效数据选取

文章将详细介绍.loc[]方法的各种使用场景&#xff0c;帮助读者深入理解并掌握这一核心功能。 在Pandas库中&#xff0c;.loc[]方法是一种强大而灵活的数据选取工具。本文将通过详细的步骤和示例&#xff0c;手把手教您如何利用这一工具进行高效的数据操作。 首先&#xff0c;我…

【数据集划分】假如你有超百万条oracle数据库数据(成真版)

【数据集划分】假如你有接近百万条oracle数据库数据&#xff08;成真版&#xff09; 写在最前面小结 数据集划分原因注意事项 1. 留出法&#xff08;Hold-out Method&#xff09;原理算法复杂度代码示例Scikit-learn的train_test_split分布式计算框架&#xff08;如Apache Spar…