编码:
ASCII
unicode–utf-8
utf-16----一个字符2个字符
utf-32----一个字符4个字节
gbk–中文编码表
string:
是一个特殊的容器,对数据(字符数组)和库函数(strlen等)进行封装
STL提供的内容都在标准命名空间下
构造方式
输出方式
下标[ ],迭代器,范围for
常用函数
reverse | reverse(s.begin(), s.end())逆置 |
---|---|
size,length | 返回字符串的有效个数 |
resize | 改变有效元素个数 |
capacity | 容量 |
reserve | 扩容 |
clear | 清空 |
empty | 判空 |
string里的容量使用:
string s(“hello”);
cout <<s.size()<<endl;
cout<<s.capacity()<<endl;
if(s.empty())
cout<<”空”<<endl
else
cout<<不空<<endl;
s.clear();
resize:调整有效元素个数
增多:s.resize(10,’!’); //将有效元素个数扩容到十个,多出的空间用!填充;如果底层空间不够则有特定的扩容方式
减少:s.resize(5); //减少时,容量空间不会改变,只减少有效元素个数
reserve:扩容
当参数大于底层空间确实会扩容
减少容量时,有一个数值标准(15),小于某个值才会真正减少
s.reserve(20) ; //直接扩容到20(开辟新空间,拷贝元素,释放旧空间),
顺序表由一个char指针两个size_t构成12个字节
String类型对象的大小为28,比顺序表多了16个字节,所以内部除了有一个char指针两个size_t之外还有一段固定长度char类型的数组,应用于普通调用,不然每调用一次都要申请空间,效率变低
string里的元素访问:
operator[ ]:有普通类型对象,有const类型对象;越界用assert断言
const char& operator[ ] (size_t pos)const
char& operator[ ] (size_t pos)
cout<< s.[100] <<endl;
at:和[ ]一样,都是给一个位置,获取该处字符;越界抛异常
const char& at (size_t pos)const
char& at (size_t pos)
cout<< at(100) <<endl;
两个函数参数都一样,都是给一个位置获取该位置的字符;
两个函数对越界的处理方法不同,一个是异常,一个是抛异常;一般用第一种
元素的修改
1.追加:使用+=;+=追加的是字符,字符串,对像;push_back只追加字符
s+=”hello”
string s1(“hello”)
s+=s1;
使用append函数要有接收变量
s=s.append(3, ‘!’); //追加3个 !
s=s.append(s1, 1, 3); //从s1的1号位置开始追加3个字符
2.插入:
s=s.insert(0, ”word); //在0号位置插word
s=s.insert( 4, 3, ‘ ’); //在4的位置插3个空字符
3.任意位置删除:
s.erase(0, 5); //在0号位置开始删除五个元素
s.erase(s.begin()) //通过迭代器删除,这样写只删了begin处的元素
s.erase(s.begin(), s.end()) //删除这个区间的元素
把字符串中的内容转化成整型数字
string s(“12345”);
int val=atoi ( s.c_str( ) ) //atoi是c语言提供的函数,参数是char* 类,不能直接给s对象;需要将对象转化成c语言的方式,把空间首地址给atoi
cout<<val<<endl;
c_str
字符串截取:substr,截取都是从当前位置截,并生成一个子串,要注意±1
第一个参数是截取位置(默认从第0个开始)
第二个参数是截取长度(默认截取为n)
string s(“string.cpp”);
string post=s.substr(s.find(‘.’)+1 ); //从 . 位置开始截取,
如果不给参数,默认参数是npos,截到末位,
npos是string内部的静态成员变量
截取文件名
string s (“F:\work\string.cpp”);
string name = s.substr ( s.rfind(‘\’) +1);
cout<< name <<endl;
size_t pos1 = s.rfind(‘\’)+1;
size_t pos2 = s.rfind(‘.’);
string post=s.substr (post1, post2) //截两位置之间的
s.substr (post1, n); //从post1位置开始截取,截取长度n
find也有两个参数,第一个参数是截什么样的字符,第二个是从哪个位置截返回值为字符参数的标号
string的扩容机制效率太低,所以先扩容再放数据
6-19 string
string s;
cin >> s; 适用于一行只有一个字符串的接收
cout<< s <<endl; 输入hello word,只接收了hello
getline函数不能处理string类对象
getline(cin, s); //第一个参数是标准输入流对象,放到第二个参数s中
string s;
getline(cin, s);
cout<< s <<endl;
循环输入:
1.一行是单个字符串的输入
string s;
while(cin>>s)
{ }
2.一行有多个字符串,字符串之间用空格隔开
string s;
while(getline(cin, s))
{ }
例:计算一行字符串中,最后一个单词的长度
#include
int main()
{
string s;
while(getlin(cin, s)) //循环输入
{
cout<<s.substr( s.rfind(‘ ’)+1).size( )<<endl;
}
return0
}
string类型对象可以直接比大小
例1.将字符串中是字母的元素进行翻转
int left=0, right=s.size( )-1;
while(left<right)
{
while( left<right && isalpha( s[left] ) //先分别找左右两个不是字母的元素标号
{
left++;
}
while( left<right && isalpha( s[right] )
{
right–;
}
if(left!=right)
{
swap(arr[left], arr[right]);
left++;
right–;
}
}
Isalpha:int isalpha(int c)
检测参数c是否是英文字母,是字符返回true,不是返回NULL
例2.找字符串第一个不重复的字符,并返回元素下标。若不存在返回-1
Leetcode,返回0
先统计每个字符出现的次数
回文数组:
bool ischar (char ch ) //判断有效字符
{
if( ( ch>=0 && ch<=9 ) || ( ch>=’A’ && ch<=’Z’ ) || ( ch>=’a’ && ch<=’z’ ) )
return turn;
return false;
}
bool isPalindrome (string s)
{
for(auto& e : s )
{
if(e>=’a’ && e<=’z’) //将字符串中大写字母转化成小写
e+=32;
}
int left=0, right=s.size()-1;
while(left<right)
{
//左指针<右值指针,且左元素不是有效字符,则指针向右走一步再判断
while(left<right && ! ischar(s[left]) )
left++;
while(left<right && ! ischar(s[right]) )
right–;
if(s[left] != s[right]) //左右两字符相等则继续找,不等直接返回
return fale;
else
{
left++;
right–;
}
}
return true;
}
用字符串模拟数字相加
int lsize=num1.size(); //lsize是num1数组的元素个数
int rsize=num2.size();
if(lsize<rsize)
{
num1.swap(num2);
swap(lsize, rsize);
}
string result(lsize+1, ‘0’);
char step=0;
for(int lid=lsize-1, int rid=rsize-1; lid>=0; lid–,rid–)
{
if(rid>0)
char sum=num1[lid]-‘0’; //num1[lid]是数组num1中的字符,要进行运算就要减一个字符0
if(rid>=0)
{
sum+=num2[rid]-‘0’;
}
sum+=step;
step=0;
if(sum>9) //sum超过9就要进位
{
step=1;
sum-=10; //此时sum的值就是当前两个最低位
}
result[lid+1]=sum+’0’; //lid是原数组的长度,新数组比原数组多一个进位,所以+1
}
if(step==1) //循环完后,有进位则将1保存到首位,没有则删除首位
result[0]=’1’;
else
result. earse(result.begin( ) )
return result;