2021华为软件工程师笔试题第一道
题目阐述
- 某公司要发传单。
- 现有主管、组员和外包人员三个层级,主管将发传单任务委托给组员,组员再把任务委托给外包。
- 实际干活的只有外包,主管和组员的传单数(名义上)为其手下的外包人员的传单数目之和。
- 要求输出所有人的传单总数,格式如下:
姓名<传单数目>
。 - 此外,为了清晰,输出要以树形结构输出,用
-
和--
分别作为组员
和外包人员
的前缀。
样例
输入
- performance后面的为
外包人员姓名,该人员的传单数目
。 - organization后面的为层级制度,如Aaron为主管,Abel为组员,Adam为外包人员
- 样例约束:每个外包人员只能被一个组员负责,每个组员只能被一个主管负责
performance
Adam,125
Andy,110
Bill,92
Evan,154
organization
Aaron,Abel,Adam
Aaron,Abel,Andy
Aaron,Jone,Bill
Aaron,Jone,Evan
eof
输出:
Aaron<481>
Abel<235>
--Adam<125>
--Andy<110>
Jone<246>
--Bill<92>
--Evan<154>
思路
- 使用面向对象的方式实现
- 自底层(外包人员)向顶层(主管)逐层收集数据
- 自底层(外包人员)向顶层(主管)逐层计算名义传单数
实现
// @ts-lint
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
})
const lines = []
rl.on('line', handle)
// -------------------------------------------------- 定义主管、组员、外包人员这三个类 --------------------------------------------------
// 主管,字母越靠前,层级越高
function A(name) {
this.name = name
// 他的手下们(他的组员们)
this.subs = []
// 他的名义传单数目
this.num = 0
}
A.prototype.add = function(item){
this.subs.push(item)
}
// 待收集完他的手下们,主管计算他的名义传单数
A.prototype.cal = function(){
this.subs.forEach(item => {
this.num += Number(item.num)
})
}
// 组员
function B(name) {
this.name = name
this.subs = []
this.num = 0
}
// 组员本质上和主管一样,啥活不干,所以可以继承主管的 add 和 cal 方法
B.prototype = Object.create(A.prototype)
// 外包
function C(name, num) {
this.name = name
this.num = Number(num)
}
// -------------------------------------------------- 用于存放各级人员的三个数组 --------------------------------------------------
/**
*
* @type {Array<C>}
*/
let cList = []
/**
*
* @type {Array<B>}
*/
let bList = []
/**
*
* @type {Array<A>}
*/
let aList = []
let status = ''
/**
*
* @param {string}line
*/
function handle(line) {
// -------------------------------------------------- 面向牛客网的输入编程 --------------------------------------------------
if (line.trim() === '') return
if (line.trim() === 'eof') {
// 最后一行时,输入的数据已经全部接收,可以计算数据并进行输出了
calculateAndPrintResult()
}
if (line === 'performance') {
status = 'p'
return
}
if (line === 'organization') {
status = 'o'
return
}
// -------------------------------------------------- 收集数据进数组 --------------------------------------------------
if (status === 'p') {
let twins = line.split(',')
cList.push(new C(twins[0], twins[1]))
}
if (status === 'o') {
let triplets = line.split(',')
let cName = triplets[2]
let bName = triplets[1]
let aName = triplets[0]
// let c = cList.find(item => item.name === cName) // must has one
let b = bList.find(item => item.name === bName)
let a = aList.find(item => item.name === aName)
if (!a) { // 不得重复
aList.push(new A(aName))
}
if (!b) {
bList.push(new B(bName))
}
// -------------------------------------------------- 建立ABC这三个类的关联(通过subs) --------------------------------------------------
// cc bb aa must exists
let cc = cList.find(item => item.name === cName)
let bb = bList.find(item => item.name === bName)
let aa = aList.find(item => item.name === aName)
if (!bb.subs.find(c => c === cc)) {
bb.add(cc)
}
if (!aa.subs.find(b => b === bb)) {
aa.add(bb)
}
// -------------------------------------------------- 计算并打印 --------------------------------------------------
function calculateAndPrintResult() {
bList.forEach(b => {
b.cal()
})
aList.forEach(a => {
a.cal()
})
aList.forEach(a => {
console.log(`${a.name}<${a.num}>`)
a.subs.forEach(b => {
console.log(`-${b.name}<${b.num}>`)
b.subs.forEach(c => {
console.log(`--${c.name}<${c.num}>`)
})
})
})
process.exit(0)
}
}
版权声明:本文为oceans原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。