赞
踩
目录
头文件#include<string>
- string s;
- cin>>s;//输入,遇空格结束
- string c1("wx love my!");//初始化可有空格
- string c2=c1;
- string c3(5,'c');//初始化为5个c即"ccccc"
- string s1[10];//二维数组10行n列
(1)字符运算
string支持+,+=连接字符串,支持=赋值,支持> >= == < <= !=的比较(按照字典序,即对应位置的ASCII码)
- string s;
- cin>>s;
- string c1("wx love my!");//初始化可有空格
-
- s+=c1;
- cout<<s;
(2)基本操作函数
- begin() 得到指向字符串开头的Iterator
- end ()得到指向字符串结尾的Iterator
- size() 得到字符串的大小
- length() 和size函数功能相同
- empty 判断是否为空
- swap()交换两字符串//s1.swap(s2)
- insert(n,s) //插入字符,在下标n之前(n从0开始)插入字符串s,insert()函数不支持传入单个字符,这时的单个字符必须写成字符串形式
- erase() //删除字符
s.erase(13);//从下标13开始往后全删除(包括下标13) s.erase(7,5);//从下标7开始往后删5个
- clear() //删除全部字符
- append 在尾部追加字符//c.append("i'm coming!"),c.append(2,'!'),c.append(str)若添加单个字符只能前面带数字表示添加几个
- push_back 追加字符//只能增加单个字符
- find(str) 查找//s.find()在当前字符串里查找子串str,如果找到返回str在当前字符串里的首字母起始下标数字位置,没有就返回npos(-1)
- find_first_of(str) 查找子串str在字符串里第一次出现的首字母下标
- find_last_of()查找子串str在字符串里最后一次出现的首字母下标
- substr() //返回某个子字符串 substr(n1,n2)从当前字符串n1下标开始取出n2个字符
- substr(k)从当前位置k开始一直到结尾取出子串
string是复杂的模板容器,而字符数组是char型指针,string可以使用[]下标运算符来读取元素或者附给字符数组或者改变已有元素,但是不能通过下标来给string赋值!
- string c1;
- char a[100]="i'm coming!";
- c1=a;//字符数组附给string
- c1[0]='I';//通过下标改变string
- cout<<a<<endl;
- cout<<c1;
- //----------------------------------------------------
- string c1("i'm coming!!");
- cout<<c1<<endl;
- for(int i=0;i<c1.size();i++)//通过下标读取string元素
- cout<<c1[i]<<endl;
- //----------------------------------------------------
- char a[100]="my";
- string c1("i'm coming!!");
- cout<<c1<<endl;
- c1[0]=a[0];//数组与string单个元素改值
- //----------------------------------------------------
- char a[100]="my";
- string c1("i'm coming!!");
- cout<<c1<<endl;
- a[0]=c1[0];//string给字符数组改值;
- cout<<a<<endl;
- //------------string支持迭代器遍历----------------------
- string c1("i'm coming!!");
- string::iterator it=c1.begin();//定义迭代器
- for(;it!=c1.end();it++)
- cout<<*it<<endl;
(1)cin
cin遇空格回车结束,但是cin的回车与空格会留在键盘缓冲区,不过cin读取会跳过所有的空格回车(包括缓冲区里的),读取其后的东西,所以对于cin输入无影响。但是对于getchar或者cin.get() cin.getline getline get都有影响,他们都会读取cin的缓冲区遗留!
(2)cin.get()
cin.get(字符变量名char ch)可以用来接收字符;cin.get(无参数)常用来掠去空格回车。其回车会留在缓冲区,多余字符也会留下。可以通过ch=cin.get()吸收多余字符
(3)cin.getline()
该方法接受一个字符串,可以接收空格并输出,默认遇回车结束。cin.getline(字符串名称,接受字符个数n,结束标志),方法会读取n-1个字符,自动在n的位置加上'\0',因此该输入只能输入字符串数组!而不能输入string!
注意结束方法是 遇到结束符号或者读够n-1个字符,但是如果输入字符多于n-1个,cin会自动设置输入失效自动关闭输入,后面的cin均不能输入就结束!且其回车结束符不留在缓冲区
(4)getline()
getline接受一个字符串,可以接收空格并输出,遇回车结束!cin.getline()类似,但是cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数,getline可用来接受string!getline(cin,str);且getline的回车不留在缓冲区里!
其头文件为#include<sstream>;stringstream是字符串流,经常被我用来作数据切分或者类型转化。编译器拥有足够的信息来判断需要哪些转换。<sstream>库中声明的标准类就利用了这一点,自动选择所必需的转换。而且,转换结果保存在stringstream对象的内部缓冲中。你不必担心缓冲区溢出,因为这些对象会根据需要自动分配存储空间。stringstream可以方便的实现数字与字符串之间的转化。
注意:stringstream流输出时会按照输出的类型自动赋值比如 ss<<"123456\\}"; int m; ss>>m; m=123456!!
(1)例题一
Problem Description
输入的第一行有一个数字 N 代表接下來有 N 行資料,每一行資料里有不固定個數的整數(最多 20 個,每行最大 200 個字元),請你寫一個程式將每行的总和印出來。
Sample Input
3
1 2 3
20 17 23 54 77 60
111 222 333 444 555 666 777 888 999Sample Output
6
251
4995
- #include <iostream>
- #include<string>
- #include<sstream>
- using namespace std;
- int main()
- {
- int N;
- cin>>N;
- cin.get();//读取换行
- while(N--)
- {
- string num;
- getline(cin,num);
- stringstream ss;
- ss<<num;//流读入ss
- int n;
- int sum=0;
- while(ss>>n)//流读出,按照n的类型读出以空格为分隔符
- sum+=n;
- cout<<sum<<endl;//输出
- ss.clear();//清空!!
- }
-
- return 0;
- }
(2)例题二
- #include <iostream>
- #include<string>
- #include<sstream>
- using namespace std;
- int main()
- {
- int n;
- stringstream ss;
- string str;
- while(cin>>n)
- {
- ss<<n;
- }
- ss>>str;
- cout<<str<<endl;
-
- return 0;
- }
输入1 2 45 90 12 输出12459012
- int n;
- stringstream ss;
- string str;
- while(cin>>n)
- {
- ss<<n<<" ";//加入空格
- }
- ss>>str;//ss遇空格为分隔符
- cout<<str<<endl;
输入:1 2 3 51 26 99输出 1;其解决方法(输出空格)
- int n;
- stringstream ss;
- string str;
- while(cin>>n)
- {
- ss<<n<<" ";
- }
-
- cout<<ss.str()<<endl;//ss.str()将ss里保存的流全部输出!
(1)问题描述
Problem Description
给一个数据库,查找是否存在(r1,c1)=(r2,c1) && (r1,c2)=(r2,c2),即:不同的二行,对应二列字符串相同。返回找到的第一个数据。若有输出NO并且下面两行分别输出r1 r2和c1 c2.若无则输出YES。输入以逗号分隔!m<1000,n<10;
Sample Input
3 3 How to compete in ACM ICPC,Peter,peter@neerc.ifmo.ru How to win ACM ICPC,Michael,michael@neerc.ifmo.ru Notes from ACM ICPC champion,Michael,michael@neerc.ifmo.ru 2 3 1,Peter,peter@neerc.ifmo.ru 2,Michael,michael@neerc.ifmo.ruSample Output
NO 2 3 2 3 YES
(2)题解代码
思路是因为不存在二维的字符串容器或者数组,因此要处理字符串,想到可以把字符串标号储存,让最后标号构成二维数组,然后遍历这个二维数组寻找相同即可。
但是注意因为m<1000而n<10所以可以分别遍历列n1,n2每一组遍历一遍行(三重循环即可),每一组中遇到新的组合就保存下来,如果有相同的就可以输出break了,注意每一组清空!因为相同只可能出现在每一组里。且刚开始读入时只能一整串读入,然后每行按照逗号分割字符串,保存map,遇到出现的用同一个编号即可。还要注意pair<int,int>容器的使用(保存一对数据及其对应编号),make_pair()在map的插入使用。
- #include <iostream>
- #include<map>
- #include<string>
- #include<utility>
- #include<algorithm>
- using namespace std;
- int main()
- {
- map<string,int> date;//字符串-编号
- int m,n;
- while(cin>>m>>n)
- {
-
- int num[m][n];//二维数组记录
- date.clear();
- int k=0;//记录编号
- cin.get();//读取回车
- for(int i=0; i<m; i++)
- {
-
- int r=0;//列数
- string s;
- s.clear();
- getline(cin,s);//读入整串
- string str;
- int len=s.length();
- for(int j=0; j<len; j++)
- {
- if(s[j]!=',')
- str.push_back(s[j]);//追加字符
- else
- {
- if(date.count(str)==0)//没出现过
- {
- date.insert(make_pair(str,k));//保存string-k
- num[i][r]=k++;//同时记录入二维数组
-
- }
- else
- num[i][r]=date[str];//出现过就直接记录
- r++;//每一个逗号都表示列数要+1了
- str.clear();
-
- }
- }
- if(date.count(str)==0)//每行最后一个字符串后面没有逗号,单独处理
- {
- date.insert(make_pair(str,k));
- num[i][r]=k++;
- }
- else
- num[i][r]=date[str];
-
- str.clear();
- }
- int flag=0;
- for(int i=0; i<n-1; i++)
- {
- for(int j=i+1; j<n; j++)//枚举两列
- {
- map<pair<int,int>,int> mmp;记录这行两列俩字符串编号pair-行数
- for(int a=0; a<m; a++)
- {
- if(mmp.count(make_pair(num[a][i],num[a][j]))==0)//没出现过
- mmp.insert( make_pair(make_pair(num[a][i],num[a][j]),a));//插入
- else//出现过了
- {
- cout<<"NO\n"<<mmp[make_pair(num[a][i],num[a][j])]+1<<" "<<a+1<<"\n"<<i+1<<" "<<j+1<<endl;//输出
- flag=1;
- break;
- }
- }
- mmp.clear();
- if(flag==1)
- break;
-
- }
- if(flag==1)
- break;
- }
- if(flag==0)
- cout<<"YES"<<endl;
- }
- return 0;
- }
(1)问题描述
Problem Description
本题的任务为模拟发送邮件时MTA(邮件传输代理)之间的交互。所谓MTA,就是email地址格式user@mtaname的“后面部分”。当某人从user1@mta1发送给另一个人user2@mta2时,这两个MTA将会通信。如果两个收件人属于同一个MTA,发送者的MTA只需与这个MTA通信一次就可以把邮件发送给这两个人。注意排除重复和判断这个用户在输入MTA下是否存在!
(2)题解代码
大意就是给你一些MTA,每一个MTA有限定的使用用户名称,然后输入发件人和收件人,以及发件内容,按照格式输出,同时判断收件人use1@MTA1中use1是否是在MTA1允许的用户里,否则就是不存在,若用户均不存在不就不发送内容。
在解题时首先是注意对输入的处理:即先用set将输入拼成邮箱地址直接保存,查找有无时直接set.count即可,不用map了,map还要对比字符串效率低。然后输入邮件信息,由于题目要求按照先后MTA顺序输出,这里就用到了队列那一题的思路:先用vector来保存MTA顺序,每个MTA名称在map里对应一个容器vector<string>来保存输入的对应邮件,每一个输入判断对应MTA是否存在,若存在则直接存入对应map即可,若不存在则新建并且push_back vector,并先用set来去除重复名字。最后是输出即对于多行文本的保存以及输出格式处理。
注意:知道map可以通过vector来映射多个数map<string,vector<string> >可以用字符串来映射一个容器;注意输入处理特别是文本分行的输入;注意map,vector,set,string综合运用。
- #include <iostream>
- #include<set>
- #include<string>
- #include<vector>
- #include<map>
- #include<algorithm>//1.输入处理特别是文本分行的输入2.map,vector,set综合运用
- using namespace std;
- void deverse_address(string &s,string &mta)//处理函数,分离MTA与名字,后面输出以及储存要用
- {
- int k=s.find('@');
- mta=s.substr(k+1);
- }
- int main()
- {
- string s,user1,MTA,user2,MTA2;
- int num;
- set<string> addr;
- while(cin>>s&&s!="*")//MTA限定保存
- {
- cin>>MTA>>num;
- while(num--)
- {
- cin>>user1;
- user1=user1+"@"+MTA;//string链接
- addr.insert(user1);//保存
- }
- }
- while(cin>>s&&s!="*")//输入邮件信息
- {
- deverse_address(s,MTA2);//发件人
- map<string,vector<string> >dest;//保存MTA对应所有邮件地址容器
- set<string> vis;//去重复
- vector<string> mta;//排序MTA
- string t,name;
- while(cin>>t&&t!="*")//输入收件人
- {
-
- if(vis.count(t))//去重
- continue;
- vis.insert(t);
- deverse_address(t,name);
- if(!dest.count(name))//不存在此MTA
- {
- mta.push_back(name);//插入
- }
- dest[name].push_back(t);存入对应map
- }
- cin.get();//吃回车
- string date;
- while(getline(cin,t)&&t!="*")//输入文本内容防止回车结束所以用while循环累加!!!
- date=date+" "+t+"\n";//文本处理自带五空格和换行!!!到时候直接输出即可
- for(int i=0;i<mta.size();i++)//按MTA顺序输出
- {
- bool flag=false;
- // vector<string> uses=dest[mta[i]];
- cout<<"Connection between "<<MTA2<<" and "<<mta[i]<<endl;
- cout<<" HELO "<<MTA2<<"\n"<<" 250"<<endl;
- cout<<" MAIL FROM:"<<"<"<<s<<">\n"<<" 250\n";
- for(int j=0;j<dest[mta[i]].size();j++)//每个MTA下输出用户
- {
- cout<<" RCPT TO:<"<<dest[mta[i]][j]<<">\n";//dest[mta[i]][j]
- if(addr.count(dest[mta[i]][j]))//判断用户是否存在!
- {cout<<" 250\n";flag=true;}
- else
- cout<<" 550\n";
- }
- if(flag==true)//至少存在一个才输出文本date
- {
- cout<<" DATA\n"<<" 354\n"<<date;
- cout<<" ."<<endl;
- cout<<" 250"<<endl;
- }
- cout<<" QUIT\n"<<" 221"<<endl;
- }
- }
- return 0;
- }
(1)问题描述
Problem Description
输入若干行代码,要求各列单词的左边界对齐且尽量靠左(每列中与最长的单词长度相同)。单词之间至少要空一格。每个单词不超过80个字符,每行不超过180个字符,一共最多1000行。
Sample Input
start: integer; // begins here stop: integer; // ends here s: string; c: char; // tempSample Output
start: integer; // begins here stop: integer; // ends here s: string; c: char; // temp
(2)题解代码
是一道字符串处理题。思路是因为要与每一列里最长的字符串对齐,因此必须要把每一列里最长的长度都保存下来;除此之外,文本按照行输入,按照行保存每一行的单词,再次用到stringstream;以前妄想便用流输出每个单词边输出格式,结果很乱。不如全部保存下来以后,再一起输出即可!
- #include <iostream>
- #include<vector>
- #include<string>
- #include<sstream>
- using namespace std;
- int main()
- {
- vector<string> all[1002];//保存每一行的所有单词,实现字符串二维
- int num[200]={0};//保存每一列的最大长度,初始化为零!不用vector的原因是vector入元素只能push_back后缀
- int row=0,col=0;
- string s;
- stringstream ss;
- while(getline(cin,s))//一整行输入
- {
- ss.clear();
- ss<<s;
- string t;
- while(ss>>t)//流输出
- {
- all[row].push_back(t);//添加单词
- num[col]=max(num[col],(int)t.size());//每一列的最大长度
- col++;//列更新
- }
- row++;//更新
- col=0;
- }
- for(int i=0; i<row; i++)//输出
- {
- for(int j=0; j<all[i].size()-1; j++)
- {
- cout<<all[i][j];
- for(int k=0; k<=num[j]-all[i][j].size(); k++)//输出空格,与最大长度对应!
- cout<<" ";
- }
- cout<<all[i][all[i].size()-1]<<endl;//最后一个单词后无空格单独输出
- }
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。