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

泰安建网站青岛网站建设公司排名

泰安建网站,青岛网站建设公司排名,艺术设计与制作,阿里巴巴外贸平台费用岛屿数量-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>…

岛屿数量-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 经常一起使用,帮助简化和增强代码的可读性与灵活性。

http://www.jinmujx.cn/news/112793.html

相关文章:

  • 中山网站建设方案手机推广软文
  • 什么网站可以做旅行行程郑州网站托管
  • 朔州市网站建设seo关键词推广话术
  • 手机 上传 Wordpress东莞seo建站哪家好
  • 自己做个网站怎么做网络网站推广
  • 一个ip做几个网站网店推广软文范例
  • 微信朋友圈做网站推广赚钱吗网站推广的工作内容
  • 用框架做网站如何居中seo推广技术培训
  • 无锡网站设计公司排名seo基础
  • app如何推广以及推广渠道上海优化公司有哪些
  • 五泉山网页设计宣传网站制作美国最新消息今天 新闻
  • wordpress邮件群发seo排名技术软件
  • yy头像在线制作网站今日刚刚发生的新闻
  • 海报在线设计网站长春网站快速优化排名
  • 奇趣网做网站杭州网站seo公司
  • 随州公司做网站企业推广托管
  • 临安做企业网站的公司百度有钱花人工客服
  • 上海网站公司排名公众号推广接单平台
  • 厦门品牌网站设计网络平台有哪些?
  • 网站开发是什么意思啊宁波营销型网站建设优化建站
  • 网店设计模板免费seo关键词是什么
  • 如何设立网站武汉网站制作
  • 泉州网站外包南昌seo外包公司
  • 受欢迎的网站建设公司系统优化app最新版
  • 没有照片怎么做网站电商seo名词解释
  • 党风廉洁建设网站产品50个关键词
  • 江西有色建设集团公司 网站百度软件
  • 百度搜索站长平台女生学电子商务好吗
  • 制作网站404页面国际新闻快报
  • 微信公众号做视频网站百度咨询电话 人工