华为机试练习(四)
一、括号匹配
1、
#include<iostream> #include<string> #include<cmath> #include<vector> using namespace std; void DeletBract(string str) { if(str.length()%2!=0) cout<<"No"<<endl; else { for(int i=0;i<str.length()-1;i++) { if(str[i]=='(') { for(int j=i+1;j<str.length();j++) { if(str[j]==')') { str[i]='a'; str[j]='a'; break; } } } } int l=0,r=0; for(int i=0;i<str.length();i++) { if(str[i]==')') { l++; } else if(str[i]=='(') { r++; } } if(l==1) cout<<"Yes"<<endl; else if(l==0&&r==0) cout<<"Yes"<<endl; else cout<<"No"<<endl; } } int main() { vector<string> vec; int n; cin>>n; fflush(stdin); for(int i=0;i<n;i++) { string str; getline(cin,str); vec.push_back(str); } for(int i=0;i<n;i++) { DeletBract(vec[i]); } return 0; }
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; char str[maxn]; stack<char> s; int main() { int t; cin >> t; while(t--) { while(!s.empty()) s.pop(); scanf("%s", str); int n = strlen(str); if(n == 2) { if(str[0] == '(' && str[1] == ')') { puts("No"); continue; } } int i; int flag1 = 0; for(i = 0; i < n; i++) { if(str[i] == '(') { s.push('('); } else { if(!s.empty()) s.pop(); else { if(flag1) break; flag1 = 1; s.push('('); } } } if(i == n) { if(!flag1) { if(s.empty()) puts("Yes"); else puts("No"); } else { if(s.size() != 2) puts("No"); else puts("Yes"); } } else puts("No"); } return 0; }
2、字符串多输入的解决
#include<iostream> #include<string> #include<cmath> #include<vector> using namespace std; int main() { vector<string> vec; int n; string str; cin>>n; for(int i=0;i<n;i++) { cout<<i<<endl; getline(cin,str); vec.push_back(str); } for(int i=0;i<vec.size();i++) { cout<<vec[i]<<endl; } return 0; }
出现问题,少输入一个字符串。
#include<iostream> #include<string> #include<cmath> #include<vector> using namespace std; int main() { vector<string> vec; //int n; string str; //cin>>n; for(int i=0;i<2;i++) { cout<<i<<endl; getline(cin,str); vec.push_back(str); } for(int i=0;i<vec.size();i++) { cout<<vec[i]<<endl; } return 0; }
不用n输入值时,可以正常输入,原因可能是之前的cin>>n,会对getline()产生影响。所以出错。
#include<iostream> #include<vector> #include<string> using namespace std; int main() { int NUM; cout<<"input vetcor size NUM="; cin>>NUM ; //getchar(); fflush(stdin); //输入NUM以后缓冲区中有个一个换行,而getline函数不忽略换行,如果不清空,第一个string的内容始终都是换行符 vector<string> str_arr(NUM); for(int i=0;i<NUM;i++) { cout<<"enter the "<<i+1<<" string:"; getline(cin,str_arr[i]); } for(int i=0;i<NUM;i++) cout<<str_arr[i]<<endl; cout<<endl; return 0; }
利用 fflush(stdin);清空缓冲区,getline()才可以正常使用。
3、
#include <iostream> #include <string> #include <vector> #include <algorithm> using namespace std; int main() { string str; int n; cin>>n; vector<string> vec; for (int i=0;i!=n;i++) { cin>>str; vec.push_back(str); } for (int j=0;j!=n;j++) { reverse(vec[j].begin(),vec[j].end()); //vec[i]在string中是该字符串的对象,也是首地址 } for (int j=0;j!=n;j++) { cout<<vec[j]<<endl; cout<<vec[j][0]<<endl; //相当于str[i] 数组的某一个元素 } return 0; }
利用cin可以多次输入。利用vector容器可以形成二维数组。
3、
#include<iostream> #include<string> #include<cmath> #include<vector> using namespace std; void DeletBract(string str) { if(str.length()%2!=0) cout<<"No"<<endl; else { for(int i=0;i<str.length()-1;i++) { if(str[i]=='(') { for(int j=i+1;j<str.length();j++) { if(str[j]==')') { str[i]='a'; str[j]='a'; break; } } } } int l=0,r=0; for(int i=0;i<str.length();i++) { if(str[i]==')') { l++; } else if(str[i]=='(') { r++; } } if(l==1||l==0) cout<<"Yes"<<endl; else cout<<"No"<<endl; } } int main() { vector<string> vec; int n; cin>>n; fflush(stdin); for(int i=0;i<n;i++) { string str; getline(cin,str); vec.push_back(str); } for(int i=0;i<n;i++) { DeletBract(vec[i]); } return 0; }
二、stack应用
1、
#include <stack> #include <iostream> using namespace std; int main() { // 创建堆栈对象 stack<int> s; // 元素入栈 s.push(3); s.push(19); s.push(23); s.push(36); s.push(50); s.push(4); cout<<"stack size is:"<<s.size()<<endl; // 元素依次出栈 while(!s.empty()) { // 打印栈顶元素,打印出:4 50 36 23 19 3 cout << s.top() << endl; // 出栈 s.pop(); } return 0; }
三、
输入描述:
输入第一行为一个正整数n(1≤n≤1000),下面n行为n个字符串(字符串长度≤100),字符串中只含有大小写字母。
输出描述:
数据输出n行,输出结果为按照字典序排列的字符串。
1、
#include<iostream> #include<vector> #include<string> #include<algorithm> using namespace std; int main() { int n; cin>>n; vector<string> vec; while(n) { string str; cin>>str; vec.push_back(str); n--; } sort(vec.begin(),vec.end()); vector<string>::iterator it; for(it=vec.begin();it!=vec.end();it++) { cout<<*it<<endl; } return 0; }
利用 vector 和algorithm来做。
2、sort 函数
#include <iostream> #include <algorithm> using namespace std; int main() { int a[20]={2,2,1,23,5,76,0,43,24,65},i; for(i=0;i<10;i++) cout<<a[i]<<" "; cout<<endl; sort(a,a+10); for(i=0;i<10;i++) cout<<a[i]<<" "; return 0; }
3、
#include<iostream> #include<set> #include<string> #include<algorithm> using namespace std; int main() { int n; cin>>n; set<string> vec; while(n) { string str; cin>>str; vec.insert(str); n--; } //sort(vec.begin(),vec.end()); set<string>::iterator it; for(it=vec.begin();it!=vec.end();it++) { cout<<*it<<endl; } return 0; }
四、
输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数。
输入描述:
输入一个整数(int类型)
输出描述:
这个数转换成2进制后,输出1的个数
1、
#include<iostream> using namespace std; int main() { int t; cin>>t; int count=0; while(t>0) { if(t%2)count++; t=t/2; } cout<<count<<endl; }
2、位运算
#include<iostream> using namespace std; int main() { int a; while(cin>>a) { int count=0; while(a) { if((a&1)>0)//和1位运算,都是1,取1 count++;//判断二进制有多少个1 a=a>>1;//右移1位,相当于除以2; cout<<a<<endl; } cout<<count<<endl; } return 0; }
四、
题目描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10; A1A; $%$; YAD; 等。
输入
A10;S20;W10;D30;X;A1A;B10A11;;A10;
输出
10,-10
1、
容易搞混的两个函数,给出所有重载函数:
int find(char c, int pos = 0) const;//从pos开始查找字符c在当前字符串的位置
int find(const char *s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
int find(const char *s, int pos, int n) const;//从pos开始查找字符串s中前n个字符在当前串中的位置
int find(const string &s, int pos = 0) const;//从pos开始查找字符串s在当前串中的位置
int find_first_of(char c, int pos = 0) const;//从pos开始查找字符c第一次出现的位置
int find_first_of(const char *s, int pos = 0) const; //从pos开始查找当前串中第一个在s的前n个字符组成的数组里的字符的位置
int find_first_of(const char *s, int pos, int n) const;
int find_first_of(const string &s,int pos = 0) const;
共同点:
查找成功时返回所在位置,失败返回string::npos的值,string::npos一般是MAX_INT(即2^32 - 1)
差异:
find(): 查找字符串中第一次出现字符c、字符串s的位置;
find_first_of(): 查找字符串中字符c、字符数组s中任意一个字符第一次出现的位置。
#include<iostream> using namespace std; int main() { string haystack = "helloworld"; string needle = "world"; cout << haystack.find_first_of(needle) << endl; //2, index of first 'l' ,needle任意一个字符第一次出现的位置 cout << haystack.find(needle) << endl; //5, index of first "world" ,world 第一次出现的位置 needle = ""; cout << haystack.find_first_of(needle) << endl;//string::npos, 因为字符数组s为空,haystack中找不到空字符(区别于'\0') cout << haystack.find(needle) << endl;//0, 空串 }
2、
#include<iostream> #include<string> using namespace std; int main() { string str; while(getline(cin,str)) { pair<int,int> point(0,0);//不需要等于号 ,记录坐标 int index,start=0;//找到;的位置 string s; index=str.find_first_of(";"); while(index!=string::npos) { s=str.substr(start,index-start);//注意是差值,是个数而非下标 cout<<s<<endl; start=index+1; index=str.find_first_of(";",index+1); } //A10;S20;W10;D30;X;A1A;B10A11;;A10; } }
利用 string.find_first_of()查找;的下标,利用substr获取字符串。
3、
#include<iostream> #include<string> using namespace std; int main() { string str; while(getline(cin,str)) { pair<int,int> point(0,0);//不需要等于号 ,记录坐标 int index=str.find_first_of(";"); int start=0;//找到;的位置 while(index!=string::npos) { string s=str.substr(start,index-start);//注意是差值,是个数而非下标 start=index+1; index=str.find_first_of(";",index+1); if(s.size()>1&&s.size()<=3)//只能有2或者3个字符 { int num=0,flag=0; for(int i=1;i<s.size();i++)//注意是s.size { if(s[i]>='0'&&s[i]<='9') { num=num*10+(s[i]-'0'); } else { flag=1; break; } } if(flag==0) { switch(s[0]) { case 'A': { point.first=point.first-num; break; } case 'D': { point.first=point.first+num; break; } case 'W': { point.second=point.second+num; break; } case 'S': { point.second=point.second-num; break; } } } } } cout<<point.first<<","<<point.second<<endl; } return 0; }//A10;S20;W10;D30;X;A1A;B10A11;;A10;
4、switch 理论上不加break没影响,但是
#include<iostream> #include<string> using namespace std; int main() { string str; while(getline(cin,str)) { pair<int,int> point(0,0);//不需要等于号 ,记录坐标 int index=str.find_first_of(";"); int start=0;//找到;的位置 while(index!=string::npos) { string s=str.substr(start,index-start);//注意是差值,是个数而非下标 start=index+1; index=str.find_first_of(";",index+1); if(s.size()>1&&s.size()<=3)//只能有2或者3个字符 { int num=0,flag=0; for(int i=1;i<s.size();i++)//注意是s.size { if(s[i]>='0'&&s[i]<='9') { num=num*10+(s[i]-'0'); } else { flag=1; break; } } if(flag==0) { switch(s[0]) { case 'A': { point.first=point.first-num; //break; } case 'D': { point.first=point.first+num; //break; } case 'W': { point.second=point.second+num; //break; } case 'S': { point.second=point.second-num; //break; } } } } } cout<<point.first<<","<<point.second<<endl; } return 0; }//A10;S20;W10;D30;X;A1A;B10A11;;A10;
却出错。
通过调试,发现case A 和case W 会相互影响。
所以以后碰到case记住加break。或者直接用if判断。
5、
#include<iostream> #include<string> using namespace std; int main() { string str; while(getline(cin,str)) { pair<int,int> point(0,0);//不需要等于号 ,记录坐标 int index=str.find_first_of(";"); int start=0;//找到;的位置 while(index!=string::npos) { string s=str.substr(start,index-start);//注意是差值,是个数而非下标 start=index+1; index=str.find_first_of(";",index+1); if(s.size()>1&&s.size()<=3)//只能有2或者3个字符 { int num=0,flag=0; for(int i=1;i<s.size();i++)//注意是s.size { if(s[i]>='0'&&s[i]<='9') { num=num*10+(s[i]-'0'); } else { flag=1; break; } } if(flag==0) { if(s[0]=='A') { point.first=point.first-num; //break; } else if(s[0]=='D') { point.first=point.first+num; //break; } else if(s[0]=='W') { point.second=point.second+num; //break; } else if(s[0]=='S') { point.second=point.second-num; //break; } } } } cout<<point.first<<","<<point.second<<endl; } return 0; }//A10;S20;W10;D30;X;A1A;B10A11;;A10; A10;D20;W10;S20;
6、用结构体struct 表示
#include<iostream> #include<string> using namespace std; struct Point //定义结构体 { int x; int y; } ; int main() { string str; while(getline(cin,str)) { Point p[1];//不需要等于号 ,记录坐标 p[0].x=0; p[0].y=0; int index=str.find_first_of(";"); int start=0;//找到;的位置 while(index!=string::npos) { string s=str.substr(start,index-start);//注意是差值,是个数而非下标 start=index+1; index=str.find_first_of(";",index+1); if(s.size()>1&&s.size()<=3)//只能有2或者3个字符 { int num=0,flag=0; for(int i=1;i<s.size();i++)//注意是s.size { if(s[i]>='0'&&s[i]<='9') { num=num*10+(s[i]-'0'); } else { flag=1; break; } } if(flag==0) { if(s[0]=='A') { p[0].x-=num; //break; } else if(s[0]=='D') { p[0].x+=num; //break; } else if(s[0]=='W') { p[0].y+=num; //break; } else if(s[0]=='S') { p[0].y-=num; //break; } } } } cout<<p[0].x<<","<<p[0].y<<endl; } return 0; }//A10;S20;W10;D30;X;A1A;B10A11;;A10; A10;D20;W10;S20;
五、
他是这么变换的,大家都知道手机上的字母: 1--1, abc--2, def--3, ghi--4, jkl--5, mno--6, pqrs--7, tuv--8 wxyz--9, 0--0,就这么简单,渊子把密码中出现的小写字母都变成对应的数字,数字和其他的符号都不做变换,
声明:密码中没有空格,而密码中出现的大写字母则变成小写之后往后移一位,如:X,先变成小写,再往后移一位,不就是y了嘛,简单吧。记住,z往后移是a哦。
输入描述:
输入包括多个测试数据。输入是一个明文,密码长度不超过100个字符,输入直到文件结尾
输出描述:
输出渊子真正的密文
输入
YUANzhi1987
输出
zvbo9441987
1、
#include<iostream> #include<string> using namespace std; const string dict1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const string dict2="bcdefghijklmnopqrstuvwxyza22233344455566677778889999"; char Char_Change(char a){ for(int i=0;i<dict1.size();i++) if(dict1[i]==a) return dict2[i]; return a; } int main(){ //string data="YUANzhi1987"; string data; while(getline(cin,data)){ for(int i=0;i<data.size();i++) data[i] = Char_Change(data[i]); cout<<data<<endl; } return 0; }
牛客网上的程序,将对应输出先用静态变量表示出来,。注意这里定义函数的返回,多个return时,返回最先满足条件的。
2、
#include<iostream> #include<string> using namespace std; const string str_1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const string str_2="bcdefghijklmnopqrstuvwxyza22233344455566677778889999"; char Char_change(char a) { int flag=0; for(int i=0;i<str_1.size();i++) { if(str_1[i]==a) { return str_2[i]; flag=1; } } if(flag==0)//注意,最好别用判断输出,牛客网通不过 { return a; } } int main() { string str; while(getline(cin,str)) { for(int i=0;i<str.size();i++) { cout<<Char_change(str[i]); } } return 0; }
3、以上程序通过循环获取对应位置,也可以通过find函数
#include<iostream> #include<string> using namespace std; const string str_1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const string str_2="bcdefghijklmnopqrstuvwxyza22233344455566677778889999"; char Char_change(char a) { int index; index=str_1.find(a); if(index>=0) return str_2[index]; return a; } int main() { string str; while(getline(cin,str)) { for(int i=0;i<str.size();i++) { cout<<Char_change(str[i]); } } return 0; }//YUANzhi1987
4、
#include<iostream> #include<string> using namespace std; const string str_1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; const string str_2="bcdefghijklmnopqrstuvwxyza22233344455566677778889999"; char Char_change(char a) { int index; index=str_1.find(a); if(index>=0) return str_2[index]; else { return a; } } int main() { string str; while(getline(cin,str)) { for(int i=0;i<str.size();i++) { cout<<Char_change(str[i]); } } return 0; }//YUANzhi1987
这次的判断返回,可以通过牛客网测试
六、
密码要求:
1.长度超过8位 2.包括大小写字母.数字.其它符号,以上四种至少三种 3.不能有相同长度超2的子串重复
说明:长度超过2的子串
输入描述:
一组或多组长度超过2的子符串。每组占一行
输出描述:
如果符合要求输出:OK,否则输出NG
输入
021Abc9000 021Abc9Abc1 021ABC9000 021$bc9000
输出
OK NG NG OK
1、
#include <iostream> #include <string> using namespace std; int main() { string str; while(cin >> str) { int flag[4] = {0}; if(str.size() <= 8) goto NG; for(int i = 0; i < str.size(); ++i)//四种情况统计 if(str[i] >= 'a' && str[i] <= 'z') flag[0] = 1; else if(str[i] >= 'A' && str[i] <= 'Z') flag[1] = 1; else if(str[i] >= '0' && str[i] <= '9') flag[2] = 1; else flag[3] = 1; if(flag[0] + flag[1] + flag[2] + flag[3] < 3) goto NG; for(int i = 0; i <= str.size()-6; i++)//长度超过二的统计 for(int j = i+3;j < str.size();j++) if(str[i] == str[j] && str[i+1] == str[j+1] &&str[i+2] == str[j+2]) goto NG; OK: cout << "OK" << endl;continue; NG: cout << "NG" << endl; } return 0; }
学习goto的应用。再有注意他们判断的逻辑。
2、判断大于2个重复的字符串
#include<iostream> #include<string> using namespace std; int main() { string str="021Abc9Abc000"; for(int i=0;i<str.size()-6;i++)//判断大于2个重复子串,只要有大于等于3的子串就可以 { for(int j=i+3;j<str.size();j++) { if(str[i]==str[j]&&str[i+1]==str[j+1]&&str[i+2]==str[j+2]) { cout<<"有长度大于2的重复子串"; break; } } } return 0; }
3、
#include<iostream> #include<string> using namespace std; int main() { string str; while(getline(cin,str)) { int flag=0;//标记 int s=0; if(str.size()>8) { for(int i=0;i<str.size()-6;i++)//判断大于2个重复子串,只要有大于等于3的子串就可以 { for(int j=i+3;j<str.size();j++) { if(str[i]==str[j]&&str[i+1]==str[j+1]&&str[i+2]==str[j+2])//说明有大于2的字符串 { flag=1; break; } } } for(int i=0;i<str.size();i++) //四种符号判断 { if(str[i]>='a'&&str[i]<='z') { s++; } else if(str[i]>='A'&&str[i]<='Z') { s++; } else if(str[i]>='1'&&str[i]<='9') { s++; } else { s++; } } if(s<3) { flag=1; } } if(flag==0) { cout<<"OK"<<endl; } else if(flag==1) { cout<<"NG"<<endl; } } return 0; }
这是利用flag形式最终判断的程序,比较繁琐,并且多了很多无用的判断。利用goto,只要一不符合条件就可以跳出判断到最后。
七、
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
1、 记录最多8条错误记录,循环记录,对相同的错误记录(净文件名称和行号完全匹配)只记录一条,错误计数增加;
2、 超过16个字符的文件名称,只记录文件的最后有效16个字符;
3、 输入的文件可能带路径,记录文件名称不能带路径。
输入描述:
一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:
输入
E:\V1R2\product\fpgadrive.c 1325
输出
fpgadrive.c 1325 1
1、
#include <iostream> #include <string> #include<cstring> #include<algorithm> using namespace std; int main() { string str="E:/V1R2\product\fpgadrive.c"; cout<<str.length()<<endl; for(int i=0;i<str.length();i++) cout<<str[i]<<" "; cout<<endl; int pos = str.rfind('e'); cout<<pos<<endl; }
可以看出识别不了直接写入的字符创中的反斜杠
#include <iostream> #include <string> #include<cstring> #include<algorithm> using namespace std; int main() { string str,s; cin>>str; cout<<str.length()<<endl; for(int i=0;i<str.length();i++) cout<<str[i]<<" "; cout<<endl; int pos = str.rfind('\\'); //注意双斜杠识别反斜杠 cout<<pos<<endl; s=str.substr(pos+1); cout<<s<<endl; }//="E:/V1R2\product\fpgadrive.c"
但是这样输入的字符串可以识别,可以找出最后的文件名。rfind,逆序查找某一字符第一次出现的位置。
2、
#include<iostream> #include<vector> #include<string> using namespace std; struct Eorr //定义结构体 { string path; int col; int num=1; }; int main() { vector<Eorr> vec; //vector容器 Eorr infor; for(int i=0;i<3;i++) { cin>>infor.path>>infor.col; vec.push_back(infor); //容器添加内容 } cout<<vec.size()<<endl; int index; for(int i=0;i<vec.size();i++) { if(vec[i].col==641) cout<<i<<endl; } } //G:\rp\onajqj\maahmq 631 E:\njfgjkcrh 641 C:\co\zk\ao\bxgxjfgrwckfxekeqro 629
利用结构体和vector可以比较,定位位置
641在下标为1的位置。
3、
#include<iostream> #include<vector> #include<string> using namespace std; const int NUM=1; struct Eorr //定义结构体 { string path; int col; int num; }; string Getfilename(string s)//得到文件名字 { string name; int n; n=s.rfind('\\');//逆序查找反斜杠 name=s.substr(n+1); if(name.size()>4) name=name.substr(name.size()-4); return name; } int main() { vector<Eorr> vec; //vector容器 string filepath; int Col; int Num=1; cin>>filepath; cin>>Col; Eorr infor; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; vec.push_back(infor); for(int j=0;j<3;j++) { int flag=0; cin>>filepath; cin>>Col; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; for(int i=0;i<vec.size();i++) { if(vec[i].path==infor.path&&vec[i].col==infor.col) { vec[i].num++; //容器添加内容 flag=1; break; } } if(flag==0) { vec.push_back(infor); } flag=0; } for(int i=0;i<vec.size();i++) { cout<<vec[i].path<<" "<<vec[i].col<<" "<<vec[i].num<<endl; } return 0; } //G:\rp\onajqj\maahmq 631 E:\njfgjkcrh 641 C:\co\zk\ao\bxgxjfgrwckfxekeqro 629 G:\rp\onajqj\maahmq 631
用四个测试;通过循环读取比测判断个数的。
4、
#include<iostream> #include<vector> #include<string> using namespace std; const int NUM=1; struct Eorr //定义结构体 { string path; int col; int num; }; string Getfilename(string s)//得到文件名字 { string name; int n; n=s.rfind('\\');//逆序查找反斜杠 name=s.substr(n+1); if(name.size()>4) name=name.substr(name.size()-4); return name; } int main() { vector<Eorr> vec; //vector容器 string filepath; int Col; int Num=1; cin>>filepath; cin>>Col; Eorr infor; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; vec.push_back(infor); while(cin>>filepath>>Col) { int flag=0; //cin>>filepath; //cin>>Col; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; for(int i=0;i<vec.size();i++) { if(vec[i].path==infor.path&&vec[i].col==infor.col) { vec[i].num++; //容器添加内容 flag=1; break; } } if(flag==0) { vec.push_back(infor); } flag=0; } for(int i=0;i<vec.size();i++) { cout<<vec[i].path<<" "<<vec[i].col<<" "<<vec[i].num<<endl; } return 0; } //G:\rp\onajqj\maahmq 631 E:\njfgjkcrh 641 C:\co\zk\ao\bxgxjfgrwckfxekeqro 629 G:\rp\onajqj\maahmq 631
while 循环输入,输出的结果,只需要将最后八个输出即可;
5、
最终程序
#include<iostream> #include<vector> #include<string> using namespace std; const int NUM=1; struct Eorr //定义结构体 { string path; int col; int num; }; string Getfilename(string s)//得到文件名字 { string name; int n; n=s.rfind('\\');//逆序查找反斜杠 name=s.substr(n+1); if(name.size()>16) name=name.substr(name.size()-16); return name; } int main() { vector<Eorr> vec; //vector容器 string filepath; int Col; int Num=1; cin>>filepath; cin>>Col; Eorr infor; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; vec.push_back(infor);//第一个vector while(cin>>filepath>>Col)//循环输入 { int flag=0; //cin>>filepath; //cin>>Col; infor.path=Getfilename(filepath); infor.col=Col; infor.num=NUM; for(int i=0;i<vec.size();i++) { if(vec[i].path==infor.path&&vec[i].col==infor.col) { vec[i].num++; //容器添加内容 flag=1; break; } } if(flag==0) { vec.push_back(infor); } flag=0; } if(vec.size()>8)//循环输出 { for(int i=vec.size()-8;i<vec.size();i++) { cout<<vec[i].path<<" "<<vec[i].col<<" "<<vec[i].num<<endl; } } else { for(int i=0;i<vec.size();i++) { cout<<vec[i].path<<" "<<vec[i].col<<" "<<vec[i].num<<endl; } } return 0; } //G:\rp\onajqj\maahmq 631 E:\njfgjkcrh 641 C:\co\zk\ao\bxgxjfgrwckfxekeqro 629 G:\rp\onajqj\maahmq 631
6、
vector 中find函数
#include <iostream> #include<algorithm> #include<vector> using namespace std; struct error_codes { string filename; int codeline; int counter=1; bool operator==(const error_codes &a)//运算符比较的重载 { if(a.filename==filename&&a.codeline==codeline) return true; else return false; } }; string getfilename(string f) //从地址字符串中,获取最后的文件名 { char *fronts,*backs; fronts=&f[0]; backs=&f[0]; while(*fronts!='\0') { if(*fronts=='\\') { backs=fronts; } ++fronts; } string result; ++backs; if(*fronts=='\0') { while(fronts!=backs) { result=result+*backs; ++backs; } backs+='\0'; } if(result.size()>16) result=result.substr(result.size()-16,16); return result; } int main() { vector<error_codes> inputnumber; string filename; int codeline=0; int i=0;//输入的次数 while(cin>>filename>>codeline)//输入 { error_codes temp;//结构体 temp.filename=getfilename(filename);//名字 temp.codeline=codeline;//行号 vector<error_codes>::iterator res;//迭代器 res=find(inputnumber.begin(),inputnumber.end(),temp); if(res==inputnumber.end()) //temp不在inpunumber数组中 { inputnumber.push_back(temp);//将结构体加入到vector中 } else { res->counter++;//有的话count+1; } ++i; } int j=0;//所有都记录,只输出最后8个 if(inputnumber.size()>8) j=inputnumber.size()-8; for(j;j<inputnumber.size();++j) { cout<<inputnumber[j].filename<<" "<<inputnumber[j].codeline<<" "<<inputnumber[j].counter<<endl; } return 0; }
该find方法需要运算符的比较重载
7、
测试用例:可以看到是记录所有的,只输出最后8个。
G:\rp\onajqj\maahmq 631
E:\njfgjkcrh 641
C:\co\zk\ao\bxgxjfgrwckfxekeqro 629
D:\mf\si\jmfdahkeffyjjsf 646
E:\wn\arefkiz 633
C:\gpjleb\cinhhx\zjydgr\njfgjkcrh 640
E:\nwrrhx\qyw\bxgxjfgrwckfxekeqro 636
G:\usgsl\ywr\tve\cqekvaxypemktyurn 647
C:\jftbig\arefkiz 650
F:\rgk\cai\arefkiz 640
D:\tvse\vs\dhzrmy\njfgjkcrh 634
E:\coba\qbs\xagq\njfgjkcrh 628
F:\wnfsmf\oxrvbv\njfgjkcrh 632
C:\khqx\nv\jmfdahkeffyjjsf 637 F:\hm\ra\uaxckn\bxgxjfgrwckfxekeqro 647 D:\soq\jmfdahkeffyjjsf 642 F:\moxnw\szxcdhlaytgj 639 E:\avcop\jd\vwtrt\njfgjkcrh 650 E:\hou\vv\szxcdhlaytgj 631 C:\uozkwd\bxgxjfgrwckfxekeqro 650 F:\jmfdahkeffyjjsf 650
E:\hgoxms\nwax\szxcdhlaytgj 633 F:\vylww\zhh\cqekvaxypemktyurn 643 C:\njfgjkcrh 637 F:\bfn\dxwjje\jmfdahkeffyjjsf 632 E:\bxgxjfgrwckfxekeqro 634 G:\gwuusj\ized\qq\szxcdhlaytgj 646 F:\arefkiz 644 G:\zsw\uewu\arefkiz 634 E:\ja\zg\njfgjkcrh 644
D:\gfute\ju\wuy\szxcdhlaytgj 636 C:\mpgcx\kcgi\arefkiz 645 C:\zayn\jmfdahkeffyjjsf 648 F:\kkplu\avvw\hbzmwj\jmfdahkeffyjjsf 648 E:\maahmq 631 E:\hs\xnto\jmfdahkeffyjjsf 645
G:\cqekvaxypemktyurn 633
D:\maahmq 646
E:\jmfdahkeffyjjsf 636
G:\hbvm\szxcdhlaytgj 642 对应输出应该为: szxcdhlaytgj 636 1 arefkiz 645 1 jmfdahkeffyjjsf 648 2 jmfdahkeffyjjsf 645 1 qekvaxypemktyurn 633 1 maahmq 646 1 jmfdahkeffyjjsf 636 1 szxcdhlaytgj 642 1
八、
题目描述
请解析IP地址和对应的掩码,进行分类识别。要求按照A/B/C/D/E类地址归类,不合法的地址和掩码单独归类。
所有的IP地址划分为 A,B,C,D,E五类
A类地址1.0.0.0~126.255.255.255;
B类地址128.0.0.0~191.255.255.255;
C类地址192.0.0.0~223.255.255.255;
D类地址224.0.0.0~239.255.255.255;
E类地址240.0.0.0~255.255.255.255
私网IP范围是:10.0.0.0~10.255.255.255 172.16.0.0~172.31.255.255 192.168.0.0~192.168.255.255
输入描述:
多行字符串。每行一个IP地址和掩码,用~隔开。
输出描述:
统计A、B、C、D、E、错误IP地址或错误掩码、私有IP的个数,之间以空格隔开。
输入
10.70.44.68~255.254.255.0 1.0.0.1~255.0.0.0 192.168.0.2~255.255.255.0 19..0.~255.255.255.0
输出
1 0 1 0 0 2 1
1、
获取字符串
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; int main() { string str= "10.70.44.68"; vector<int> vec; string s(str.begin(),str.end()-3); string t=str.substr(0,2); cout<<s<<endl; cout<<t; }
可以通过这种方法不用循环,获取字符串中间的子串,同理也可以通过substr获取。
2、拆分点,获取每一个数值
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; int main() { string str= "10.70.44.68"; vector<int> vec; for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } cout<<endl; for(int i=0;i<vec.size();i++) cout<<vec[i]<<" "; }
3、返回vector中的值,要么用全局变量,要么用指针
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; // 初步判断输入的点十分进制表示法是否正确 void isValie(string str,vector<int> &vec)//添加指针 { for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } } int main() { string str= "10.70.44.68"; vector<int> vec; isValie(str,vec); for(int i=0;i<vec.size();i++) cout<<vec[i]<<" "; }
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; // 初步判断输入的点十分进制表示法是否正确 vector<int> vec; void isValie(string str)//添加指针 { for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } } int main() { string str= "10.70.44.68"; isValie(str); for(int i=0;i<vec.size();i++) cout<<vec[i]<<" "; }
两种结果是一样的,但是指针类型可以循环处理多组数据,全局变量的话需要多次置零。
但是注意输入这样的ip后 10..44.68,出现如下结果,注意不输入的情况。
4、
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; bool IpValid(string str,vector<int> &vec)//添加指针,将各个数摘出来 { for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 if(s.size()==0) //10..44.68避免这样情况 return false; int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } if(vec.size()!=4)//个数判断 return false; for(int i=0;i<vec.size();i++) { if(vec[i]<0||vec[i]>255)//范围判断 return false; } return true; } void NumtoVec(int num,vector<int> &box)//逆序存放,将数字转为8位的二进制存放 { //形参中添加vector,是想将数字从函数内传递传去 vector<int> box1; int n; int m=0; while(num>=0 && m<8) { n=num%2; box1.push_back(n); num=num/2; m++; } for(int i=0;i<box1.size();i++)//逆序变正 { box.push_back(box1[box1.size()-i-1]); } } bool MaskValid(string str) { vector<int> vec; vector<int> box; if(IpValid(str,vec)==false) //不满足则退出 return false; for(int i=0;i<vec.size();i++) cout<<vec[i]<<" "; cout<<endl; for(int i=0;i<vec.size();i++) { NumtoVec(vec[i],box); } for(int i=0;i<box.size();i++) cout<<box[i]<<" "; } int main() { string str= "10.70.44.68~255.254.255.0"; //string str= "10.70.44.68~5.4.2.0"; vector<int> vec; string str_ip,str_mask; int n=str.find('~'); str_ip=str.substr(0,11); str_mask=str.substr(n+1,str.size()); IpValid(str_ip,vec); for(int i=0;i<vec.size();i++) cout<<vec[i]<<" "; cout<<endl; MaskValid(str_mask); }
5、
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; bool IpValid(string str,vector<int> &vec)//添加指针,将各个数摘出来 { for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 if(s.size()==0) //10..44.68避免这样情况 return false; int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } if(vec.size()!=4)//个数判断 return false; for(int i=0;i<vec.size();i++) { if(vec[i]<0||vec[i]>255)//范围判断 return false; } return true; } void NumtoVec(int num,vector<int> &box)//逆序存放,将数字转为8位的二进制存放 { //形参中添加vector,是想将数字从函数内传递传去 vector<int> box1; int n; int m=0; while(num>=0 && m<8) { n=num%2; box1.push_back(n); num=num/2; m++; } for(int i=0;i<box1.size();i++)//逆序变正 { box.push_back(box1[box1.size()-i-1]);//255.255.255.0 --> 1111111111111111111111110000000 } } bool MaskValid(string str) { vector<int> vec; vector<int> box; if(IpValid(str,vec)==false) //不满足则退出 return false; for(int i=0;i<vec.size();i++) { NumtoVec(vec[i],box); } for(int i=0;i<box.size();i++) cout<<box[i]; cout<<endl; int n=box.size(),m=-1;//1逆序查找,0正序查找,如果1的下标大于0,说明不符合 for(int i=0;i<box.size();i++) { if(box[i]==0) { n=i; break; } } for(int i=box.size()-1;i>=0;i--) { if(box[i]==1) { m=i; break; } } if(n==box.size()||m==-1)//这是为了出现0.0.0.0或者255.255.255.255特殊情况 return false; else if(n<m) return false; else return true; } int main() { //string str= "10.70.44.68~255.255.255.0"; string str= "10.70.44.68~5.4.2.0"; vector<int> vec; string str_ip,str_mask; int n=str.find('~'); str_ip=str.substr(0,11); str_mask=str.substr(n+1,str.size()); cout<<str_mask<<endl; IpValid(str_ip,vec); cout<<MaskValid(str_mask); }
6、七种情况讨论
#include <iostream> #include <string> #include <vector> #include <list> using namespace std; bool IpValid(string str,vector<int> &vec)//添加指针,将各个数摘出来 { for(int i=0;i<str.length();i++) { int j=i; for(;j<=str.size();j++) { if(str[j]=='.'||j==str.size()) { string s(str.begin()+i,str.begin()+j);//获取子串的方式 if(s.size()==0) //10..44.68避免这样情况 return false; int num=atoi(s.c_str());//atoi将char变为int,c_str将string变为char vec.push_back(num); break; } } i=j; } if(vec.size()!=4)//个数判断 return false; for(int i=0;i<vec.size();i++) { if(vec[i]<0||vec[i]>255)//范围判断 return false; } return true; } void NumtoVec(int num,vector<int> &box)//逆序存放,将数字转为8位的二进制存放 { //形参中添加vector,是想将数字从函数内传递传去 vector<int> box1; int n; int m=0; while(num>=0 && m<8) { n=num%2; box1.push_back(n); num=num/2; m++; } for(int i=0;i<box1.size();i++)//逆序变正 { box.push_back(box1[box1.size()-i-1]);//255.255.255.0 --> 1111111111111111111111110000000 } } bool MaskValid(string str) { vector<int> vec; vector<int> box; if(IpValid(str,vec)==false) //不满足则退出 return false; for(int i=0;i<vec.size();i++) { NumtoVec(vec[i],box); } int n=box.size(),m=-1;//1逆序查找,0正序查找,如果1的下标大于0,说明不符合 for(int i=0;i<box.size();i++) { if(box[i]==0) { n=i; break; } } for(int i=box.size()-1;i>=0;i--) { if(box[i]==1) { m=i; break; } } if(n==box.size()||m==-1) return false; else if(n<m) return false; else return true; } int main() { //string str= "10.70.44.68~255.255.255.0"; string str; int ip_a=0,ip_b=0,ip_c=0,ip_d=0,ip_e=0,ip_err=0,ip_pri=0;//定义初始值 while(getline(cin,str)) { vector<int> vec; string str_ip,str_mask; int n=str.find('~'); str_ip=str.substr(0,n); str_mask=str.substr(n+1,str.size()); if(IpValid(str_ip,vec)&&MaskValid(str_mask)) { if(vec[0]>=1&&vec[0]<=126) { if(vec[0]==10) ip_pri++; ip_a++; } else if(vec[0]>=128&&vec[0]<=191) { if(vec[0]==172&&(vec[1]>=16&&vec[1]<=31)) ip_pri++; ip_b++; } else if(vec[0]>=192&&vec[0]<=223) { if(vec[0]==192&&vec[1]==168) ip_pri++; ip_c++; } else if(vec[0]>=224&&vec[0]<=239) { ip_d++; } else if(vec[0]>=240&&vec[0]<=255) { ip_e++; } } else { ip_err++; } } cout<<ip_a<<" "<<ip_b<<" "<<ip_c<<" "<<ip_d<<" "<<ip_e<<" "<<ip_err<<" "<<ip_pri<<endl; return 0; }
7、
测试案例
测试用例: 206.76.161.30~255.0.0.0 159.70.213.68~255.0.0.0 181.131.118.0~255.255.255.0 80.164.71.44~255.255.255.255 12.208.232.42~255.255.0.0 150.24.121.174~255.0.102.0 131.221.165.68~255.0.0.0 160.126.59.101~255.0.75.0
236.239.205.137~255.255.0.0 89.124.33.74~255.0.0.159 233.174.151.221~255.255.0.0 218.140.130.246~255.255.255.255 13.13.219.143~255.0.0.0 232.95.224.67~255.255.255.255 2.108.39.131~255.0.0.0 161.217.200.192~255.0.0.0
123.170.177.162~255.0.0.0 239.64.91.24~255.0.0.0 241.199.108.210~255.255.255.0 117.0.169.232~255.255.255.255 122.49.165.60~255.255.242.255 71.148.13.251~255.0.0.32 199.22.216.173~255.254.27.0 58.24.55.101~255.132.255.0
68.128.113.136~255.0.0.0 197.234.247.46~255.255.255.0 79.22.71.93~255.255.0.0 250.217.239.76~255.0.8.0 153.96.7.235~255.255.0.0 237.173.48.19~255.0.0.0 140.48.84.23~255.255.255.0 107.222.50.243~255.0.0.0
189.224.126.176~255.255.255.0 111.9.155.102~255.0.0.0 117.4.142.205~255.255.255.255 59.0.177.100~255.255.0.0 60.70.81.248~255.255.255.255 72.85.2.100~255.255.125.0 74.15.130.23~255.0.0.0 37.51.172.97~255.255.255.149
51.58.149.175~255.0.0.0 76.106.99.1~255.255.0.0 198.102.96.87~255.255.0.0 97.170.76.38~255.0.214.0 42.115.213.173~255.255.0.0 95.115.180.128~255.255.0.0 192.240.88.125~255.0.0.47 148.36.118.39~255.0.0.0
237.211.17.109~255.255.255.255 161.230.133.200~255.0.0.0 163.139.243.139~255.0.0.0 249.174.134.36~255.255.255.0 148.64.179.63~255.0.0.0 59.156.109.132~255.0.0.0 42.50.113.7~255.0.0.0 225.95.158.160~255.0.0.0
133.17.112.129~255.0.152.0 212.183.133.49~255.255.0.0 183.12.213.169~255.255.255.255 7.144.20.194~255.255.0.0 106.46.24.252~255.255.255.255 51.181.112.115~255.0.0.0 47.243.149.186~255.255.255.0 174.11.159.234~255.0.0.0
8.83.231.207~255.0.0.0 212.211.51.229~255.0.0.0 6.13.59.212~255.255.119.0 131.151.60.159~255.0.0.0 47.21.57.12~255.0.0.0 136.242.238.159~255.0.0.0 249.200.157.157~255.255.255.0 150.2.21.239~255.0.0.0 26.100.58.90~255.226.0.0
7.167.169.193~255.255.255.0 48.49.16.45~255.132.0.0 67.244.5.142~255.0.189.0 239.170.232.59~255.0.0.0 223.138.166.166~255.0.0.103 199.65.124.179~255.255.0.0 231.121.177.81~255.255.186.193 30.247.220.230~255.255.255.0
227.72.33.192~255.255.255.255 126.189.96.104~255.255.167.255 对应输出应该为: 23 15 6 6 3 30 0
九、
这题是一种新的形式,swap_with_zero函数是已知的,只需直接调用就行,而需要自己编写sort函数,问题就是没法再dev中调试。
1、
十、
三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
输入描述:
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
输入
3 10 81 0
输出
1 5 40
1、可以看出喝到的个数是空瓶的个数的一半取整
#include<iostream> #include<string> using namespace std; int main() { int n; while(cin>>n) { cout<<n/2<<endl; } return 0; }
其实说是3个空瓶换一瓶汽水,但本质上只要有两个空瓶就可以换一瓶汽水
2、递推考虑
已知1个空瓶换0瓶汽水,2个空瓶换1个汽水。
那么3个空瓶,首先用三个空瓶换一个汽水,这时剩一个空瓶,和一个空瓶情况相同了,所以dp(3)=dp(1)+1=1;
同理,dp(4)=dp(2)+1;dp(n)=dp(n-2)+1;
递推状态转移公式出来了。
#include<iostream> using namespace std; int Num[100]={0};//预先定义了空间空间复杂度高 int main() { int n; while(cin>>n) { Num[1]=0; Num[2]=1; for(int i=3;i<=n;i++) { Num[i]=Num[i-2]+1; } cout<<Num[n]<<endl; } return 0; }
3、降低空间复杂度
#include<iostream> using namespace std; int main() { int n; while(cin>>n) { int l1=0,l2=1,q; for(int i=3;i<=n;i++) { if(i%2==0) l2++; else l1++; } if(n%2==0) cout<<l2<<endl; else cout<<l1<<endl; } return 0; }
只保留了两个数来存储变量。节省空间。