华为2020 暑期实习生 通用软件开发工程师 笔试回忆

题型

  • 编程 3道 120分钟

编程1:员工评选

投票选举最佳员工,选出得票数最高的员工,若:
1)票数相同,按名字的字典序排序;
2)票数相同且名字有包含关系(Tom和Tomy),则名字短者在前。

  • 输入:一行,名字之间用隔开,如:Tom,Lucy,Tom,Jack,Rose
  • 输出:最佳员工的名字,如:Tom
  • 思路:设置结构体存储名字和票数,创建一个结构体数组,然后调用sort函数传一个lamda表达式进行排序,最后输出第一个元素;
  • 参考代码(AC 75%):
#include<iostream>
#include<vector>
#include<algorithm>
#include<map>
#include<string>
#include<set>

using namespace std;

bool contain(string &s1, string &s2);

struct person{
	string name;
	int vote;
	person(string s, int v):name(s),vote(v){}
};

int main(){
	string str;
	cin >> str;
	vector<string> names;
	map<string, int> votes;
	int start = 0, end = 0;
	while (end != str.size())
	{
		if (str[end] == ',')
		{
			string name = str.substr(start, end - start);
			names.push_back(name);
			start = end + 1;
			end++;
		}
		else if (isalpha(str[end]))
			end++;
		else
        {
            cout << "error.0001";
            return 0;
        }
	}
	names.push_back(str.substr(start, end - start));
	for (auto &n : names)
		votes[n]++;
	vector<person> ps;
	for (auto v : votes)
		ps.push_back(person(v.first, v.second));
	sort(ps.begin(), ps.end(),
		[&votes](const person &p1, const person &p2){
		if (p1.vote != p2.vote)
			return p1.vote > p2.vote;
		else if (contain(p1.name, p2.name))
			return p1.name.size() < p2.name.size();
		else
			return p1.name < p2.name ;
	}
	);
	cout << ps[0].name;
	return 0;
}

bool contain(string &s1, string &s2)
{
	if (s1.size() < s2.size())
	{
		string temp = s2;
		s2 = s1;
		s1 = temp;
	}
	for (int i = 0; i<=s1.size() - s2.size(); i++)
	{
		if (s1[i] == s2[0])
        {
            bool tag = true;
            int j = 0;
            while(j < s2.size())
            {
                if(s1[i + j] != s2[j])
                {
                    tag = false;
                    break;
                }
                j++;
            }
            if(tag) return true;
        }
	}
	return false;
}

编程2:字符匹配

这道题题意看的不是很懂。
给出一个待匹配串,一个表示若干寄存器的固定格式的母串,寄存器格式:xxx[name:xxx,mask:xxx,val:xxx],母串有多个寄存器字符串通过相连,匹配规则:1)待匹配串和寄存器编号相同;2)待匹配串的name、mask、val和母串中的某个寄存器相同。

  • 输入:待匹配串,母串,空格相隔;
  • 输出:对于每一个匹配到的寄存器,输出寄存器的name mask val空格相隔;
  • 思路:这道题最后没时间了(代码里有大量的if/else没来得及优化),就只考虑了待匹配串是一个寄存器编号的情况。设置下标start和end遍历母串,不断截取需要的字符串进行比较或者输出就行。
  • 参考代码(AC 75%):
#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

int main(){
	string str, sta;
	cin >> str >> sta;
	string temp;
	int start = 0, end = 0;
	while (end != sta.size())
	{
		if (sta[end] == '[')
		{
			string s = sta.substr(start, end - start);
			start = end + 1;
			end++;
			if (str == s)
			{
				while (sta[end] != ']')
				{
					if (sta[end] == '=')
					{
						start = end + 1;
						end++;
					}
					else if (sta[end] == ',')
					{
						string s = sta.substr(start, end - start);
						cout << s << " ";
						start = end + 1;
						end++;
					}
					else
						end++;
				}
				string s = sta.substr(start, end - start);
				cout << s << " ";
				cout << endl;
			}
		}
		else if (sta[end] == ',')
		{
			start = end + 1;
			end++;
		}
		else
			end++;
	}
	return 0;
}

编程3:最长调用链

给出n个函数,每个函数的权值,以及每个函数可以调用的其他函数,输出权值最大的调用链的权值。

  • 输入:第一行,x a b c d ...x代表函数的个数,后边的x个数代表每个函数可以调用的其他函数个数;
    接下来x行,每行如z y a b c ...z代表函数编号,y代表函数权值,后面的若干数代表函数x可以调用的函数编号;
  • 输出:最大权值;
  • 思路:记忆递归,但是提示段错误:可能数组越界或者递归深度过大,之前没记忆化的时候也是这个提示,而且AC率没有变;
  • 参考代码(AC 60%):
#include<iostream>
#include<vector>
#include<algorithm>
#include<set>
#include<map>

using namespace std;

int maxval = 0;
map<int, int> cache;

int calcu(vector<vector<int>> &call, set<int> &memo, int index, vector<int> &val, int curr);

int main(){
	int n;
	cin >> n;
	vector<int> temp(n + 1);
	for (int i = 1; i <= n; i++)
		cin >> temp[i];
	vector<vector<int>> call(n + 1);
	vector<int> val(n + 1);
	for (int i = 1; i <= n; i++)
	{
		int x, v;
		cin >> x >> v;
		val[x] = v;
		for (int j = 0; j<temp[i]; j++)
		{
			int x;
			cin >> x;
			call[i].push_back(x);
		}
	}
	for (int i = 1; i <= n; i++)
	{
		if (temp[i] != 0)
		{
			set<int> memo;
			if (calcu(call, memo, i, val, 0) == -1)
			{
				cout << "R";
				return 0;
			}
		}
	}
	cout << maxval;
	return 0;
}

int calcu(vector<vector<int>> &call, set<int> &memo, int index, vector<int> &val, int curr)
{
	if (memo.count(index))
	{
		return -1;
	}
	if (cache.count(index))
	{
		curr += cache[index];
		maxval = max(maxval, curr);
		return curr;
	}
	curr += val[index];
	memo.insert(index);
	if (call[index].size() == 0)
	{
		maxval = max(maxval, curr);
		return curr;
	}
	for (auto v : call[index])
	{
		int temp = calcu(call, memo, v, val, curr);
		if (temp == -1)
			return -1;
		cache[index] = max(cache[index], temp - curr);
		memo.erase(v);
	}
	//no use
	return curr;
}

华为的笔试题还是有一定难度的,而且输入的处理真的很让人脑阔疼,感觉自己一直在截字符串233,不过总的来说逻辑清晰的话还是能AC一部分(留下了羞愧的泪水)。

发布了26 篇原创文章 · 获赞 16 · 访问量 5857

猜你喜欢

转载自blog.csdn.net/weixin_44826484/article/details/105544446