这道题真是扒掉我一层皮,还是有部分问题,大多数案例应该可以通过!c/c++不像java的string那么方便,加之vc6.0实在太难用,只能达到这个效果了!
一、收获
1.size_t pos1 = s.find(";",index);
每次使用find函数时,不要忘记第二个参数(开始查询下标),这个每一轮查询都不一样,这个是查完整个字符串的保证
size_t,本质是unsigned int,用typedef起了个名
2.s.substr(pos1,pos2-pos1);
第一个参数是起始位置,第二个参数是长度
3.C++的char数组与string对象相互转化
char t[100];
strcpy(t, s2.c_str());
由于strtok方法参数只能是char[]和char*必须转化
参考:https://www.cnblogs.com/fnlingnzb-learner/p/6369234.html
4.int和string转化
int len = strtol((v1[i].substr(t1+1,t2-t1-1)).c_str(),NULL,0);//字符串转为long int类型
由于vc6.0实在太难用,只支持86%的C++,stoi等函数都不能用,只能用这个凑合。java多简单。
5.char转为string
这个,找不到好办法??
6.vc6.0的一些问题,见:https://www.cnblogs.com/sybil-hxl/p/10468571.html
7.剩下的一些算法细节,代码中都有注释,就不在此处写了!
二、题目
/*
二,查找未定义变量
输入二个C语言语句u,第一句为正常的C语言变量定义语句,符合C语言语法要求,变量间可以有多个空格,
包括数组、指针定义等。第二句为变量运算语句,要求输出第二个C语言语句中未定义的变量。
Example:
int x12,y=1,num_stu=89,a[30],*p;
Sum=num+x12*y;
Output:
Sum num
*/
2.思路
(1)输入第一行s1,先把数据类型删除,然后删除c的内容,最后用sep1分隔,得到所有已定义变量名存储到v1中
(2)输入第二行s2,从s2中删除空格以及v1中定义的变量
这里数组定义处理那块费了很大的劲!
(3)把删除完已定义变量的s2进行多符号分隔
方法一:采用C语言的strtok方法
方法二:split2方法,即能够被多个符号分隔
(4)输出未定义的变量名
(5)17_2.txt内容可以是:
int x12,y=1,num_stu=89,a[30],*p;
Sum=num+x12*y-a[30]+a[20]*a[31];
int x12,y=1,num_stu=89,a[30],*p;
Sum=num+x12*y-a[30]+a[20]+z;
3.代码
注释掉的代码暂时没用,也不一定能跑出来,防止以后用得着,先留着
/* #ifdef WIN32 #pragma warning (disable: 4514 4786) #endif */ #include <iostream> #include <string> #include <cstring> #include <vector> #include <algorithm> #include <stdlib.h> using namespace std; void delStr(string& s,string& str){//删除字符串中的子串,这一个可以顶下面好几个方法了! int pos = 0; if(!s.empty()){ while((pos = s.find(str,pos)) != string::npos){ s.erase(pos,str.length()); } } } /* void delChar(string& s,string& c){ int n = c.length(); cout<<n<<endl; for(int i=0;i<n;i++){ string tmp(c[i],1);//这是临时变量,地址就没啦!!!!! cout<<"========="<<tmp<<"========="<<endl; delStr(s,tmp);//直接调用上面的方法,省劲!! } }*/ /* //暂时不用 void deletChar1(string& s,char c[]){//去掉字符串中的几个字符,空格和*(用于指针定义)。其实最好用regex?? int n = sizeof(c)/sizeof(char); for(int i=0;i<n;i++){ iterator tmp = find(s.begin(),s.end(),c[i]); while(tmp!=s.end()){ auto x = s.erase(tmp); tmp = find(x,s.end(),c[i]); } } } */ /* void trim(string& s){//暂时不用 //去掉头和尾的空格 if(!s.empty()){ s.erase(0,s.find_first_not_of(" ")); s.erase(s.find_last_not_of(" ")+1);//别忘记+1 } //去掉字符串中间的所有空格 int index=0; if(!s.empty){ while((index = s.find(" ",index)) != npos){//每次使用find函数时,不要忘记第二个参数,这个是查完整个字符串的保证 s.erase(index,1); } } } */ void delValue(string& s){//删除变量赋的值 size_t p = s.find("="); if(p != string::npos){ //if(( p = s.find("=",p) ) == string::npos){//如果只有一个“=” s = s.substr(0,p);//直接取等号之前的为变量名。 //}else{//如果是连续赋值,还真不知道怎么处理???c++好像不支持定义时连续赋值? //} } } void split1(vector<string>& v,const string& s,const string& c){//只能根据一个分隔符分隔字符串 size_t pos1 = 0; size_t pos2 = s.find(c); while(string::npos != pos2){//表示find找不到 string tmp = s.substr(pos1,pos2-pos1);//第一个参数是起始位置,第二个参数是长度 delValue(tmp);//删除变量赋的值 v.push_back(tmp); pos1 = pos2 + c.length(); pos2 = s.find(c,pos1);//从pos1开始查找,避免没必要的查找和重复 } if(pos1 != s.length()){//最后一个分隔符之后的子串 v.push_back(s.substr(pos1)); } } void split2(vector<string>& v,const string& s,const string& sep){//可以用多种分隔符分隔字符串 //1.获得第一个不是分隔符的字母位置f1 //2.第二个分隔符位置f2 //3.截取字符串f1-f2 //4.循环1,2 int f1=-1,f2=-1; int i=0; while(i<s.length()){ //ab;cd;f,ggg,hi //;, f1=0 f2=2 size_t p1 = sep.find(s[i]); if(p1 == string::npos){ if(f1 == -1){//标志第一个 f1 = i; } }else{ f2 = i; } if(f1 != -1 && f2 != -1 && f1<f2){//不能丢f1<f2的条件,否则仍然会出问题 string tmp = s.substr(f1,f2-f1); delValue(tmp);//删除变量赋的值 v.push_back(tmp); f1=f2=-1;//恢复 } //这里没有像split1一样处理最后一个分隔符之后的子串是因为“;”本身就是分隔符,在s2的最后,其后面没有变量了 i++; } } void main(){ freopen("G:/17_2.txt","r",stdin); string a[6]={"int","short","long","char","float","double"}; string b="+-*%/&|!~^><=:?.(),;";//sizeof这种符号就无法使用 string c[3]={" ","*",";"}; string sep1 = ","; while(!cin.eof()){//一共两行,其实没必要这个循环了!,如果有很多测试可以加上循环 vector<string> v1,v2;//v1存储第一行定义的变量名,v2存储第二行没定义的变量名也就是输出结果 string s1,s2; cin>>s1; //一、输入第一行,先把数据类型删除,然后删除c的内容,最后用sep1分隔,得到所有已定义变量名存储到v1中 for(int i=0;i<6;i++){ if(s1.compare(a[i]) == 0){ getline(cin,s1);//应该先把整行全部输入,作为字符串,然后再分析。用","隔开表示两个定义变量。 for(int j=0;j<3;j++){//把里面的空格,分号,星号删掉 delStr(s1,c[j]); } //split1(v1,s1,sep1);//这两个方法都可以用 split2(v1,s1,sep1); } } getline(cin,s2); //二、第二行处理,从s2中删除空格以及v1中定义的变量 delStr(s2,c[0]); for(i=0;i<v1.size();i++){ int t1=0,t2=0; if((t1=v1[i].find("[")) != string::npos && (t2=v1[i].find("]")) != string::npos){//如果包含数组,对数组变量的处理 size_t sz; int len = strtol((v1[i].substr(t1+1,t2-t1-1)).c_str(),NULL,0);//字符串转为long int类型 string var1 = v1[i].substr(0,t1); int t0=0; while((t0=s2.find(var1,t0)) != string::npos){ t1=t2=t0; while((t1=s2.find("[",t1)) != string::npos && (t2=s2.find("]",t2)) != string::npos){ string index = s2.substr(t1+1,t2-t1-1); //int index = strtol( (s2.substr(t1+1,t2-t1-1)).c_str(),NULL,0 ); int index1 = strtol(index.c_str(),NULL,0); if(index1 < len && index1 >=0){ delStr(s2,var1+"["+index+"]"); } t1=t2=t2+1; } t0=t0+1;//若没有t0+1,则导致死循环 } }else{//如果不含数组,直接把相应变量删掉就好 delStr(s2,v1[i]); } } //三、把删除完已定义变量的s2进行多符号分隔 //方法一:采用C语言的strtok方法 /*char t[100]; strcpy(t, s2.c_str()); const char *sep = "+-*%/&|!=;"; char *p = strtok(t, sep); while(p){ v2.push_back(p); p = strtok(NULL, sep); }*/ //方法二:split2方法,即能够被多个符号分隔 split2(v2,s2,b); //四、输出未定义的变量名 for(i=0;i<v2.size();i++){ cout<<v2[i]<<" "; } cout<<endl; } }
作者:西伯尔
出处:http://www.cnblogs.com/sybil-hxl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
浙公网安备 33010602011771号