当前位置: 首页 > news >正文

【C++ STL详解】——string类

目录

前言

一、string类对象的常见构造

二、string类对象的访问及遍历

1.下标+【】(底层operator【】函数)

​编辑

2.迭代器

3.范围for

4.at

5.back和front

三、string类对象的容量操作

1.size 和 length

2.capacity

3.empty

4.clear

5.resize(调整当前字符串的大小)

6.reserve(改变当前容量的大小)

7.shrink_to_fit(缩容)

四、string类对象的修改操作

1.operator+=(尾部追加)

2.append(拼接)

3.push_back(尾插)

4.insert(插入)

5.erase(删除)

6.replace(替换)

7.swap(交换)

五、string的查找

1.find(左闭右开区间,正向查找)

2.rfind(反向查找)

六、string的截取

substr:左闭右开

七、string与字符串的转化

1.字符串转化为string

2.string转为字符串

八、非成员函数重载

1.operator<<和operator>>(输入输出运算符重载)

2.relational operators (string)


前言

好了,老铁们,前面我们对C++的一些基础语法以及一些注意事项都有了一定的了解!那么接下来我们将要进入一个崭新的世界,就是对STL库的学习!对于STL的学习核心有三点:熟用、明理(底层实现)、扩展!下面先来看看string类

  • 通过文档可以看出string是表示字符串的字符串类
  • 底层实际是:basic_string模板类的别名,typedef  basic_string<char, char_traits, allocator>stirng;
  • 使用string类时,必须包含#include头文件以及using namespace std;

如果想要了解更多,关于string类的说明,大家可以参照这个文档:string类

一、string类对象的常见构造

string();   //构造一个空字符串,长度为0(默认构造)string (const string& str); //拷贝构造string (const char* s); //复制s所指向的字符序列string (const char* s, size_t n); //复制所指向的字符序列的前n个字符string (size_t n, char c);      //复制n个字符Cstring (const string& str, size_t pos, size_t len = npos);
//复制str中从字符位置pos开始并跨越len个字符的部分(如果str太短或len为string::npos,则复制到str的末尾)

示例:

	string s0;                         //构造空串string s1("is string");            //复制is stringconst char* s = "hello string";string s2(s);                      //复制"hello string"string s3(s, 3);                   //复制"hello string"前3个字符string s4(10, '#');                //复制10个#string s5(s1, 0, 5);               //从s1中的位置0开始跨越5个字符的部分,左闭右开区间cout << s0 << endl;cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;

二、string类对象的访问及遍历

1.下标+【】(底层operator【】函数)

string s1("hello string");
for (int i = 0; i < s1.size(); i++)
{cout << s1[i] << ' ';//底层写法:cout << s1.operator[](i) << endl;
}

2.迭代器

  • 正向迭代器(begin+end)

begin函数:返回一个指向字符串第一个字符的迭代器

end函数:返回一个指向字符串最后一个字符的下一个位置(即为'\0')的迭代器

这里要注意到,迭代器的函数都会有两个形式一个是非const,一个是const!会根据对象类型的不同去选择不同的函数!

示例:

string s1("hello string");
string::iterator it = s1.begin();
while (it != s1.end())
{cout << *it << ' ';it++;
}
	const string s2("hello string");string::const_iterator it = s2.begin();while (it != s2.end()){cout << *it << ' ';it++;}//    const对象返回的是const迭代器,所以不能用普通迭代器去接受

  • 反向迭代器(rbegin+rend)

rbegin函数:返回一个指向字符串最后一个字符的反向迭代器

rend函数:返回一个指向字符串第一个字符前理论元素的反向迭代器(被认为是反向端)

示例:

	string::reverse_iterator it1 = s1.rbegin();while (it1 != s1.rend()){cout << *it1 << ' ';it1++;}

可以看出,其实就是反向输出!但是要注意它是反向++的

3.范围for

for (auto a : s1)
{cout << a << ' ';
}

其实,范围for底层就是个迭代器!!!

4.at

	for (int i = 0; i<s.length(); ++i){cout << s.at(i) << " ";}

注意:这里是at(),不是方括号[],和第一个operator功能类似,但是唯一的不同在于,两者对于越界的处理不同!

5.back和front

cout << s.back() << endl;;//访问到最后一个字符
cout << s.front();//访问第一个字符

注意:它访问到的同时,还可以进行修改!

s.back() = 'A';//最后一个元素变为A
s.front() = 'B';//第一个变为B
cout << s.back() << ' ';
cout << s.front();

三、string类对象的容量操作

1.size 和 length

string s1("hello string");
cout << s1.size() << endl;
cout << s1.length() << endl;//返回字符串有效长度

size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。他们得到的结果并不一定等于capacity!

2.capacity

s1.capacity();//返回总空间的大小

3.empty

 s1.empty();//检测字符串是否为空,为空就返回true,否则返回false

4.clear

 s1.clear();//擦除字符串内容,使其变为空字符串,并不改变底层空间的大小

5.resize(调整当前字符串的大小)

会出现以下两种情况:

        ①如果n小于当前字符串的长度,那么他就会将当前长度缩短到n个字符的长度,并将第n个字符以外的其他部分全部删除!

        ②如果n大于当前字符的长度,那么就会将大小扩大到n,扩大的部分如果有字符c,那就拿字符C填充,没有就拿字符'\0'补充!

6.reserve(改变当前容量的大小)

规则如下:

  • 如果n大于当前的容量,那么容量就会扩充到n甚至更大
  • 如果n小于当前容量,那就什么都不做
  • 这个函数不会影响字符串的长度,也不会改变其内容

7.shrink_to_fit(缩容)

规则:调整其capacity以适应它的size

四、string类对象的修改操作

1.operator+=(尾部追加)

如上图,有常见的三种重载形式,功能就是:通过在当前字符串的末尾附加额外字符来扩展字符串

string s("hello string");
s += " ";
s += "!!!!!!";
cout << s << endl;
string s2 = ("  ggggg  ");
s += s2;
cout << s << endl;

2.append(拼接)

这个函数的功能:也是上面的一样,追加,额……但是重载函数有很多,但是常用的就三种:

string& append(const string& str);

string& append(const char*s);

string& append(size_t  n,char c);

	string s("hello string");s.append(" ");s.append("sjda");s.append(10, 'A');cout << s << endl;

3.push_back(尾插)

功能:将字符c追加到字符串的末尾,使其长度增加1。

s.push_back('A');

4.insert(插入)

额……还是有点多,其实常用的就一个:在pos位置前插入字符串

string& insert(size_t pos,const char *s);

int main()
{string s("hello string");s.insert(5, "hhhhhe");//在第五个位置前,插入字符串“hhhhhe”cout << s << endl;return 0;
}

5.erase(删除)

规则:擦除字符串中从字符位置pos开始并跨越len字符的部分(如果内容太短或len为string::npos,则擦除直到字符串末尾)。

s.erase(0, 5);//删除从第0个位置开始的5个字符
cout << s << endl;//迭代器
s.erase(s.begin() + 1);
cout << s << endl;//删除第二个位置的值//删除区间的元素,区间为左闭右开[first,last)
s.erase(s.begin() + 1, s.end() - 1);
cout << s << endl;

6.replace(替换)

其实也有很多个,hh,大家想看完整的可以自己点进链接,下面两种是最常用的

  • String& replace (size_t pos, size_t len, const char* s);
cout << s.size() << endl;
s.replace(0, 4, "AAAAAAAAA");//从0位置开始的4个字符替换成特定字符串,
//但是有一点需要注意,字符串的内容的长度可以任意,随之大小也会改变cout << s << endl;
cout << s.size() << endl;

  • String& replace (size_t pos, size_t len, size_t n, char c);
cout << s.size() << endl;
cout << s.capacity() << endl;s.replace(0, 4, 100, 'V');//从0位置开始的4个字符替换为100个字符‘V’
cout << s << endl;
cout << s.size() << endl;
cout << s.capacity() << endl;

编译器会按照自己特定的方式进行扩容,在LInux下又是另外的扩容方式!!

需要注意:

上面的尾部追加字符s.append(1,c) / s.push_back(c) /s+='c'其实实现的差不多,但是实际应用中使用+=比较多,它不仅仅可以连接字符,还可以连接字符串

②实际上insert/erase/replace,但数据很大时,需要挪动大量的数据,效率太低,能少用就尽量少用!!!

③对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

7.swap(交换)

        对于这个交换函数,其实在STL库里面有两个,一个是作为string类的成员函数,一个是全局的函数,谁都可以用的!

int main()
{string s1("hello s1");string s2("hello s2");//用string里面的交换函数s1.swap(s2);cout << s1 << endl;cout << s2 << endl;cout << endl;//全局的swapswap(s1, s2);cout << s1 << endl;cout << s2 << endl;return 0;
}

五、string类的查找

1.find(左闭右开区间,正向查找)

功能:从字符串pos位置(不写默认是0)开始往后找字符c,返回的是第一个匹配的第一个字符的位置。
如果没有找到匹配项,函数返回string::npos(-1)。(n
pos是一个静态成员常量值,具有size_t类型元素的最大可能值

注意:他们都是const成员函数,就是说可读不可写,仅仅只是查找,遍历访问操作它是可以改变值的,也就是可读可写!

int main()
{string s("http://baidu.com/");string s2("bai");//find(string,pos)返回第一个匹配的位置,也就是b的位置size_t pos1= s.find(s2);cout << pos1 << endl;//find(str,pos)size_t pos2 = s.find("com");cout << pos2 << endl;//find(字符,pos)size_t pos3 = s.find('u');cout << pos3 << endl;return 0;
}

这里没有演示第三个重载函数,因为它其实和第二个重复了,直接用第二个就好了!

2.rfind(反向查找)

功能:从pos位置(默认是npos位置)开始向前查找字符串或者字符,找到就返回它的位置,这个位置是从前先后数的;如果没有找到就返回npos(换个方向理解就是:找到最后一次匹配的第一个字符的位置

注意:这里的第三个重载函数其实和find的情况是一样的,重复了第二个,感觉有点多余(个人吐槽)

六、string类的截取

substr:左闭右开

功能:从pos位置开始,截取n个字符,返回的结果是一个新的字符串对象,这个新对象的内容就是使用截取到子字符串去初始化!

所以这个实际上可以和find去结合使用

七、string类与一些类型的转化

1.字符串转化为string

这个很简单,其实就是第一部分的常见构造的方式!!

string s1("hello string");char str[] = "hello string";
string s2(str);

2.string转为字符串

这个可以使用string类中的c_str或者date

c_str: const char *c_str() const;

data: const char *data() const;

区别:在C++98中,C_str转化过来的,在末尾会加上"\0",但是data不会!在C++11中,两者都会加!

string s("https://cplusplus.com/reference/string/string/rfind/");const char* str1 = s.c_str();
const char* str2 = s.data();
cout << str1 << endl;
cout << str2 << endl;

3.内置类型转化为string

double d = 40.25;
string s1 = to_string(d);

还可以是其他的内置类型哦!!!!!

4.string转化为内置类型

string s1("45.630");
double d = stod(s1);

八、非成员函数重载

1.operator<<和operator>>(输入输出运算符重载)

Istream& operator>> (Istream& is, string& str);输入运算符重载

Ostream& operator<< (Ostream& os, const string& str);输出运算符重载

string s;
cin>>s;
cout<<s<<endl;

因为有了这个重载函数,所以可以使用cin和cout输入输出string类!

2.relational operators (string)(大小比较)

这是string类的关系操作符,包括==,!=,<,<=,>,>=。重载的函数,支持string类和string类、string类和字符串之间的比较!

int main()
{string s1("hello");string s2("hikklkl");//string 和stringcout << (s1 == s2) << endl;cout << (s1 != s2) << endl;cout << (s1 < s2) << endl;cout << (s1 <= s2) << endl;cout << (s1 > s2) << endl;cout << (s1 >= s2) << endl;cout << endl;//string和字符串const char* s3 = "hella";cout << (s1 == s3) << endl;cout << (s1 != s3) << endl;cout << (s1 < s3) << endl;cout << (s1 <= s3) << endl;cout << (s1 > s3) << endl;cout << (s1 >= s3) << endl;return 0;
}

十分的爽!

3.getline(获取一行字符串)

这个函数的存在,其实就是因为cin和scanf的一点小缺陷,看代码

发现了什么,明明输入的A B,可是出来的却是A,其实就是因为cin和scanf在遇到空格时就会停止读取后面的字符,而后面的字符实际上放在缓冲区里!在读取一次看看

此时,A B才能完全输出!有了getline就很方便!

这个函数也是有两个用法的:

如果有界定符,那就读取到界定符为止,后面的字符直接丢弃!

string s;
getline(cin, s,'r');//读到分隔符‘r’为止
cout << s << endl;

②如果没有,那就是默认到‘\0’


好了,感谢大家的阅读!这部分内容有点小多,大家如果想要查看原文档可以点击string文档!

其实实际上用到不多!!题中见分晓!

相关文章:

【C++ STL详解】——string类

目录 前言 一、string类对象的常见构造 二、string类对象的访问及遍历 1.下标【】&#xff08;底层operator【】函数&#xff09; ​编辑 2.迭代器 3.范围for 4.at 5.back和front 三、string类对象的容量操作 1.size 和 length 2.capacity 3.empty 4.clear 5.res…...

MatplotlibPython 1 3.7

放大数据&#xff0c;如果想仔细看某一行的数据的时候 可以调不同的颜色&#xff0c;图片的长宽高&#xff0c;以及线的种类 plt.figure 这个命令下的所有东西都在这个figure里面 plt.xlim 改变坐标轴的范围 plt.xlabel 改变坐标轴的总名称 plt.xticks 换单位 plt.yt…...

深入理解 Dubbo:构建分布式服务治理体系

目录 1. 介绍 2. Dubbo 的核心概念 2.1 服务提供者&#xff08;Provider&#xff09;与服务消费者&#xff08;Consumer&#xff09; 2.2 注册中心&#xff08;Registry&#xff09; 2.3 监控中心&#xff08;Monitor&#xff09; 3. Dubbo 的功能特性 3.1 远程调用&…...

唤起原生IOS和安卓Android app的方法

大家好我是咕噜美乐蒂&#xff0c;很高兴又和大家见面了&#xff01; 要唤起原生 iOS 或 Android 应用程序&#xff0c;你可以使用以下方法&#xff1a; 唤起原生 iOS 应用程序 在 iOS 上&#xff0c;你可以使用自定义 URL 方案或 Universal Links 来唤起原生应用程序。以下…...

RabbitMQ的web控制端介绍

2.1 web管理界面介绍 connections&#xff1a;无论生产者还是消费者&#xff0c;都需要与RabbitMQ建立连接后才可以完成消息的生产和消费&#xff0c;在这里可以查看连接情况channels&#xff1a;通道&#xff0c;建立连接后&#xff0c;会形成通道&#xff0c;消息的投递、获取…...

GitHub登不上:修改hosts文件来解决(GitHub520,window)

参考链接&#xff1a;GitHub520: 本项目无需安装任何程序&#xff0c;通过修改本地 hosts 文件&#xff0c;试图解决&#xff1a; GitHub 访问速度慢的问题 GitHub 项目中的图片显示不出的问题 花 5 分钟时间&#xff0c;让你"爱"上 GitHub。 (gitee.com) GitHub网站…...

01-DevOps代码上线-git入门及gitlab远程仓库

一、准备学习环境 10.0.0.71-gitlab 2c2g-20GB 10.0.0.72-jenkins 2c2g-20GB 10.0.0.73-sonarqube 1c1g-20GB 10.0.0.74-nexus 1c1g-20GB 10.0.0.75-dm 1c1g-20GB &#xff08;模拟写代码服务器&#xff09; 在centos系统中&…...

EdgeX Foundry 安全模式安装部署

文章目录 一、安装准备1.官方文档2. 克隆服务器3.安装 Docker4.安装 docker-compose 二、安装部署1.docker-comepse2.启动 EdgeX Foundry3.访问 UI3.1. consul3.2. EdgeX Console EdgeX Foundry # EdgeX Foundryhttps://iothub.org.cn/docs/edgex/ https://iothub.org.cn/docs…...

网络安全-appcms-master

一、环境 gethub上面自己找appcms-master 二、分析一下源码以及闯关思路 首先是有一个函数循环以及函数过滤&#xff0c;我们的post会将我们所传的所有val值去进行一个循环&#xff0c;之后通过htmlspecialchars这个函数进行过滤和转换所以val值不能通过单双引号闭合注入的方…...

ThreadLocal 与 synchronized 区别

我的理解 目的都是为了一个大前提:操作内容的线程安全。 任务不同&#xff1a;synchronized 解决的是多线程下线程操作权限的问题&#xff0c;以及原子性的保证。通过对锁的竞争&#xff0c;达到对资源的访问有序。 ThreadLocal是解决的事多线程下资源的隔离问题&#xff0c;即…...

灵魂指针,教给(二)

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一、数组名的理解 二、使用指针访问数组 三、一维数组传参本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组…...

线程安全--浅谈Ad-hoc与加锁的区别

浅谈Ad-hoc 与加锁 两者要解决的都是对对象的语义混乱操作&#xff0c;即有个count进行累加操作。 我的理解/文心一言的反馈如下: 加锁是保证我们对同一个count在多线程下的访问有序&#xff0c;即“读写-修改-写入”具有原子性。 而Ad-hoc机制就是通过程序员自己定义一个私有…...

数据治理实战——翼支付金融板块业务数仓建设和数据治理之路

目录 一、数据治理背景 二、数据治理建设内容 2.1 组织协同 2.2 平台建设 2.3 数据应用治理 2.4 数据规范 2.5 数据安全 三、企业级数仓建设 3.1 调研阶段 2.2 平台护航 2.3 数仓分层 2.4 维度建模 2.4.1 维度建模四步曲 2.4.2 命名规范 2.4.3 资产沉淀 2.4.4 …...

[Buuctf] [MRCTF2020]Transform

1.查壳 64位exe文件&#xff0c;没有壳 2.用64位IDA打开 找到主函数&#xff0c;F5查看伪代码 从后往前看&#xff0c;有一个判断语句&#xff0c;是两个数组进行比较的&#xff0c;我们双击byte_40F0E0查看里面的内容 所以能够推出byte_414040的内容&#xff0c;byte_4140…...

【C++】C++模板基础知识篇

个人主页 &#xff1a; zxctscl 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 文章目录 1. 泛型编程2. 函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 3. 类模板3.1 类模板的定义格式3.2 类模板的实例化…...

golang 注释插件

Goanno插件 自动生成golang注释,该插件为 Intellij/Goland 中的 golang 提供自动生成注释 如何使用&#xff1f; control command / (for windows: control alt /)&#xff08;生成注释&#xff09;Right click -> Generate -> Goanno&#xff08;生成注释&#x…...

Unity插件之天气系统UniStorm

首先呢&#xff0c;它是一款强大的动态昼夜天气系统&#xff0c;能够以较快的帧速率创建AAA级动态生成的天气、照明和天空&#xff0c;并且具有300多个可定制的组件&#xff0c;允许用户创建任何可以想象的环境。 第一步&#xff1a;他需要两个物体Camera摄像机、Player播放器…...

Java使用xlsx-streamer和EasyExcel解决读取超大excel文件数据处理方法

前言 最近有个项目在生产环境做数据导入时&#xff0c;发现开始执行导入任务会出现cpu狂飙的情况。几番定位查找发现是在读取excel的时候导致此问题的发生&#xff0c;因此在通常使用的为POI的普通读取&#xff0c;在遇到大数据量excel&#xff0c;50MB大小或数五十万行的级别的…...

智能驾驶规划控制理论学习04-基于车辆运动学的规划方法

目录 一、线性二自由度汽车模型&#xff08;自行车模型&#xff09; 1、二自由度模型概述 2、不同参考点下的状态空间方程 3、前向仿真 二、运动基元生成方法 1、杜宾斯曲线&#xff08;Dubins Curve&#xff09; 2、Reeds Shepp Curve 三、多项式曲线&#xff08;Poly…...

一键查看:大厂网站都用了啥技术栈,有图有真相。

本次我们采用Wappalyzer插件来看下国内大厂的网站都采用了什么技术架构&#xff0c;文章最后由Wappalyzer的安装方法。 今日头条网站 淘宝网站 哔哩哔哩 京东商城 花瓣网 CSDN 国务院 网易 58同城 腾讯网 如何安装Wappalyzer 用Edge浏览器即可...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...