当前位置: 首页 > news >正文

力扣 岛屿数量-200

岛屿数量-200

class Solution {//深度优先搜索 dfs
public:int vis[300][300] = {0};//用于标记的数组,标记是否遍历过int cnt = 0;//岛屿计数//上下左右的移动方向数组int dx[4]={-1,1,0,0};int dy[4]={0,0,-1,1};//深度优先搜索void dfs(vector<vector<char>>& grid,int x,int y){for(int i=0;i<4;i++){int bx = x+dx[i];int by = y+dy[i];//检查边界if(bx<0||bx>=grid.size()||by<0||by>=grid[0].size())continue;//检查是否被标记过(已经遍历过),当前位置的值是否为1,被标记过或者值为1就跳过if(vis[bx][by]||grid[bx][by]!='1')continue;//标记当前点为已经访问vis[bx][by]=1;//递归搜索相邻的格子dfs(grid,bx,by);}}int numIslands(vector<vector<char>>& grid) {//遍历数组for(int i=0;i<grid.size();i++){for(int j=0;j<grid[0].size();j++){//如果没有被标记过(为0),并且值为'1'if(!vis[i][j]&&grid[i][j]=='1'){//岛屿计数加1cnt++;//当前元素标记为1表示已经访问过vis[i][j]=1;//深度优先搜索dfs(grid,i,j);}}}return cnt;}
};

每日问题

右值引用和移动语义

右值引用和移动语义

在 C++11 中,引入了 右值引用 和 移动语义 这两个重要概念,它们主要用于优化性能,减少不必要的资源拷贝,尤其是在处理大对象时。理解这两个概念有助于写出更加高效的 C++ 代码。

1. 右值和左值

在讨论右值引用之前,我们需要先理解 左值 和 右值 的区别:

  • 左值 (Lvalue):指代内存中的某个位置,有持久性的,可以对其取地址。
    • 示例:变量、数组元素、解引用的指针等。
    • 例如:int a = 10; 中的 a 是左值。
  • 右值 (Rvalue):临时的、没有持久性的数据,不能取地址。通常是表达式计算的结果、常量、临时对象等。
    • 示例:a + b 或 func() 返回的临时对象。
    • 例如:int x = a + b; 中的 a + b 是右值。

左值 和 右值 的区分在 C++11 中变得更加重要,特别是在涉及到 右值引用 和 移动语义 时。

2. 右值引用(&&)

右值引用(&&)是 C++11 引入的新特性,它用于捕获 右值。与传统的 左值引用(&) 不同,右值引用是用来绑定 右值 的,目的是为了解决不必要的拷贝操作和资源的浪费。

右值引用的特点:

  • 右值引用只能绑定 右值,而不能绑定左值。
  • 右值引用使得对象的资源(如内存、文件句柄等)能够被 转移(move),而不是复制(拷贝)。

右值引用的声明:

int&& r = 5;  // 5 是右值,r 是右值引用

3. 移动语义

移动语义 允许资源从一个对象 转移(move) 到另一个对象,而不是复制资源。这通过右值引用实现,避免了昂贵的深拷贝操作,特别是在处理大型对象(如 std::vector、std::string)时,大大提高了性能。

关键概念:

  • 移动构造函数:一个特殊的构造函数,它接收一个右值引用,并转移(而不是复制)其资源。
  • 移动赋值运算符:与移动构造函数类似,它接收一个右值引用并转移资源。

例子:移动构造函数和移动赋值运算符

考虑一个自定义的类 MyClass,它管理一个动态分配的数组。我们希望能够利用 移动语义 来避免不必要的资源拷贝。

#include <iostream>
#include <cstring>class MyClass {
private:char* data;public:// 普通构造函数MyClass(const char* str) {data = new char[strlen(str) + 1];strcpy(data, str);std::cout << "Constructing: " << data << std::endl;}// 移动构造函数MyClass(MyClass&& other) noexcept {data = other.data;          // 转移所有权other.data = nullptr;       // 使其他对象处于有效的空状态std::cout << "Moving: " << data << std::endl;}// 移动赋值运算符MyClass& operator=(MyClass&& other) noexcept {if (this != &other) {delete[] data;         // 删除原来的资源data = other.data;     // 转移所有权other.data = nullptr;  // 使其他对象处于有效的空状态}std::cout << "Move Assigning: " << data << std::endl;return *this;}// 析构函数~MyClass() {delete[] data;std::cout << "Destructing: " << (data ? data : "nullptr") << std::endl;}void print() const {std::cout << "Data: " << data << std::endl;}
};int main() {MyClass obj1("Hello, World!");    // 使用普通构造函数MyClass obj2 = std::move(obj1);   // 使用移动构造函数obj2.print();                      // 输出 obj2 的数据// obj1 不再持有有效数据,因为它的资源已被转移obj1.print();                      // 输出 obj1 的数据(null)MyClass obj3("Temporary");obj3 = std::move(obj2);           // 使用移动赋值运算符return 0;
}

输出:

Constructing: Hello, World!
Moving: Hello, World!
Data: Hello, World!
Destructing: nullptr
Move Assigning: Hello, World!
Destructing: Temporary
Destructing: Hello, World!

4. 为什么使用移动语义?

移动语义的主要优点在于,它允许将资源的所有权从一个对象转移到另一个对象,而不是进行昂贵的复制操作。

性能优化:

在没有移动语义的情况下,当一个对象被复制时,通常需要执行深拷贝操作,这可能会消耗大量时间,尤其是对于包含大量数据的对象(如 std::vector、std::string)。但是使用移动语义,数据的所有权被直接转移,避免了复制操作,从而提高了性能。

使用场景:

  • 当一个对象的生命周期短,并且不再需要它时,可以将它的资源转移到另一个对象中。
  • 当你返回一个临时对象时,移动语义能避免不必要的复制。

5. 右值引用与常规引用的区别

  • 左值引用 (&):可以绑定到 左值,引用已经存在的对象。不能绑定到临时对象或常量。
  • 右值引用 (&&):只能绑定到 右值,即临时对象、表达式的结果等。允许资源的转移,避免了深拷贝。

举个例子:

int a = 10;
int& lref = a;     // 左值引用,绑定到左值 a
int&& rref = 20;   // 右值引用,绑定到右值 20

6. 总结

  • 右值引用 (&&) 允许我们捕获和操作 右值,为 移动语义 提供支持。
  • 移动语义 允许我们将对象的资源从一个对象转移到另一个对象,避免了不必要的拷贝,从而提高了程序的性能。
  • 移动构造函数 和 移动赋值运算符 是支持移动语义的核心,它们通过转移对象的资源来避免复制操作。

通过右值引用和移动语义,我们能够写出更高效、性能更好的 C++ 代码,尤其是在处理大型数据结构和容器时。

自动类型推导(auto 和 decltype)

自动类型推导:auto 和 decltype

在 C++ 中,auto 和 decltype 都是与类型推导相关的关键字,它们帮助程序员简化代码,避免手动指定冗长或复杂的类型。

1. auto 关键字

        auto 是 C++11 引入的关键字,用来自动推导变量的类型。编译器根据变量的初始化表达式来推导变量的类型。

基本用法:

auto x = 10;        // x 的类型是 int
auto y = 3.14;      // y 的类型是 double
auto z = "hello";   // z 的类型是 const char*

用于函数返回类型:

auto 也可以用于函数的返回类型,特别是当返回类型较为复杂时,或者返回值的类型依赖于某些表达式的计算结果。

auto add(int a, int b) {return a + b;  // 返回值的类型自动推导为 int
}

用于迭代器:

auto 在使用 STL 容器时特别有用,避免了繁琐的类型声明,尤其是迭代器类型的声明。

#include <vector>std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {std::cout << *it << " ";  // 自动推导 it 的类型
}

2. decltype 关键字

decltype 是 C++11 引入的另一个关键字,它的作用是查询表达式的类型。decltype 不会计算表达式的值,只会返回该表达式的类型。

基本用法:

int x = 10;
decltype(x) y = 20;  // y 的类型与 x 相同,都是 intdouble z = 3.14;
decltype(z) w = 2.71;  // w 的类型是 double

用于推导函数返回类型:

有时候,函数的返回类型可能很复杂(如模板函数),这时可以用 decltype 来推导返回类型,而无需手动指定。

template<typename T, typename U>
auto multiply(T a, U b) -> decltype(a * b) {return a * b;  // 返回值的类型是 a * b 的类型
}

3. auto 和 decltype 的区别

auto:用于变量声明时,编译器根据初始化表达式来推导类型。适用于你知道变量的初始值,但不想显式写出类型时。

        自动推导类型,适用于变量声明。

        如果初始化表达式返回引用或常量,auto 会丢弃引用或常量。

decltype:用于获取任何表达式的类型,无论是否为引用、常量、指针等。适用于你想要查询某个表达式类型或返回类型时。

        获取表达式的类型,不对类型进行推导。

        如果表达式是一个引用类型,decltype 会保留这个引用。

举例说明两者的区别:

int x = 10;
int& ref = x;// auto 会推导为 int,因为初始化值是 `x`
auto a = x;      // a 的类型是 int// decltype 会保留引用类型
decltype(ref) b = x;  // b 的类型是 int&

4. 使用场景和最佳实践

使用 auto:

        适用于复杂类型的变量声明,尤其是当类型很长或难以确定时。

        减少代码重复和冗长,特别是在模板编程中。

        迭代器类型、返回类型等都可以通过 auto 自动推导。

示例:

std::vector<int>::iterator it = vec.begin();
auto it2 = vec.begin();  // 自动推导类型

使用 decltype:

        当你需要保持某个变量的类型,特别是引用类型时,decltype 是非常有用的。

        用于函数返回类型推导,或者在模板编程中获取表达式类型。

示例:

decltype(x + y) result = x + y;  // result 的类型与 x + y 相同

5. 组合使用:auto 和 decltype

这两个关键字可以结合使用,尤其是在模板编程或复杂类型的情况中非常有用。

示例:

template <typename T>
auto sum(T a, T b) -> decltype(a + b) {return a + b;
}

在这里,auto 用于返回类型,decltype 用于推导 a + b 的类型。

总结

        auto 关键字用于变量声明时自动推导类型,简化代码,尤其在复杂类型或迭代器类型中非常有用。

        decltype 用于查询表达式的类型,保持原始类型信息,适用于需要精确控制类型的场景。

        auto 和 decltype 经常一起使用,帮助简化和增强代码的可读性与灵活性。

相关文章:

力扣 岛屿数量-200

岛屿数量-200 class Solution {//深度优先搜索 dfs public:int vis[300][300] {0};//用于标记的数组&#xff0c;标记是否遍历过int cnt 0;//岛屿计数//上下左右的移动方向数组int dx[4]{-1,1,0,0};int dy[4]{0,0,-1,1};//深度优先搜索void dfs(vector<vector<char>…...

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【三】

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料&#xff1a; 极狐GitLab 官网极狐…...

十二、正则表达式、元字符、替换修饰符、手势和对话框插件、字符串截取

1. 正则表达式 1.1 基本使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&g…...

【信息系统项目管理师】第3章:信息系统治理 考点梳理

文章目录 3.1 IT 治理3.1.1 IT治理基础3.1.2 IT治理体系3.1.3 IT治理任务3.1.4 IT治理方法与标准 3.2 IT 审计3.2.1 IT审计基础3.2.2 审计方法与技术3.2.3 审计流程3.2.4 审计内容 3.1 IT 治理 IT治理起到重要的统筹、评估、指导和监督作用。 信息技术审计(IT审计)作为与IT治…...

实现对图片或者视频增加隐藏水印和提取水印

好久好久没有写博客了&#xff0c;最近看见一个很有意思的文章&#xff1a;小心你的电脑被窃听&#xff0c;就是说在一些公司&#xff0c;截图都会存在水印&#xff0c;方便溯源&#xff0c;然后出于技术的好奇&#xff0c;我在github上搜了一下&#xff0c;还真有相关的github…...

uniapp配置全局消息提醒

1.H5使用根标签插入dom的方式实现。 2.app端使用plus.nativeObj.View的方式绘制实现 H5端app端 H5端 创建组件orderAlert.vue <template><div class"view"><div class"content" v-if"visible"><div class"message&q…...

卸载snap docker一直卡住:Save data of snap “docker“ in automatic snapshot set #3

在卸载 Snap 安装的 Docker 时卡住&#xff0c;通常是因为 Snap 在执行卸载时会先尝试保存一些快照&#xff08;自动或手动创建的&#xff09;&#xff0c;并且该过程可能因某些原因而卡住。为了解决这个问题&#xff0c;你可以按照以下步骤强制删除 Snap 安装的 Docker&#x…...

python学习——字典元素的访问和遍历

在Python中&#xff0c;访问和遍历字典元素的方法如下&#xff1a; 文章目录 访问字典元素1. 使用键来访问值2. 使用 get() 方法 遍历字典元素1. 遍历字典的键2. 遍历字典的值3. 遍历字典的键和值4. 使用列表推导式来创建新的列表 实操 访问字典元素 1. 使用键来访问值 # 创…...

数据结构基础之《(9)—归并排序》

一、什么是归并排序 1、整体是递归&#xff0c;左边排好序右边排好序merge让整体有序 2、让其整体有序的过程里用了排外序方法 3、利用master公式来求解时间复杂度 4、当然可以用非递归实现 二、归并排序说明 1、首先有一个f函数 void f(arr, L, R) 说明&#xff1a;在arr上…...

【深度学习】各种卷积—卷积、反卷积、空洞卷积、可分离卷积、分组卷积

在全连接神经网络中&#xff0c;每个神经元都和上一层的所有神经元彼此连接&#xff0c;这会导致网络的参数量非常大&#xff0c;难以实现复杂数据的处理。为了改善这种情况&#xff0c;卷积神经网络应运而生。 一、卷积 在信号处理中&#xff0c;卷积被定义为一个函数经过翻转…...

远程视频验证如何改变商业安全

如今&#xff0c;商业企业面临着无数的安全挑战。尽管企业的形态和规模各不相同——从餐厅、店面和办公楼到工业地产和购物中心——但诸如入室盗窃、盗窃、破坏和人身攻击等威胁让安全主管时刻保持警惕。 虽然传统的监控摄像头网络帮助组织扩大了其态势感知能力&#xff0c;但…...

电脑启动需要经历哪些过程?

传统BIOS启动流程 1. BIOS BIOS 启动&#xff0c;BIOS程序是烧进主板自带的ROM里的&#xff0c;所以无硬盘也可以启动。BIOS先进行自检&#xff0c;检查内存、显卡、磁盘等关键设备是否存在功能异常&#xff0c;会有蜂鸣器汇报错误&#xff0c;无错误自检飞快结束。 硬件自检…...

纯Go语言开发人脸检测、瞳孔/眼睛定位与面部特征检测插件-助力GoFly快速开发框架

前言​ 开发纯go插件的原因是因为目前 Go 生态系统中几乎所有现有的人脸检测解决方案都是纯粹绑定到一些 C/C 库&#xff0c;如 ​​OpenCV​​ 或 ​​​dlib​​​&#xff0c;但通过 ​​​cgo​​​ 调用 C 程序会引入巨大的延迟&#xff0c;并在性能方面产生显著的权衡。…...

postman使用正则表达式提取数据实战篇!

之前篇章中postman多接口关联使用的是通过JSON提取器的方式进行提取。 除了JSON提取器提取数据外还可通过另一种方式——正则表达式来提取数据。 1、使用正则表达式提取器实现接口关联&#xff0c;match匹配 正则匹配表达式将需要提取的字段key:value都放入表达式中&#xff…...

ipmitool使用详解(三)-解决各种dell、hp服务器无法ipmitool连接问题

报错 [root@localhost ~]# ipmitool -H 10.1.2.41 -I lan -U admin -P "password123" lan print 1 Get Session Challenge command failed Error: Unable to establish LAN session Error: Unable to establish IPMI v1.5 / RMCP session [root@localhost ~]# ipmit…...

AWS EC2设置用户名密码登录

使用AWS EC2 设置用户名密码登录 步骤 1: 访问控制台 登录到AWS管理控制台。导航至 EC2 Dashboard。在左侧导航栏中选择 Instances。选择需要配置的实例。使用 EC2 Instance Connect 访问实例控制台。 步骤 2: 切换到 root 用户 打开终端或命令行工具&#xff0c;通过SSH连…...

BurpSuite安装教程(详细!!附带下载链接)

声明 学习内容来自 B 站UP主泷羽sec&#xff0c;如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识&#xff0c;以下网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 ✍&#x1f3fb;作者简介&#xff1a;致…...

MIPS寄存器文件设计实验

今天写MIPS寄存器文件设计实验&#xff0c;同时复习一下MIPS这块地方 实验要求&#xff1a; 一、寄存器的作用 想象一下&#xff0c;你正在厨房准备做一顿大餐。你需要用到各种食材和工具&#xff0c;比如刀、锅、砧板&#xff0c;还有食材本身&#xff0c;比如肉、菜、调料等…...

uniapp使用扩展组件uni-data-select出现的问题汇总

前言 不知道大家有没有学习过我的这门课程那&#xff0c;《uniCloud云开发Vue3版本官方推荐用法》&#xff0c;这么课程已经得到了官方推荐&#xff0c;想要快速上手unicloud的小伙伴们&#xff0c;可以学习一下这么课程哦&#xff0c;不要忘了给一键三连呀。 在录制这门课程…...

反向代理模块开发

1 概念 1.1 反向代理概念 反向代理是指以代理服务器来接收客户端的请求&#xff0c;然后将请求转发给内部网络上的服务器&#xff0c;将从服务器上得到的结果返回给客户端&#xff0c;此时代理服务器对外表现为一个反向代理服务器。 对于客户端来说&#xff0c;反向代理就相当于…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

Debian系统简介

目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版&#xff…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...