C++知识点之string,结合华为编程题:简单错误记录分析(附加容器pair知识点)

来源:互联网 发布:广电网络建阳分公司 编辑:程序博客网 时间:2024/05/22 14:57

C++中string类的详解

string是C++标准库的一个重要的部分,主要用于字符串处理。可以使用输入输出流方式直接进行操作,也可以通过文件等手段进行操作。

string类的声明

头文件:#include< string >
命名域的声明:using namespace std;

string类的函数原型

string类的构造函数:
string(const char *s); //用c字符串s初始化
string(int n,char c); //用n个字符c初始化

string类的字符操作:
substr操作:
s.substr(pos1,n)返回字符串位置为pos1后面的n个字符组成的串
如:string s2=s.substr(1,5)

insert操作:
s.insert(pos,str)//在s的pos位置插入str
s.insert(s.it,ch)// 在s的it指向位置前面插入一个字符ch,返回新插入的位置的迭代器
注意用迭代器当参数和无符号数当参数的区别

erase操作:
指定pos和len,其中pos为为起始位置,pos以及后面len-1个字符串都删除
如:str.erase (10,8);
迭代器,删除迭代器指向的字符
如: str.erase (str.begin()+9);
迭代器范围,删除这一范围的字符串,范围左闭右开
如:str.erase (str.begin()+5, str.end()-9);

append和replace操作:
append函数可以用来在字符串的末尾追加字符和字符串
如: str.append(str2); //直接追加一个str2的字符串
repalce顾名思义,就是替换的意思,先删除,后增加。
如:str.replace(9,5,str2)//第9个字符以及后面的4个字符被str2代替

assign操作:
assign操作在一起列容器当中都存在,比如vector等等。是一个很基本的操作函数,string使用assign可以灵活的对其进行赋值。
如:str.assign(base) //直接把base赋值给str;
str.assign(base,10,9); //把base第10个字符以及后面的8个字符赋给str

string的搜索操作:

find和rfind函数:
find函数主要是查找一个字符串是否在调用的字符串中出现过,大小写敏感。
如:found=str.find(“needles are small”,found+1,6);//在str当中,从第found+1的位置开始查找参数字符串的前6个字符

rfind函数就是找最后一个出现的匹配字符串,返回的位置仍然是从前往后数的。
std::size_t found = str.rfind(key); //rfind是找最后一个出现的匹配字符串

string的比较与转换:

compare函数:
和strcmp函数一样,如果两个字符串相等,那么返回0,调用对象大于参数返回1,小于返回-1。
如:s1=”123”,s2=”1234”;
cout < < s1.compare(s2)<< endl;//-1

s1=”1234”,s2=”123”;
cout<< s1.compare(s2)<< endl;//1

string的特性描述:

int capacity()const; //返回当前容量(即string中不必增加内存即可存放的元素个数)
int size()const; //返回当前字符串的大小()
int length()const; //返回当前字符串的长度
注意:字符串大小和长度是不等价的。区别在于,size()=length()+1; 计算字符串大小时,结束符“\0”也占一个字节。

string类的大部分函数:
begin 得到指向字符串开头的Iterator
end 得到指向字符串结尾的Iterator
rbegin 得到指向反向字符串开头的Iterator
rend 得到指向反向字符串结尾的Iterator
size 得到字符串的大小
length 和size函数功能相同
max_size 字符串可能的最大大小
capacity 在不重新分配内存的情况下,字符串可能的大小
empty 判断是否为空
operator[] 取第几个元素,相当于数组
c_str 取得C风格的const char* 字符串
data 取得字符串内容地址
operator= 赋值操作符
**reserve 预留空间
swap 交换函数**
insert 插入字符
append 追加字符
push_back 追加字符
operator+= += 操作符
erase 删除字符串
clear 清空字符容器中所有内容
resize 重新分配空间
assign 和赋值操作符一样
replace 替代
copy 字符串到空间
find 查找
rfind 反向查找
find_first_of 查找包含子串中的任何字符,返回第一个位置
find_first_not_of 查找不包含子串中的任何字符,返回第一个位置
find_last_of 查找包含子串中的任何字符,返回最后一个位置
find_last_not_of 查找不包含子串中的任何字符,返回最后一个位置
substr 得到字串
compare 比较字符串
operator+ 字符串链接
operator== 判断是否相等
operator!= 判断是否不等于
operator< 判断是否小于
operator>> 从输入流中读入字符串
operator<< 字符串写入输出流
getline 从输入流中读入一行

华为编程题:简单错误记录

直接上题目:
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1.记录最多8条错误记录,对相同的错误记录(即文件名称和行号完全匹配)只记录一条,错误计数增加;(文件所在的目录不同,文件名和行号相同也要合并)
2.超过16个字符的文件名称,只记录文件的最后有效16个字符;(如果文件名不同,而只是文件名的后16个字符和行号相同,也不要合并)
3.输入的文件可能带路径,记录文件名称不能带路径

输入描述:

一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。

文件路径为windows格式如:E:\V1R2\product\fpgadrive.c 1325

输出描述:

将所有的记录统计并将结果输出,格式:文件名代码行数数目,一个空格隔开,如: fpgadrive.c 1325 1

结果根据数目从多到少排序,数目相同的情况下,按照输入第一次出现顺序排序。如果超过8条记录,则只输出前8条记录.如果文件名的长度超过16个字符,则只输出后16个字符

示例1
输入

E:\V1R2\product\fpgadrive.c 1325
输出

fpgadrive.c 1325 1

本题分析:
1、本题主要考察的是字符串的基本操作问题,因此需要掌握字符串的最基本的一些操作,如:substr, rfind, erase 等。
2、由于本题需要用到的键与值的对应问题,因此需要用到pair操作,具体用法会在后面讲解。
3、本题主要就是实现字符串中内容的对比和字符串长度的大小操作。

实现流程:
1、输入案例方式:
因为本题需要输入多行的字符串,并分别对每一行的字符串进行处理,因此输入方式如下:

string input;while(getline(cin,input)){//表示对输入的字符串整行的取,getline用法如下://getline(istream &in, string &s),从输入流读入一行到string s}

2、本题是对每个字符串的错误次数进行统计,因此会形成字符串为键值对应错误次数的值的对应关系,又因为需要一个容器可以同时存储字符型的数据和整形的数据,因此需要用到容器里的pair工具。本体实现方式如下:

//创建一个容器,用标准库类型进行定义vector < pair <string,int >> errors;//利用这种类型,定义一个实例make_pair(file,1);

3 、用rfind函数查找文件名前面的位置,然后把文件名提取出来,用上述方式记录错误次数。简单点说就是包含文件名的字符串对应一个错误次数。并添加一个遍历,若出现重复的文件名,则错误次数加1,删除文件名。

4、对生成的数据要求是从多到少的排序,因此要对vector进行排序,用到函数为stable_sort(errors.begin(),errors.end(),cmp);并重新对cmp进行定义;
注意sort和stable_sort的区别:
stable_sort的用法与sort一致,区别是stable_sort函数遇到两个数相等时,不对其交换顺序;

5、最后是输出方式。本题要求输出最长为16个字符。因此需要判断,当超过16个字符的时候,就截取最后的有效16位,用到函数为erase();

代码实现如下:

#include<iostream>#include <string>#include <vector>#include <algorithm>using namespace std;bool cmp(pair<string ,int>a, pair<string , int>b){    return a.second>b.second;}int main(){    string input,file;    vector<pair<string,int>> errors;//pair的用法!!    while(getline(cin, input))    {        if(input.size()==0)        {            //输出字符串为空,表示结束输入            break;        }        unsigned int p=input.rfind('\\');        file=input.substr(p+1);        errors.push_back(make_pair(file,1));        for(int i=0;i<errors.size()-1;i++)//        {            if(errors[i].first==file)            {                errors[i].second++;                errors.pop_back();                break;//发现相同,修改后直接跳出            }        }    }    stable_sort(errors.begin(),errors.end(),cmp);    int idx=0;    while(idx<8 && idx<errors.size())    {        string filename=errors[idx].first;        int t=filename.find(' ');        if(t>16)        {            errors[idx].first.erase(0,t-16);        }        cout<<errors[idx].first<<" "<<errors[idx].second<<endl;        idx++;    }    system("pause");    return 0;}

STL中pair容器的用法

标准库类型–pair类型定义在utility头文件中定义。
这里写图片描述

1、pair的创建和初始化

pair包含两个数值,与容器一样,pair也是一种模板类型。但是又与之前介绍的容器不同,在创建pair对象时,必须提供两个类型名,两个对应的类型名的类型不必相同。
例如:
pair < string,string >anon;
pair< string,int>word_count;
pair< string, vector< int> >line;

2、pair对象的操作

对于pair类,可以直接访问其数据成员:其成员都是公有的,分别命名为first和second,只需要使用普通的点操作符。

3、生成新的pair对象

除了构造函数,标准库还定义了一个make_pair函数,由传递给它的两个实参生成一个新的pair对象。
例如:
pair < string, string> next_auth;
string first,last;
while(cin>>first>>last) {
next_auth=make_pair(first,last);
//…
}

原创粉丝点击