刚入职一周的同事提交了一个新增 2w和删减1.4w的代码,不想review代码,头大~

科技   2024-12-15 16:19   陕西  

今天看到一个挺有意思的网友吐槽:刚入职一周的同事提交了一个新增2万行、删减1.4万行的代码,要求做Code Review。

结果他表示:“我真的头大,不想review了!”作为一个程序员,我不得不说,这种事情真的很让人头疼。


首先,2万行的新增代码,基本可以理解为“半个新模块”了。如果没有明确的文档或注释,review的时候几乎就是在“盲人摸象”。哪怕代码写得再好,能不能理解、能不能维护,都是问题。

而删减1.4万行代码更让人抓狂,删掉的部分会不会影响到其他功能?哪些是冗余的,哪些是意外删除的?这些都需要小心谨慎地检查。

我深知新人刚入职的时候,有时候就是会“过度热情”,要不然怎么在上班的第一周就提交如此“大作”呢?如果是我,会建议同事们给新人更多指导,尽量避免这种一刀切式的提交。

对新人来说,代码质量比数量重要,逐步积累经验更能提高工作效率。

你们怎么看呢?

算法题:解数独

今天我们来聊聊解数独的算法,作为程序员,数独这类题目你可能已经见怪不怪了,但如果你真的用程序来解它,那就有些意思了。

数独问题的核心就是在一个 9x9 的网格中填充数字,规则很简单:每一行、每一列以及每个 3x3 的子宫格都必须包含 1 到 9 的数字,而且不能重复。听起来简单,但你要用程序去解,难度可就大了。别着急,咱们一步步来。

首先,我知道你脑海中可能会出现“暴力破解”这个词。嗯,确实,这是最直接的一种方法,就是通过遍历每一个空格,试着填入每个数字,直到所有规则都满足为止。但这种方法效率低,尤其是在数据量较大的时候,性能会很差。所以,今天咱们要讲的,是一种更加高效的回溯算法。

回溯算法怎么理解呢?可以这么想:每次填数字的时候,咱们会考虑当前数字是否符合规则,如果不符合,直接回退,换一个数字继续尝试。这就像你在解谜游戏时,推倒一块拼图发现不对劲时,再去试其他拼法一样,直到拼图完美符合。

现在,我们开始动手了。先来看一下数独的解法:

def solve_sudoku(board):
    def is_valid(board, row, col, num):
        # 检查行
        for i in range(9):
            if board[row][i] == num:
                return False
        # 检查列
        for i in range(9):
            if board[i][col] == num:
                return False
        # 检查3x3子宫格
        start_row, start_col = 3 * (row // 3), 3 * (col // 3)
        for i in range(start_row, start_row + 3):
            for j in range(start_col, start_col + 3):
                if board[i][j] == num:
                    return False
        return True

    def solve(board):
        for i in range(9):
            for j in range(9):
                if board[i][j] == 0:  # 找到一个空格
                    for num in range(110):
                        if is_valid(board, i, j, num):  # 如果数字符合规则
                            board[i][j] = num  # 填入数字
                            if solve(board):  # 递归继续填
                                return True
                            board[i][j] = 0  # 如果填错了,就回退
                    return False  # 如果所有数字都试过了,返回False
        return True  # 如果整个板子都填满了,返回True

    solve(board)
    return board

这段代码首先定义了一个 is_valid 函数,用来判断某个数字能否放在某个位置上。它分别检查了数字是否已经在当前行、列或3x3子宫格中出现。如果没有出现,就说明这个数字可以填上。接着在 solve 函数中,我们遍历每一个空格,尝试填入数字 1 到 9,并递归调用 solve 继续尝试。如果发现填入某个数字后无法继续填下去,就回退,换一个数字。

其实,回溯算法最大的特点就是不断尝试和回退。它的效率虽然比暴力破解强,但当数据量增大时,还是会遇到一些性能瓶颈。毕竟,9x9的数独虽然不是特别大,但算法的执行过程其实是有很多可能的分支。

不过,别急!我们可以对回溯做一些优化。比如,如果我们使用“最小候选数策略”,即优先填充空格数最少的单元格,这样可以在某些情况下更早地找出错误并回退,从而减少不必要的递归。可以通过预处理来统计每个空格可填的数字数量。

这里有个优化后的代码示例:

def solve_sudoku(board):
    def is_valid(board, row, col, num):
        for i in range(9):
            if board[row][i] == num or board[i][col] == num:
                return False
        start_row, start_col = 3 * (row // 3), 3 * (col // 3)
        for i in range(start_row, start_row + 3):
            for j in range(start_col, start_col + 3):
                if board[i][j] == num:
                    return False
        return True

    def find_empty(board):
        empty_cells = []
        for i in range(9):
            for j in range(9):
                if board[i][j] == 0:
                    empty_cells.append((i, j))
        return empty_cells

    def solve(board):
        empty_cells = find_empty(board)
        if not empty_cells:
            return True
        # 优先选择最少候选数的空格
        i, j = min(empty_cells, key=lambda cell: len(get_candidates(board, *cell)))
        for num in range(110):
            if is_valid(board, i, j, num):
                board[i][j] = num
                if solve(board):
                    return True
                board[i][j] = 0
        return False

    def get_candidates(board, row, col):
        candidates = set(range(110))
        for i in range(9):
            candidates.discard(board[row][i])
            candidates.discard(board[i][col])
        start_row, start_col = 3 * (row // 3), 3 * (col // 3)
        for i in range(start_row, start_row + 3):
            for j in range(start_col, start_col + 3):
                candidates.discard(board[i][j])
        return candidates

    solve(board)
    return board

这里我们在 solve 函数中加入了一个 find_empty 函数,它会先找到所有空格,并通过 min 函数结合 get_candidates 来选择可选数字最少的空格。这样,在大多数情况下可以有效减少回溯的深度。

数独问题看似简单,但要做到高效解决其实不容易。回溯算法已经是目前为止比较高效的解法了,当然如果你需要更高效的算法(比如在更大的棋盘上),那就得用到更多高级的优化技巧啦。

不过,今天就先聊到这里。希望你对解数独的算法有了更深的理解,动手试试吧!

对编程、职场感兴趣的同学,大家可以联系我微信:golang404,拉你进入“程序员交流群”。
🔥虎哥私藏精品 热门推荐🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》

资料包含了《IDEA视频教程》《最全python面试题库》《最全项目实战源码及视频》《毕业设计系统源码》,总量高达650GB全部免费领取

Python技术迷
回复:python,领取Python面试题。分享AI编程,AI工具,Python技术栈,Python教程,Python编程视频,Pycharm项目,Python爬虫,Python数据分析,Python核心技术,Python量化交易。
 最新文章