C++抽象编程——字符串(2)——<string>库的应用与字符串遍历

来源:互联网 发布:南通cnc数控编程培训 编辑:程序博客网 时间:2024/06/05 16:28

Operator overloading

正如你在上篇的图中所看到的一样,string库利用了C++中非常强大的特性,重新定义了一系列的标准运算,我们称为运算符重载(operator overloading)。它根据操作对象的数据类型,重新定义了操作符的行为。 在<string>库中,最重要的是重载的运算符是+号。 当+应用于数字时,它执行加法。 当+时应用于字符串,它执行字符串之间的连接,就是把两个字符串首尾相连接。你还可以使用+ =形式将新文本连接到现有字符串上, +和+ =运算符允许串联或单个的连接字符,比如下面的例子,它设置字符串变量str为字符串“abcd”:

#include <iostream>#include <string>using namespace std;int main() {string str = "abc";str += "d";cout << str << endl;return 0;}

结果如图;

学过Java的人可能想+运算符通过其他类型的值将这些值转换为字符串,然后连接他们在一起。 很遗憾,该功能在C ++中不可用,它会把使用具有不兼容操作数的+运算符作为错误返回。C ++还重载关系运算符,以便可以比较字符串值(这比很多语言,比如C和java中更加方便)。例如,你可以检查str的值是否等于“quit”:

if (str == "quit")

关系运算符使用字母顺序来比较字符串,他的顺序由底层ASCII代码定义。 所以,很显然这是区分大小写的,因此“abc”不等于“ABC”。


Selecting characters from a string

在C++中,string的下标是从0开始计数的,比如我们上一篇的博文中的“hello, world”,它每一个元素的下标如图:


每一个字符下面的数字代表字符所在的位置,我们称为下标(index)。C++提供了两种不同的办法去从一个字符串中提取单个字符。其中一种就是在string的后面加一个方括号,里面提供它的下标比如:

str[0]

此时,它将会返回第一个元素“h”。C++还提供了另外一个调用方法,.at 方法,虽然上面的方式我们更好理解,但是在除了字符串的过程中,我们更愿意用.at函数去代替上面的方法,因为.at方法会检查你的下标是否越界。他们的功能都是一样的,操作如下:

str.at(i)

其实我们不仅仅可以选择他们,我们还可以对选择的字符进行赋值操作,比如:

str[0] = 'H'; 或者 str.at(0) = 'H';

这个时候字符串就变为了 “Hello, world”。


String assignment

C ++重新定义字符串的赋值,以便为一个字符串赋值另一个复制字符,就像这样:

str2 = str1;

这个表达式,意思就是把str1的字符赋值给str2,在这期间注意是先把str1 copy下来再进行赋值,复赋值后str1的值不受影响,也就是单纯的复制,除非这个str的参数为引用类型。


Extracting parts of a string

字符串的连接使得一个字符串由短变长,但是我们常常做的操作却是在一个长字符串中进行一些翻转,分离操作。 字符串类出口一个名为substr的方法,它接受两个参数:要选择字符的索引开始位置和截止的位置。 调用str.substr(start,n)通过从str指定的索引位置开始从str中提取n个字符来创建一个新字符串。 例如,如果str包含字符串“hello,world”,则调用方法

str.substr(1, 3);

那么它会返回一个从位置1跟3截取的字符串“ell”,当然我们如果只是输入一个数字,那么它就默认为开始位置,一直截取到最后,例如:

str.substr(7)

那么返回的是“world”。当然我们也可以写一个函数来获取字符串的后半部分:

string secondHalf(string str) {return str.substr(str.length() / 2);}


Searching within a string

很多时候,你会发现我们常常要在一个字符串中查找某个特殊的字符或者字符,这是很经常的操作。为了解决这个问题,<string>库出口了一个叫 str.find(pattern)的函数来帮助你。这个函数返回第一个遇到这个字符或者字符串的下标,例如我们上面的例子:


x不在字符串中,所以我们返回系统定义的找不到的error。

Iterating throughthe characters in a string

         虽然<string>库中提供了很多强力的工具来处理字符串,但是通过学习一些简单的代码示例去编程往往使得问题更加简单,这样的编程示例我们称为范式(pattern)。例如我们遍历字符串中的字符我们需要用到下面的代码:

for (int i = 0; i< str.length(); i++) {
. . . body of loop that manipulates str[i] . . .
}

在每个循环周期,选择表达式str [i]指的是字符串中第i个字符,循环的目的是处理每个字符,循环继续,直到i到达字符串的长度。 因此,你可以使用下面的函数来数该字符串中的空格数量,代码如下:

#include <iostream>#include <string>using namespace std;int countSpaces(string str);int main() {string str;getline(cin,str);cout << "空格数量为:" << countSpaces(str) << endl;return 0;}/*里面的for循环是重点*/ int countSpaces(string str) {int nSpaces = 0;for (int i = 0; i < str.length(); i++) {if (str[i] == ' ') nSpaces++;}return nSpaces;}

运行结果如下;

对于某些应用,通常从后面开始遍历会有意想不到的结果。所以我们可以通过下面的范式实现从后面开始遍历,

for (int i = str.length() - 1; i >= 0; i--)
这里 i从最后一个字符的下标开始往回遍历,一直到下标为0为止。当然我们自己也可以通过思考写出这些代码,但是这会恒消耗你的时间,我们可以适当的记忆一些标准的范式以提高我们的编程效率。当然,我们肯定是可以从前面开始遍历的:

for (int i = 0; i < str.length(); i++)

对于某些程序,你可能要修改不同的循环模式来开始或者结束循环,比如要求写一个函数来检查某个字符串是否以某个特别的前缀开头,代码如下:

bool startsWith(string str, string prefix) {if (str.length() < prefix.length()) return false;for (int i = 0; i < prefix.length(); i++) {if (str[i] != prefix[i]) return false;}return true;}
程序一开始检查两边的长度,以确保str的长度不能小于prefix(前缀)的长度,当你阅读这个程序的时候,很值得你思考的是这两个return语句,一旦发现字符串之间和前缀不同,那么内部循环就会返回false,当遍历完所有的字符后都没有发现有不同的字符,程序的循环外部才会返回true。以后这个基础的范式你会一次又一次的发现。

Growing a string through concatenation

另外一个你要记住的范式就是创建一个含同样字符的字符串,虽然循环的结构体取决于应用程序本身,但是一般的模式斗志这样的:

string str = " ";
for (whatever loop header line fits the application) {
str += the next substring or character;
}

作为一个简单的例子,我们可以写出下面的一个函数:

string repeatChar(int n, char ch) {string str = "";for (int i = 0; i < n; i++) {str += ch;}return str;}
当我们使用输出语句的时候,比如:

cout << repeatChar(72, '-') << endl;
这个时候会输出72个减号;

很多时候,我们将连接范式跟循环范式一起使用,比如我们的字符串翻转函数,就像"desserts",翻转后变为"stressed",代码如下;

string reverse(string str) {string rev = "";for (int i = str.length() - 1; i >= 0; i--) {rev += str[i];}return rev;}
稍后补上完整的代码。实话,这些函数很有用。


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孩子不喜欢做作业怎么办 宝宝腿不一样粗怎么办 一个小腿肿了怎么办 左右小腿不一样粗怎么办 小孩不敢自己睡怎么办 小孩不一个人睡怎么办 晚上一个人睡觉害怕怎么办 孩子自己睡害怕怎么办 小孩晚上睡觉怕怎么办 小孩分房睡害怕怎么办 坐飞机不认识字怎么办 科目一不识字怎么办 孩子不自己睡觉怎么办 70岁老人坐高铁怎么办 八岁儿童怎么办护照 第一次坐飞机有点紧张怎么办 坐飞机恐高耳鸣怎么办 火车坐过站怎么办 凌晨的火车应该怎么办 高铁坐过一站怎么办 宝宝断奶瘦了怎么办 第一次坐飞机怕晕机怎么办 焦虑症怕坐飞机怎么办 新生宝宝老是哭闹怎么办 宝宝坐飞机后哭闹怎么办 飞机经济舱不支持退票怎么办 证件被单位扣押怎么办 小孩高烧41度怎么办 国际航班未成年托管怎么办手续 如果飞机上发烧怎么办 不到二岁飞机票怎么办 做飞机婴儿票怎么办 公司拖欠报销款怎么办 高考志愿滑档怎么办 中考志愿没录取怎么办 美工30岁以后怎么办 水彩纸破了怎么办 ps放大后模糊怎么办 手机照相机删了怎么办 索尼6300要自拍怎么办 水彩纸鼓起来怎么办