ThoughtWorks公司算法岗位面试经历总结
一、面试的具体流程:
1、面试时间:8月22日(周三)15:00
2、公司地址:成都市高新区天府软件园E1-1 7楼(请从1号门进入)
3、面试流程:技术面试 1H
4、面试经历:
(1)技术面:自带笔记本,在原来的作业题(计算机自动生成迷宫的基础上)添加新的2个功能,及时编程,时限30分钟;
- 介绍一个自己最感兴趣的项目(导师的自然科学基金项目),详说技术路线(水平集与U-Net)
- 介绍自己的论文具体原理;
- 面向对象编程与面向过程编程的区别
- 介绍一下卷积神经网络的常见几个模型,具体说说VGG,ResNet两者间的区别
- 神经网络如果卷积层数无穷多,会出现什么后果?
- 谈谈机器学习与深度学习之间的区别
- 机器学习中的Stacking融合技术原理是什么?为什么会分块?
(2)HR面
- 自我介绍(1分钟)
- 你最大的优势是什么?
- 详细介绍一个比赛?
- 别人是如何评价你的?缺点是什么?
- 成绩如何?
- 遇到挑战如何处理,有没有与同事发生较大冲突?有的话如何解决?
- 比实验室其他人的优势是什么?
- 做过最有意义(最有挑战)的项目是什么?最困难的一段学习经历是什么?
- 平时是如何学习的?
- 遇到最大的挫折是什么?
- 为什么选择跨专业学计算机?
- 你平时喜欢做什么?看过哪些书?最近在看什么书?
- 是否愿意做开发岗位?
(3)面试结束时,面试官问:你还有什么想问的?(面试官面试其实想知道两件事:你能干这活不?你愿意在我们公司干这活不?)
- 请问公司对我这个职位的期望是什么?(问了)
- 请问入职后是否有相关的职位技能培训?(问了)
- 团队成员有多少人?核心工作是什么?(问了)
- 贵公司未来5年的发展方向是什么?(问了)
- 您能形容一下部门的工作氛围吗,以及部门有团建活动吗?
- 这个职位的发展路径一般是怎么样的呢?(问了)
- 能告诉我现在公司/部门面临的最大机遇/挑战是什么吗?
- 这个职位为什么空缺?
- 这个职位换过多少人?主要原因是什么?
- 目前这个职位最紧要的任务是什么?如果我有幸进入贵公司,您希望我三个月完成哪些工作?(问了)
- 贵公司/部门希望通过这个职位实现的长期目标是什么?
- 这一职位面临的最大困难是什么?
- 贵公司最近有什么重大规划?
- 请问在这个职位做出出色业绩的员工,将有什么发展机会?大约多长时间能实现?能举个例子吗?
- 贵公司在产品与服务上的成功之处是什么?
- 这个职位的工作业绩是如何评估的?(问了)
- 为什么这个职位仍然空缺着?
- 我有多少假期,以及加班情况?
- 公司/部门的目标有哪些?
-
贵公司什么时候可以答复面试结果?
5、内心戏与总结(已挂)
提前一天去的成都,晚上也刷了很多面经,思特沃克算是我的第一次现场面试,手撕代码。可惜两个功能知道怎么做,未在30分钟实现,感觉自己还是太菜了。
(1)内推校招作业题的通过标准(我用的是Python)
- 良好的编程习惯,特别注重细节,小到一个空格,缩进,注释的方式都会被怼;
- 仅仅实现功能,未必能通过筛选,必须对代码进行优化,如面向对象编程,最好封装成类,可以直接调用;
- 能展现出自己编程的个性
- MarkDown的编辑说明,网易云笔记的使用,如何写readme说明文档
(2)现场手撕代码,时限30分钟
- 在原来的作业题的基础上,继续完善,并不能破坏原来的结构;
- 最好写成类函数的形式,方便调用,可读性强;
- 模式是什么?几个面试官坐在你对面,给你两张A4纸,上面是需要添加的功能说明,先理解,如有不懂可以提问,知道怎么做后,先给面试官讲一下自己的思路,再进行编程实现,30分钟。
(3)为什么会挂?
个人觉得主要还是编程没有实现,印象分肯定差了不少。加上后面的面试表现不太好,哎,还得努力
二、作业题(通过筛选标准)
完整版代码(作业题+面试附加题)已上传至百度云盘:https://pan.baidu.com/s/1l12swNRooGAOwwgKlvQofg 密码:swa2 ,内容如下:
一、作业内容
* 本作业限时3天完成
* 作业完成后必须附上 Readme 纯文本文档(推荐使用 markdown 排版)
* Readme文档中必须描述如何运行单元测试或主程序来证明作业的正确性(至少针对测试用例输入能够得到对应输出)
* 作业的输入和输出必须和题目的测试用例输出严格一致
* 可以选用擅长的语言完成,例如C、C++、Java、C#、Javascript、Python、Scala等
*请注意作业的保密性,不要将作业放在Git等渠道上面
校招题目
用计算机生成迷宫是一个很有趣的任务。我们可以用 道路网格(Road Grid) 来表示迷宫的道路,那么 3 x 3 的 道路网格(图-1 左)可以对应一个 7 x 7 的 渲染网格(Render Grid) ——图-1 右 的方式(迷宫的墙是灰色的,道路是白色的):
连通 道路网格 有如下的约束条件:
● 每一个 cell 只能够直接与相邻正南、正北、正东、正西的 cell 连通。不能够和其他的 cell 连通。
● 两个 cell 之间的连通一定是双向的。即 cell(0,0) 和 cell(1,0) 连通等价于 cell(1,0) 和cell(0,0) 的连通。
要求1:将迷宫渲染为字符串
现在我们希望你书写程序,将给定迷宫的 道路网格,渲染为字符串输出。例如,其使用方式如下(伪代码,仅做演示,实际实现时请应用实际语言的编程风格)
Maze maze = MazeFactory.Create(command);
String mazeText = maze.Render();
其中 command 是一个字符串。它的定义如下:
● 第一行是迷宫 道路网格 的尺寸。例如 3 x 3 的迷宫为 3 3,而 5 x 4 的迷宫为 5 4(5 行 4 列)。
● 第二行是迷宫 道路网格 的连通性定义。如果 cell(0,1) 和 cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号 ; 隔开。
例如,如果给定输入:
3 3
0,1 0,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
则输出字符串为(如果当前 渲染网格 为墙壁,则输出 [W] 如果为道路则输出 [R]):
[W] [W] [W] [W] [W] [W] [W]
[W] [R] [W] [R] [R] [R] [W]
[W] [R] [W] [R] [W] [R] [W]
[W] [R] [R] [R] [R] [R] [W]
[W] [W] [W] [R] [W] [R] [W]
[W] [R] [R] [R] [W] [R] [W]
[W] [W] [W] [W] [W] [W] [W]
要求2:检查输入的有效性
在处理输入的时候需要检查输入的有效性。需要检查的有效性包括如下的几个方面:
● 无效的数字:输入的字符串无法正确的转换为数字。此时,该函数的输出为字符串 ”Invalid number format. ”
● 数字超出预定范围:数字超出了允许的范围,例如为负数等。此时,该函数的输出为字符串”Number out of range. ”
● 格式错误:输入命令的格式不符合约定。此时,该函数的输出为字符串 ”Incorrect command format. ”
● 连通性错误:如果两个网格无法连通,则属于这种错误。此时,该函数的输出为字符串 ”Maze format error.”
当多个问题同时出现时,报告其中一个错误即可。
二、文档说明
0. 写在前面
该方法主要功能包括以下几个部分:
- 利用Python实现迷宫字符串:类的封装、输入数据的有效性判断
- 测试数据的输入有两种输入方式:手动输入与直接加载(考虑到第二行输入的不便性)
- 个性化输出结果:将迷宫中的路径标记为红色,便于检查
1. 运行环境
Windows(64位) + PyCharm + Anaconda(Python3.5.2)
2. 代码如何运行
(1) 代码说明
1) 该代码已封装为类Maze,具体函数见文件getMaze.py。其中包括两个属性:num与command,分别表示为:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
command: 迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号;隔开。
2)另外,类Maze主要包含三个功能:initial_maze,getFinalMaze与showResult,分别表示为:
- Maze.initial_maze():初始化迷宫&道路网格
- Maze.getFinalMaze():将迷宫渲染为字符串
- Maze.showResult():矩阵形式打印最终迷宫字符串
3)getMaze.py还包括另外三个函数:judge_num,dataInput_byHand与dataInput_withFile,其功能分别表示为:
- judge_num():判断迷宫道路网格的尺寸的输入是否合法
- dataInput_byHand():手动输出5种不同的测试数据
def dataInput_byHand():
"""
输入:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,(3行3列),即num = [3,3]
command:迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2 当多个连通,则以分号;隔开
输出:
num, command
"""
# step1: 输入迷宫的行列数,中间用空格隔开
while True:
num = [int(i) for i in input().split()]
# 判断输入数据是否合法
if judge_num(num):
break
else:
num = [i for i in input().split()]
if judge_num(num):
break
# step2: command的输入
command = list(input().split(';'))
return num,command
- dataInput_withFile():直接加载已准备好5种的测试文档
def dataInput_withFile():
# 请选择5种不同的待测试的文件
data = list(open('data/data_正确输入.txt').read().split('\n')) # 正确输入
# data = list(open('data/data_Incorrect command format.txt').read().split('\n')) # 格式错误
# data = list(open('data/data_Invalid number format.txt').read().split('\n')) # 无效的数字
# data = list(open('data/data_Mazeformat error.txt').read().split('\n')) # 连通性错误
# data = list(open('data/data_Number out of range.txt').read().split('\n')) # 数字超出预定范围
num = [i for i in data[0].split()]
command = list(data[1].split(';'))
# 判断num的输入是否存在错误!
if len(num) != 2:
print('Invalid number format.')
quit()
else:
# 判断读入行列数是否为数字
if num[0].lstrip('-').isdigit() == 0 or num[1].lstrip('-').isdigit() == 0:
print('Invalid number format.')
quit()
else:
num = [int(i) for i in num]
return num, command
4)主函数为:
# 主函数
if __name__ == "__main__":
# step1: 数据输入
# num, command = dataInput_byHand() # 手动输入测试数据
num, command = dataInput_withFile() # 直接加载5种txt格式的测试数据
# step2: 调用函数
maze = Maze(num, command) # 定义类maze
initial_Result = maze.initial_maze() # 初始化迷宫
final_Result = maze.getFinalMaze(initial_Result) # 迷宫渲染为字符串
# step3: 输出结果
maze.showResult(final_Result) # 矩阵形式打印最终迷宫字符串
(2)测试数据
1)data_正确输入
3 3
0,1 0,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
2)data_Incorrect command format
3 3
0,1 0,2aa;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
3)data_Invalid number format
3 a
0,1 0,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
4)data_Mazeformat error
3 3
0,1 1,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
5)data_Number out of range
3 -1
0,1 0,2;0,0 1,0;0,1 1,1;0,2 1,2;1,0 1,1;1,1 1,2;1,1 2,1;1,2 2,2;2,0 2,1
(3)运行结果
1)data_正确输入
[W] [W] [W] [W] [W] [W] [W]
[W] [R] [W] [R] [R] [R] [W]
[W] [R] [W] [R] [W] [R] [W]
[W] [R] [R] [R] [R] [R] [W]
[W] [W] [W] [R] [W] [R] [W]
[W] [R] [R] [R] [W] [R] [W]
[W] [W] [W] [W] [W] [W] [W]
2)data_Incorrect command format
Incorrect command format.
3)data_Invalid number format
Invalid number format.
4)data_Mazeformat error
Mazeformat error.
5)data_Number out of range
Number out of range.
(4)个性化输出结果
为了方便直观检查迷宫生成是否合理,该方法将"[R]"标记为红色,函数如下:
# 矩阵形式打印最终迷宫字符串
def showResult(self,result):
"""
输入:
result: 渲染后的迷宫字符串二维列表
输出:
矩阵形式打印出结果
"""
# 如果添加颜色,代码如下:
for i in range(len(result)):
count = 0
for j in result[i]:
if j == '[R]':
print('\033[5;31m' + j + ' \033[0m', end='') # 将"[R]"标记为红色
count += 1
else:
print(j, end=' ')
count += 1
if (count % len(result[0]) == 0):
print(end='\n')
# 如果不添加颜色,代码如下:
# for i in range(len(result)):
# print(" ".join(str(j) for j in result[i]))
运行结果如下:
- 当第一行输入为:3 3,第二行不变时。
- 当第一行输入为:6 8,第二行不变时。
三、具体代码
# !/usr/bin/python3.5.2
# -*- coding: UTF-8 -*-
# 计算机生成迷宫,再渲染为字符串
class Maze:
def __init__(self, num, command):
"""
初始化:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
command: 迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号;隔开。
"""
self.num = num
self.command = command
# 初始化迷宫&道路网格
def initial_maze(self):
"""
输入:
self.num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
输出:
result: 初始的迷宫
"""
row, col = self.num[0], self.num[1] # 获取行数,列数
result = [['[W]']*(2*col+1) for index in range(2*row+1)] # 初始化迷宫
for i in range (row):
for j in range(col):
result[2*i+1][2*j+1] = '[R]'# 初始化输出
return result
# 迷宫渲染为字符串
def getFinalMaze(self, result):
"""
输入:
self.num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
self.command: 迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号;隔开。
result: 初始的迷宫
输出:
result: 渲染后的迷宫,即根据self.command联通信息渲染后的迷宫
"""
row, col = self.num[0], self.num[1] # 获取行数,列数
# step1: 判断迷宫道路网格的连通性定义输入是否合法
if row < 0 or col < 0:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit() # 判断行列数是否合法
for i in range(len(self.command)): # 进入循环
# 判断每个分开字符长度
if '-' in self.command[i]:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断每个分开字符长度
elif len(self.command[i]) != 7:
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# 判断读入的点是否能转换为数字
elif self.command[i][0].isdigit() == 0 or self.command[i][2].isdigit() == 0 or self.command[i][4].isdigit() == 0 or self.command[i][6].isdigit() == 0:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
# 判断读入的点是否合法
elif int(self.command[i][0]) < 0 or int(self.command[i][2]) < 0 or int(self.command[i][4]) < 0 or int(self.command[i][6]) < 0:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断读入的点是否超出范围
elif int(self.command[i][0]) >= row or int(self.command[i][4]) >= row or int(self.command[i][2]) >= col or int(self.command[i][6]) >= col:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断读入数据格式是否正确
elif self.command[i][1] != ',' and self.command[i][5] != ',':
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# 判断读入数据格式是否正确
elif self.command[i][3] != ' ':
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# step2: 迷宫渲染为字符串
x = abs(int(self.command[i][0]) - int(self.command[i][4]))
y = abs(int(self.command[i][2]) - int(self.command[i][6]))
# 判断读入点是否连通
if (x + y) > 1:
print('\033[5;31m' + 'Mazeformat error.' + ' \033[0m')
quit()
# 连通的是同一个点跳过
if (x + y) == 0:
break
if x == 0:
result[int(self.command[i][0]) * 2 + 1][min(int(self.command[i][2]), int(self.command[i][6])) * 2 + 2] = '[R]'
else:
result[min(int(self.command[i][0]), int(self.command[i][4])) * 2 + 2][int(self.command[i][2]) * 2 + 1] = '[R]'
return result
# 矩阵形式打印最终迷宫字符串
def showResult(self,result):
"""
输入:
result: 渲染后的迷宫字符串二维列表
输出:
矩阵形式打印出结果
"""
# 如果添加颜色,代码如下:
for i in range(len(result)):
count = 0 # 用于计数
for j in result[i]:
if j == '[R]':
print('\033[5;31m' + j + ' \033[0m', end='') # 将"[R]"标记为红色
count += 1
else:
print(j, end=' ')
count += 1
if (count % len(result[0]) == 0): # 换行判断
print(end='\n')
# 如果不添加颜色,代码如下:
# for i in range(len(result)):
# print(" ".join(str(j) for j in result[i]))
# 判断迷宫道路网格的尺寸的输入是否合法
def judge_num(num):
index = False
if len(num) == 2:
# 判断读入行列数是否为数字
if str(num[0]).lstrip('-').isdigit() == 1 and str(num[1]).lstrip('-').isdigit() == 1:
index = True
return index
def dataInput_byHand():
"""
输入:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,(3行3列),即num = [3,3]
command:迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2当多个连通,则以分号;隔开
输出:
num, command
"""
# step1: 输入迷宫的行列数,中间用空格隔开
while True:
num = [int(i) for i in input().split()]
# 判断输入数据是否合法
if judge_num(num):
break
else:
num = [i for i in input().split()]
if judge_num(num):
break
# step2: command的输入
command = list(input().split(';'))
return num,command
def dataInput_withFile():
# 请选择5种不同的待测试的文件
data = list(open('data/data_正确输入.txt').read().split('\n')) # 正确输入
# data = list(open('data/data_Incorrect command format.txt').read().split('\n')) # 格式错误
# data = list(open('data/data_Invalid number format.txt').read().split('\n')) # 无效的数字
# data = list(open('data/data_Mazeformat error.txt').read().split('\n')) # 连通性错误
# data = list(open('data/data_Number out of range.txt').read().split('\n')) # 数字超出预定范围
num = [i for i in data[0].split()]
command = list(data[1].split(';'))
# 判断num的输入是否存在错误!
if len(num) != 2:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
else:
# 判断读入行列数是否为数字
if num[0].lstrip('-').isdigit() == 0 or num[1].lstrip('-').isdigit() == 0:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
else:
num = [int(i) for i in num]
return num, command
# 主函数
if __name__ == "__main__":
# step1: 数据输入
# num, command = dataInput_byHand() # 手动输入测试数据
num, command = dataInput_withFile() # 直接加载5种txt格式的测试数据
# step2: 调用函数
maze = Maze(num, command) # 定义类maze
initial_Result = maze.initial_maze() # 初始化迷宫
final_Result = maze.getFinalMaze(initial_Result) # 迷宫渲染为字符串
# step3: 输出结果
maze.showResult(final_Result) # 矩阵形式打印最终迷宫字符串
三、福利——手撕代码(添加的两个功能)
1、题目内容
2、代码实现
尽管知道自己已经挂了,但还是想实现以下,内心还是有点不甘。代码本身不难,就是4连通区域的分析,双重循环判断,当时我错在了Python中二维列表赋值,result与tmp,因为需要判断,这会改变其中一个二维列表中的值,另一个二维列表也会变化!面试过程中调试知道有这个问题,没能及时找到合适的解决方案。详细可以参考博客:Python中的赋值、浅拷贝与深拷贝。现在我更改代码后结果如下:
新增功能后的代码如下(完整版,未优化封装,没过实在是没心情再封装咯):
# !/usr/bin/python3.5.2
# -*- coding: UTF-8 -*-
import copy
# 计算机生成迷宫,再渲染为字符串
class Maze:
def __init__(self, num, command):
"""
初始化:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
command: 迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号;隔开。
"""
self.num = num
self.command = command
# 初始化迷宫&道路网格
def initial_maze(self):
"""
输入:
self.num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
输出:
result: 初始的迷宫
"""
row, col = self.num[0], self.num[1] # 获取行数,列数
result = [['[W]']*(2*col+1) for index in range(2*row+1)] # 初始化迷宫
for i in range (row):
for j in range(col):
result[2*i+1][2*j+1] = '[R]'# 初始化输出
return result
# 迷宫渲染为字符串
def getFinalMaze(self, result):
"""
输入:
self.num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,而5 x 4的迷宫为5 4(5行4列)
self.command: 迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2,多个连通以分号;隔开。
result: 初始的迷宫
输出:
result: 渲染后的迷宫,即根据self.command联通信息渲染后的迷宫
"""
row, col = self.num[0], self.num[1] # 获取行数,列数
# step1: 判断迷宫道路网格的连通性定义输入是否合法
if row < 0 or col < 0:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit() # 判断行列数是否合法
for i in range(len(self.command)): # 进入循环
# 判断每个分开字符长度
if '-' in self.command[i]:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断每个分开字符长度
elif len(self.command[i]) != 7:
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# 判断读入的点是否能转换为数字
elif self.command[i][0].isdigit() == 0 or self.command[i][2].isdigit() == 0 or self.command[i][4].isdigit() == 0 or self.command[i][6].isdigit() == 0:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
# 判断读入的点是否合法
elif int(self.command[i][0]) < 0 or int(self.command[i][2]) < 0 or int(self.command[i][4]) < 0 or int(self.command[i][6]) < 0:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断读入的点是否超出范围
elif int(self.command[i][0]) >= row or int(self.command[i][4]) >= row or int(self.command[i][2]) >= col or int(self.command[i][6]) >= col:
print('\033[5;31m' + 'Number out of range.' + ' \033[0m')
quit()
# 判断读入数据格式是否正确
elif self.command[i][1] != ',' and self.command[i][5] != ',':
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# 判断读入数据格式是否正确
elif self.command[i][3] != ' ':
print('\033[5;31m' + 'Incorrect command format.' + ' \033[0m')
quit()
# step2: 迷宫渲染为字符串
x = abs(int(self.command[i][0]) - int(self.command[i][4]))
y = abs(int(self.command[i][2]) - int(self.command[i][6]))
# 判断读入点是否连通
if (x + y) > 1:
print('\033[5;31m' + 'Mazeformat error.' + ' \033[0m')
quit()
# 连通的是同一个点跳过
if (x + y) == 0:
break
if x == 0:
result[int(self.command[i][0]) * 2 + 1][min(int(self.command[i][2]), int(self.command[i][6])) * 2 + 2] = '[R]'
else:
result[min(int(self.command[i][0]), int(self.command[i][4])) * 2 + 2][int(self.command[i][2]) * 2 + 1] = '[R]'
return result
# 矩阵形式打印最终迷宫字符串
def showResult(self,result):
"""
输入:
result: 渲染后的迷宫字符串二维列表
输出:
矩阵形式打印出结果
"""
# 如果添加颜色,代码如下:
for i in range(len(result)):
count = 0 # 用于计数
for j in result[i]:
# 迷宫的判断1
if j != '[W]' and j != '[T]': # j == '[R]'
print('\033[5;31m' + j + ' \033[0m', end='') # 将"[R]"标记为红色
count += 1
elif j == '[T]':
print('\033[1;32m' + j + ' \033[0m', end='') # 将"[R]"标记为红色
count += 1
else:
print(j, end=' ')
count += 1
if (count % len(result[0]) == 0): # 换行判断
print(end='\n')
# 如果不添加颜色,代码如下:
# for i in range(len(result)):
# print(" ".join(str(j) for j in result[i]))
# 判断迷宫道路网格的尺寸的输入是否合法
def judge_num(num):
index = False
if len(num) == 2:
# 判断读入行列数是否为数字
if str(num[0]).lstrip('-').isdigit() == 1 and str(num[1]).lstrip('-').isdigit() == 1:
index = True
return index
def dataInput_byHand():
"""
输入:
num: 迷宫道路网格的尺寸。例如 3 x 3 的迷宫为3 3,(3行3列),即num = [3,3]
command:迷宫道路网格的连通性定义。如果cell(0,1)和cell(0,2) 是连通的,则表示为:0,1 0,2当多个连通,则以分号;隔开
输出:
num, command
"""
# step1: 输入迷宫的行列数,中间用空格隔开
while True:
num = [int(i) for i in input().split()]
# 判断输入数据是否合法
if judge_num(num):
break
else:
num = [i for i in input().split()]
if judge_num(num):
break
# step2: command的输入
command = list(input().split(';'))
return num,command
def dataInput_withFile():
# 请选择5种不同的待测试的文件
# data = list(open('data/data_正确输入.txt').read().split('\n')) # 正确输入
# data = list(open('data/data_Incorrect command format.txt').read().split('\n')) # 格式错误
# data = list(open('data/data_Invalid number format.txt').read().split('\n')) # 无效的数字
# data = list(open('data/data_Mazeformat error.txt').read().split('\n')) # 连通性错误
# data = list(open('data/data_Number out of range.txt').read().split('\n')) # 数字超出预定范围
data = list(open('data/maze_plus2.txt').read().split('\n')) # 迷宫拐弯
num = [i for i in data[0].split()]
command = list(data[1].split(';'))
# 判断num的输入是否存在错误!
if len(num) != 2:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
else:
# 判断读入行列数是否为数字
if num[0].lstrip('-').isdigit() == 0 or num[1].lstrip('-').isdigit() == 0:
print('\033[5;31m' + 'Invalid number format.' + ' \033[0m')
quit()
else:
num = [int(i) for i in num]
return num, command
def calNum(result,i,j):
tmp = copy.deepcopy(result) # 采用深拷贝,防止传入的值被影响
sum = 0
if tmp[i][j + 1] == '[R]':
sum += 1
if tmp[i][j - 1] == '[R]':
sum += 1
if tmp[i + 1][j] == '[R]':
sum += 1
if tmp[i - 1][j] == '[R]':
sum += 1
return sum
def get4Union(result):
row, col = len(result), len(result[0])
tmp = copy.deepcopy(result)
for i in range(1, row-1):
for j in range(1, col-1):
if tmp[i][j] == '[R]':
index = calNum(result, i, j)
if index >= 1:
tmp[i][j] = '['+str(index)+']'
return tmp
# 验收作业二
def checkPoint(result, i, j):
tmp = copy.deepcopy(result)
index = False
if tmp[i][j + 1] == '[W]' and tmp[i + 1][j] == '[W]' and tmp[i - 1][j] != '[W]' and tmp[i][j - 1] != '[W]': # 右下为[W]
index = True
if tmp[i][j + 1] == '[W]' and tmp[i + 1][j] != '[W]' and tmp[i - 1][j] == '[W]' and tmp[i][j - 1] != '[W]': # 右上为[W]
index = True
if tmp[i][j + 1] != '[W]' and tmp[i + 1][j] == '[W]' and tmp[i - 1][j] != '[W]' and tmp[i][j - 1] == '[W]': # 左下为[W]
index = True
if tmp[i][j + 1] != '[W]' and tmp[i + 1][j] != '[W]' and tmp[i - 1][j] == '[W]' and tmp[i][j - 1] == '[W]': # 左上为[W]
index = True
return index
def setTower(result):
row, col = len(result), len(result[0])
tmp = copy.deepcopy(result)
for i in range(1, row-1):
for j in range(1, col-1):
if tmp[i][j] == '[W]' and checkPoint(result, i, j):
tmp[i][j] = '[T]'
return tmp
# 主函数
if __name__ == "__main__":
# step1: 数据输入
# num, command = dataInput_byHand() # 手动输入测试数据
num, command = dataInput_withFile() # 直接加载5种txt格式的测试数据
# step2: 调用函数
maze = Maze(num, command) # 定义类maze
initial_Result = maze.initial_maze() # 初始化迷宫
final_Result = maze.getFinalMaze(initial_Result) # 迷宫渲染为字符串
print("\n第一步:原始结果为:\n")
print(final_Result)
# step3: 输出结果
print("\n第二步:个性化输出结果:\n")
maze.showResult(final_Result) # 矩阵形式打印最终迷宫字符串
###################### 题目二 ######################
print("\n第三步:输出结果1(4连通区域分析):\n")
myres1 = get4Union(final_Result)
maze.showResult(myres1)
print("\n第四步:输出结果2(拐点分析):\n")
myres2 = setTower(myres1)
maze.showResult(myres2)
3、在面试的前一晚,看了一些面经:http://www.job592.com/pay/comms81356.html,看到一篇文章中写到,面试追加的题目为,设计一个机器人去行走这个迷宫,并给出其动态变化。这个功能函数代码如下:
################################ 走迷宫 ####################################
# 矩阵处理
def matrix01(result):
row, col = len(result), len(result[0])
if row==0:
quit()
elif row>0:
for i in range(row):
for j in range(col):
if result[i][j]=='[W]':
result[i][j] = 0
elif result[i][j]=='[R]':
result[i][j] = 1
return result
# 用来判断坐标是否合法
def check_valid(mg, x, y):
if x >= 0 and x < len(mg) and y >= 0 and y < len(mg[0]) and mg[x][y] == 1:
return True
else:
return False
# 迷宫结果优化
def process(step):
# 先识别哪些无路可走的点的下一个点
change_records = []
for i in range(len(step) - 1):
if (abs(step[i][0] - step[i + 1][0]) == 0 and abs(step[i][1] - step[i + 1][1]) == 1) or \
(abs(step[i][0] - step[i + 1][0]) == 1 and abs(step[i][1] - step[i + 1][1]) == 0):
pass
else:
change_records.append(i + 1)
# 然后根据这些点识别出这个点的最远回退点
clip_nums = []
for i in change_records:
for j in range(i):
if (abs(step[j][0] - step[i][0]) == 0 and abs(step[j][1] - step[i][1]) == 1) or \
(abs(step[j][0] - step[i][0]) == 1 and abs(step[j][1] - step[i][1]) == 0):
break
clip_nums.append((j, i))
# 注意回退点之间的包含关系, 逆序处理, 是为了规避顺序对列表进行处理后下标偏移的问题
record = []
for i in clip_nums[::-1]:
if not (i[0] in record or i[1] in record):
step = step[:i[0] + 1] + step[i[1]:]
record += list(range(i[0], i[1]))
print(step)
step = []
def walk(mg, x, y):
global step
if x == 1 and y == 1:
step.append((x, y))
mg[x][y] = 2
# process(step)
print(step)
print("Walk success!")
print(mg)
quit()
if check_valid(mg, x, y):
step.append((x, y))
mg[x][y] = 2
walk(mg, x, y + 1)
walk(mg, x, y - 1)
walk(mg, x - 1, y)
walk(mg, x + 1, y)
主函数部分:
#step4 迷宫求解(假设出口为(1,1),入口自己设定)
print("\n第三步:迷宫如何求解:\n")
mg = matrix01(final_Result)
walk(mg, 5, 5) # 表示出发点为(5,5),终点为(1,1)
运行结果:
可惜啊,准备得再充分,临时变题,世事难料。