3月份(3月11号)华为春招笔试题,本人菜的抠脚,三道题才过了一道。之前在牛客上刷了几十道题沾沾自喜,笔试的时候发现自己是井底之蛙。
印象比较深的是第一题的字符串替换的题目(具体名字记不清了),大意是输入一组数量为n的字符串,格式是“字符串名=字符串值”,字符串值中可能包含"&{字符串名}“的子串,需要用同一字符串名的字符串值来替换。最后输出内容是输入数据最后一行所有”&{串名}"被替换后的串值。
输入数据
xxx=sss/ooo/&{ttt}/uuu
ttt=www
eee=jjj
yyy=ggg/ppp/&{xxx}/ttt/&{eee}
输出数据
ggg/ppp/sss/ooo/www/uuu/ttt/jjj
题目约定输入数据最后一行每个被"&{}“包含的字符串名都在之前的输入数据中给出。
字符串处理比较繁琐,但是算法上不需要涉及太多知识点。我没想出来什么牛逼的方法,老老实实用常规的思路。输入用getline函数读取字符串之后按‘=’分割成两个字符串,然后用make_pair函数存到vector<pair<string,string>>,first存储字符串名,second存储字符串值。输入数据全部处理之后,再对vector里面的second字符串遍历,查到‘&’,标记下标,查到‘}’,标记下标。截取两下标之间的子串,匹配vector里面的first,匹配对了就把原来second里的字符串改成 ‘&’前的子串 + 匹配到的first对应的second字符串 + ‘}’后的子串,然后重新遍历一遍改后的字符串,直到字符串里面没有被”&{}"修饰的字符串名。
下面贴上代码:
#include <iostream>
#include <string.h>
#include <vector>
using namespace std;
int main()
{
int i,j,k,s,t,n,pos,len;
string str;
vector<pair<string,string> > sentence;
while (cin>>n)
{
char ch=getchar();
sentence.clear();
for (s=0;s<n;s++)
{
getline(cin,str);
len=str.length();
for (pos=0;pos<len;pos++)
if (str[pos]=='=')
break;
//从=号右边提取$替换子串,存为(xxx,ttt)这种
i=pos+1;
string left=str.substr(0,pos);
string right=str.substr(pos+1);
sentence.push_back(make_pair(left,right));
}
for (s=0;s<sentence.size();s++)
{
i=0;
str=sentence[s].second;
while (i<len)
{
len=str.length();
if (str[i]=='&')
{
for (j=i+2;j<len;j++)
if (str[j]=='}')
break;
string str1=str.substr(i+2,j-2-i);
for (k=0;k<sentence.size();k++)
//有变量可以替换
if (str1==sentence[k].first)
{
str.erase(str.begin()+i,str.begin()+j+1);
str=str.substr(0,i)+sentence[k].second+str.substr(i);
}
i=0;
}
else i++;
}
sentence[s].second.clear();
sentence[s].second=str;
}
cout<<sentence[sentence.size()-1].second<<endl;
}
}
我一开始想在输入的时候就对字符串进行处理,直接对vector里面的第j个数据的second元素找“&{}”,找到了就和vector里面前j-1个数据的first元素比对,如果相等就把“&{}”结构直接替换成它的second数据,没有相等的first就把第j个数据标记为true,表示存在没有替换过的‘&{}’结构。如果第j个数据的second里面没有“&{}”结构,就让它和前j-1个数据里面被标记为true数据的“&{}”以内的字符串对比,两个字符串相等就替换这个结构。
后来发现越写越乱,逻辑也不清楚,算法效率也不高,遇到极端情况可能比上面的方法时间复杂度更高,然后就换成上面的方法了。
笔试也不知道能不能过,归根究底还是自己太菜了,代码得多敲,各种算法也得多看。作为我的第一篇博客,希望自己以后能越来越好吧。