C++结合Lambda表达式在函数内部实现递归

这篇具有很好参考价值的文章主要介绍了C++结合Lambda表达式在函数内部实现递归。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

529. 扫雷游戏

已解答

中等

相关标签

相关企业

让我们一起来玩扫雷游戏!

给你一个大小为 m x n 二维字符矩阵 board ,表示扫雷游戏的盘面,其中:

  • 'M' 代表一个 未挖出的 地雷,
  • 'E' 代表一个 未挖出的 空方块,
  • 'B' 代表没有相邻(上,下,左,右,和所有4个对角线)地雷的 已挖出的 空白方块,
  • 数字'1' 到 '8')表示有多少地雷与这块 已挖出的 方块相邻,
  • 'X' 则表示一个 已挖出的 地雷。

给你一个整数数组 click ,其中 click = [clickr, clickc] 表示在所有 未挖出的 方块('M' 或者 'E')中的下一个点击位置(clickr 是行下标,clickc 是列下标)。

根据以下规则,返回相应位置被点击后对应的盘面:

  1. 如果一个地雷('M')被挖出,游戏就结束了- 把它改为 'X' 。
  2. 如果一个 没有相邻地雷 的空方块('E')被挖出,修改它为('B'),并且所有和其相邻的 未挖出 方块都应该被递归地揭露。
  3. 如果一个 至少与一个地雷相邻 的空方块('E')被挖出,修改它为数字('1' 到 '8' ),表示相邻地雷的数量。
  4. 如果在此次点击中,若无更多方块可被揭露,则返回盘面。

示例 1:

C++结合Lambda表达式在函数内部实现递归,C/C++编程序笔记,c++,leetcode,算法

输入:board = [["E","E","E","E","E"],["E","E","M","E","E"],["E","E","E","E","E"],["E","E","E","E","E"]], click = [3,0]
输出:[["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]

示例 2:

C++结合Lambda表达式在函数内部实现递归,C/C++编程序笔记,c++,leetcode,算法

输入:board = [["B","1","E","1","B"],["B","1","M","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]], click = [1,2]
输出:[["B","1","E","1","B"],["B","1","X","1","B"],["B","1","1","1","B"],["B","B","B","B","B"]]

提示:

  • m == board.length
  • n == board[i].length
  • 1 <= m, n <= 50
  • board[i][j] 为 'M''E''B' 或数字 '1' 到 '8' 中的一个
  • click.length == 2
  • 0 <= clickr < m
  • 0 <= clickc < n
  • board[clickr][clickc] 为 'M' 或 'E'

这是一道leetcode上面的题目,题目本身不难,只需要改变一次状态就行了。改变状态中需要确定点击的是什么内容,如果是空白则需要递归找到所有的空白。

先用AI先了一个python版本:

class Solution:
    def updateBoard(self, board: List[List[str]], click: List[int]) -> List[List[str]]:
        directions = [(-1, 0), (1, 0), (0, -1), (0, 1), (-1, -1), (-1, 1), (1, -1), (1, 1)]  # 相邻方向

        def count_mines(r, c):
            count = 0
            for dr, dc in directions:
                nr, nc = r + dr, c + dc
                if 0 <= nr < len(board) and 0 <= nc < len(board[0]) and board[nr][nc] == 'M':
                    count += 1
            return count

        def reveal(r, c):
            if board[r][c] == 'E':
                mines_count = count_mines(r, c)
                if mines_count == 0:
                    board[r][c] = 'B'
                    for dr, dc in directions:
                        nr, nc = r + dr, c + dc
                        if 0 <= nr < len(board) and 0 <= nc < len(board[0]):
                            reveal(nr, nc)
                else:
                    board[r][c] = str(mines_count)

        click_r, click_c = click
        if board[click_r][click_c] == 'M':
            board[click_r][click_c] = 'X'
        else:
            reveal(click_r, click_c)

        return board

 python果然更加现代,函数里面可以定义函数。想着将python改写为C++实现,C++虽然无法在函数内部实现函数,但是有lamda表达式,于是写出来下面的版本:

#include <vector>
#include <string>

using namespace std;

class Solution {
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        int directions[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; // 相邻方向

        auto countMines = [&](int r, int c) -> int {
            int count = 0;
            for (auto& dir : directions) {
                int nr = r + dir[0], nc = c + dir[1];
                if (nr >= 0 && nr < board.size() && nc >= 0 && nc < board[0].size() && board[nr][nc] == 'M') {
                    ++count;
                }
            }
            return count;
        };

        auto revealFunc = [&](int r, int c) {
            if (board[r][c] == 'E') {
                int minesCount = countMines(r, c);
                if (minesCount == 0) {
                    board[r][c] = 'B';
                    for (auto& dir : directions) {
                        int nr = r + dir[0], nc = c + dir[1];
                        if (nr >= 0 && nr < board.size() && nc >= 0 && nc < board[0].size()) {
                            revealFunc(nr, nc);
                        }
                    }
                } else {
                    board[r][c] = '0' + minesCount;
                }
            }
        };

        int click_r = click[0], click_c = click[1];
        if (board[click_r][click_c] == 'M') {
            board[click_r][click_c] = 'X';
        } else {
            revealFunc(click_r, click_c);
        }

        return board;
    }
};

啊,编译报错了。

 error: variable 'revealFunc' declared with deduced type 'auto' cannot appear in its own initializer
   23 |                             revealFunc(nr, nc);
      |                             ^
1 error generated.
还是不行,不能递归调用。

在C++中,Lambda表达式不能直接递归调用自身,因为它的类型是在声明时确定的,而在递归调用时,Lambda表达式的类型还没有完全确定。
为了解决这个问题,你可以将Lambda表达式存储在一个std::function对象中,这样就可以在递归调用中使用它了。std::function是一个可以存储任何可调用对象的通用容器,只要其签名与std::function的模板参数匹配即可。

正确版本:

class Solution {
public:
    vector<vector<char>> updateBoard(vector<vector<char>>& board, vector<int>& click) {
        int directions[8][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}}; // 相邻方向
        auto countMines = [&](int r, int c) -> int {
            int count = 0;
            for (auto& dir : directions) {
                int nr = r + dir[0], nc = c + dir[1];
                if (nr >= 0 && nr < board.size() && nc >= 0 && nc < board[0].size() && board[nr][nc] == 'M') {
                    ++count;
                }
            }
            return count;
        };
        std::function<void(int, int)> revealFunc;
        revealFunc = [&](int r, int c) {
            if (board[r][c] == 'E') {
                int minesCount = countMines(r, c);
                if (minesCount == 0) {
                    board[r][c] = 'B';
                    for (auto& dir : directions) {
                        int nr = r + dir[0], nc = c + dir[1];
                        if (nr >= 0 && nr < board.size() && nc >= 0 && nc < board[0].size()) {
                            revealFunc(nr, nc);
                        }
                    }
                } else {
                    board[r][c] = '0' + minesCount;
                }
            }
        };
        int click_r = click[0], click_c = click[1];
        if (board[click_r][click_c] == 'M') {
            board[click_r][click_c] = 'X';
        } else {
            revealFunc(click_r, click_c);
        }
        return board;
    }
};

执行用时分布

10ms

击败97.79%使用 C++ 的用户

消耗内存分布

15.11MB

击败15.20%使用 C++ 的用户

C++感觉需要重新学习了。。。文章来源地址https://www.toymoban.com/news/detail-831656.html

到了这里,关于C++结合Lambda表达式在函数内部实现递归的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Lambda表达式和匿名内部类的区别

    匿名内部类:可以是接口,也可以是抽象类,还可以是具体类 Lambda表达式:只能是接口 如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类 如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式 匿名内部类:编译之后,产

    2024年02月10日
    浏览(48)
  • 探索Python中的函数式编程:Lambda表达式与函数式工具【第135篇—Lambda表达式】

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 在Python编程世界中,函数式编程逐渐成为了一种流行的范式,特别是在处理数据和编写简洁、高效代码时。函数式编程的核心思想是将计算视

    2024年04月08日
    浏览(83)
  • C++ 中的Lambda表达式

    Lambda 表达式 (lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是 一个匿名函数,即没有函数名的函数 。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。 闭包 就是能够读取其他函数内部变量

    2024年02月09日
    浏览(48)
  • 【C++】 Lambda表达式详解

    描述 记得去年立了一个重学C++新特性的flag,可是真的太忙了,大部分精力都花在全栈上了,今年开始看一些开源源码,发现各种奇怪的语法,根本看不懂, 不学不行 了。而且接触了很多语言后,发现新特性的确能 提高开发效率 ,所以还是重新学习下C++吧。 环境 版本号 描

    2024年02月08日
    浏览(56)
  • C++ 11 Lambda表达式

    https://www.cnblogs.com/DswCnblog/p/5629165.html C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多高级语言在很早以前就已经提供了Lambda表达式的功

    2024年02月10日
    浏览(49)
  • Lambda表达式内部访问的局部变量必须是final or effectively final 为什么

    在Java中,Lambda表达式内部访问的局部变量必须是final或者事实上的final。这是因为Lambda表达式实际上是一个闭包,它包含了对其外部的变量的引用,而这些变量在Lambda表达式执行期间不能被修改,否则会导致线程安全问题。 在Java中,final表示一个变量被赋值之后不能再

    2024年02月13日
    浏览(33)
  • 【C++】STL 算法 - transform 变换算法 ② ( 变换规则为 普通函数 | 变换规则为 Lambda 表达式 | 变换规则为 函数对象 | 变换规则为 函数适配器转换的函数对象 )

    transform 算法函数原型 : 下面的函数原型作用是 将 一个输入容器 中的元素 变换后 存储到 输出容器 中 ; 参数解析 : InputIt first1 参数 : 输入容器 的 起始迭代器 ( 包含 ) ; InputIt last1 参数 : 输入容器 的 终止迭代器 ( 不包含 ) ; OutputIt d_first 参数 : 输出容器 的 开始迭代器 , 输出元

    2024年01月21日
    浏览(48)
  • 【C++】Lambda表达式的使用

    例如: 了解Lambda的优点 掌握Lambda表达式的使用 了解Lambda表达式的底层原理 Lambda表达式的语法 lambda表达式的底层实现涉及到闭包(Closure)的概念。闭包是一个函数对象,它可以捕获外部作用域中的变量,并在其生命周期内访问和修改这些变量。lambda表达式的底层实现就是通

    2024年02月14日
    浏览(43)
  • C++复习笔记--Lambda表达式

    ① [] 用于捕获变量,一般用于使用和修改外部的变量,可以为空; ② (int a, int b) 表示参数列表,可以省略; ③ - int 定义返回类型,一般可以省略,让编译器自动推断; ④ auto f 表示将定义的 lambda 表达式赋值给对象 f,auto 用于自动推断类型; 基本用法如下: ① 使用和修

    2024年02月16日
    浏览(58)
  • Java 函数式编程与 Lambda 表达式

    2023年10月31日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包