卡码网--数组篇(二分法)

系列文章目录


文章目录

  • 系列文章目录
  • 前言
  • 数组
  • 二分查找


前言

详情看:https://programmercarl.com/ 总结知识点用于复习


数组

概念: 数组是存放在连续内存空间上的相同类型数据的集合。

数组可以方便的通过下标索引的方式获取到下标对应的数据。

特点

  1. 数组下标都是从0开始的。
  2. 数组内存空间的地址是连续的。
  3. 数组的元素是不能删的,只能覆盖。
  4. 二维数组在内存的空间地址是连续的。

正是因为数组在内存空间的地址是连续的,所以我们在删除或者增添元素的时候,就难免要移动其他元素的地址。

测试代码

#include <iostream>  
using namespace std;  void test_arr() {int array[2][3] = {{0, 1, 2},{3, 4, 5}};cout << &array[0][0] << " " << &array[0][1] << " " << &array[0][2] << endl;cout << &array[1][0] << " " << &array[1][1] << " " << &array[1][2] << endl;
}int main() {test_arr();
}

0x7ffc80278450 0x7ffc80278454 0x7ffc80278458
0x7ffc8027845c 0x7ffc80278460 0x7ffc80278464

打印出来,可以发现都相差4个字节。 60-5c=4 因为是十六进制 c是12 16-12=4
int类型四个字节。在C++中二维数组是连续分布的。

基础知识:
在C++中,数组是一种基本的数据结构,用于存储相同类型的数据元素。以下是数组的基础操作,包括定义、赋值和调用:

1. 定义数组
数组可以在声明时初始化,也可以先声明后赋值。
声明时初始化

int arr[5] = {1, 2, 3, 4, 5};
#先声明后赋值
int arr[5];  
arr[0] = 1;  
arr[1] = 2;  
arr[2] = 3;  
arr[3] = 4;  
arr[4] = 5;

2. 访问数组元素
使用索引来访问数组元素,索引从0开始。

int value = arr[0]; // 访问第一个元素

3. 修改数组元素
通过索引修改数组中的元素。

arr[0] = 10; // 修改第一个元素的值

4. 数组的大小
数组的大小在声明时就固定了,不能改变。可以使用sizeof运算符来获取数组的总大小(以字节为单位),或者使用sizeof(数组名) / sizeof(数组类型)来获取数组的元素个数。

int size = sizeof(arr) / sizeof(arr[0]); // 获取数组的元素个数

5. 遍历数组
使用循环结构遍历数组中的每个元素。

for (int i = 0; i < 5; i++) {  cout << arr[i] << " ";  
}

6. 数组作为函数参数
当数组作为函数参数时,实际上传递的是数组的指针。

void printArray(int arr[], int size) {  for (int i = 0; i < size; i++) {  cout << arr[i] << " ";  }  cout << endl;  
}

7. 多维数组
C++也支持多维数组,例如二维数组。

int matrix[3][3] = {  {1, 2, 3},  {4, 5, 6},  {7, 8, 9}  
};

访问二维数组的元素:

int value = matrix[0][1]; // 访问第一行第二列的元素

在C++中,字符串数组是一种用于存储多个字符串的数据结构。与基本数据类型数组类似,字符串数组也支持定义、赋值和调用等操作,但需要注意的是,字符串在C++中通常通过std::string类型来表示,或者在某些情况下使用字符数组(以空字符\0结尾)来表示。以下是关于字符串数组在C++中的基础操作:

  1. 定义字符串数组
    使用std::string类型:
    这是C++标准库中提供的字符串类型,使用它定义字符串数组非常直接。
#include <iostream>  
#include <string>  
using namespace std;  int main() {  string arr[5]; // 定义了一个可以存储5个std::string对象的数组  // ...  
}

也可以直接在定义时初始化:

string arr[5] = {"Apple", "Banana", "Cherry", "Date", "Elderberry"};

使用字符数组:
在C++中,你也可以使用字符数组(以\0结尾的字符序列)来模拟字符串数组。但这种方式更加底层,且操作起来相对复杂。

char str_array[3][20] = {"Hello", "world", "!"}; // 定义了一个二维字符数组,模拟字符串数组
  1. 赋值
    使用std::string类型:可以直接使用赋值运算符=给std::string类型的数组元素赋值。
arr[0] = "New Apple"; // 将"New Apple"赋值给arr的第一个元素

使用字符数组:对于字符数组,你不能直接对整个数组进行赋值,但可以使用strcpy等函数来复制字符串。不过,在模拟字符串数组时(即二维字符数组),你通常是在初始化时就已经设定好了字符串内容。

  1. 调用
    使用std::string类型:直接通过索引访问数组元素即可。
cout << arr[0] << endl; // 输出arr的第一个元素

使用字符数组:同样,通过索引访问二维数组的元素来引用字符串。

cout << str_array[0] << endl; // 输出第一个字符串"Hello"

注意,这里输出时不需要显式地指定字符串的结束位置,因为C++会根据\0自动判断字符串的结束。

4. 遍历
对于字符串数组(无论是std::string类型还是字符数组模拟的),你都可以使用循环结构来遍历数组中的每个字符串。

使用std::string类型:

for (int i = 0; i < 5; i++) {  cout << arr[i] << endl;  
}

使用字符数组:
遍历二维字符数组时,外层循环控制行(即不同的字符串),内层循环(如果需要的话)控制列(但在这种情况下,内层循环通常不需要,因为你是以整个行作为字符串来处理的)。

for (int i = 0; i < 3; i++) {  cout << str_array[i] << endl; // 直接输出整行,即一个字符串  
}

二分查找

力扣链接 704. 二分查找:https://leetcode.cn/problems/binary-search/description/

在这里插入图片描述
Step1: 读题 可以提炼出 1. 数组是升序的 2. 无重复元素 这两个条件是二分法的前提。
Step2: 二分法确定左右区间。

定义数组区间为[left,right]即左闭右闭。target属于[left,right]的话,left==right就是有意义的。则判断条件时while(left<=right)是有意义的。

if (nums[middle] > target) right 要赋值为 middle - 1。


class Solution {
public:int search(vector<int>& nums, int target) {int left = 0;int right = nums.size() - 1; // 定义target在左闭右闭的区间里,[left, right]while (left <= right) { // 当left==right,区间[left, right]依然有效,所以用 <=int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2if (nums[middle] > target) {right = middle - 1; // target 在左区间,所以[left, middle - 1]} else if (nums[middle] < target) {left = middle + 1; // target 在右区间,所以[middle + 1, right]} else { // nums[middle] == targetreturn middle; // 数组中找到目标值,直接返回下标}}// 未找到目标值return -1;}
};

一、基本概念
vector是C++标准模板库(STL)中的一个模板类,用于表示可以动态增长的数组。
它可以存储具有相同类型的数据项,这些数据项在内存中连续存储,因此可以通过下标快速访问。
二、特性
动态数组:vector在内部使用动态分配数组来存储元素,当元素数量超过当前容量时,vector会自动重新分配一个更大的数组,并将现有元素复制过去。
连续存储:与静态数组类似,vector中的元素在内存中也是连续存储的,这使得它可以通过指针算术来高效访问元素。
随机访问:由于vector中的元素是连续存储的,因此它支持随机访问迭代器,可以通过下标直接访问任意元素。
高效尾部操作:在vector的末尾添加或删除元素是非常高效的,因为这些操作不会导致内存重新分配(除非需要增加容量)。
内存管理:vector提供了reserve()和resize()成员函数来手动管理其容量和大小。reserve()用于增加容器的容量,而resize()用于改变容器的大小。
三、基本操作
定义与初始化:
可以使用默认构造函数来创建一个空的vector。std::vector vec; // 创建一个空的int类型vector
可以使用初始化列表来创建一个包含特定元素的vector。

std::vector<int> vec = {1, 2, 3, 4, 5}; // 创建一个包含5个整数的vector

可以使用另一个vector的范围来创建一个新的vector。

std::vector<int> originalVec = {1, 2, 3, 4, 5};  
std::vector<int> newVec(originalVec.begin(), originalVec.end()); // 使用originalVec的范围来创建newVec

元素访问:
可以使用下标运算符[]来访问vector中的元素。
可以使用at()成员函数来访问元素,该函数会进行范围检查。
插入与删除:
提供了push_back()成员函数来在vector的末尾添加一个元素。
提供了pop_back()成员函数来删除vector的最后一个元素。
提供了insert()和erase()成员函数来在vector的任意位置插入或删除元素。
遍历:
可以使用范围for循环来遍历vector中的元素。
可以使用迭代器来遍历vector,包括正向迭代器和反向迭代器。
容量与大小:
提供了size()成员函数来获取vector中元素的数量。
提供了capacity()成员函数来获取vector的容量。
提供了empty()成员函数来检查vector是否为空。

#include <iostream>  
#include <vector>  int main() {  // 创建一个空的vector  std::vector<int> vec;  // 向vector中添加元素  vec.push_back(1);  vec.push_back(2);  vec.push_back(3);  // 遍历vector并打印元素  for (int i = 0; i < vec.size(); ++i) {  std::cout << vec[i] << " ";  }  std::cout << std::endl;  // 使用范围for循环遍历vector并打印元素  for (auto& x : vec) {  std::cout << x << " ";  }  std::cout << std::endl;  // 删除vector的最后一个元素  vec.pop_back();  // 再次遍历vector并打印元素  for (auto& x : vec) {  std::cout << x << " ";  }  std::cout << std::endl;  return 0;  
}

Python 代码

class Solution:def search(self, nums: List[int], target: int) -> int:left, right = 0, len(nums) - 1  # 定义target在左闭右闭的区间里,[left, right]while left <= right:middle = left + (right - left) // 2if nums[middle] > target:right = middle - 1  # target在左区间,所以[left, middle - 1]elif nums[middle] < target:left = middle + 1  # target在右区间,所以[middle + 1, right]else:return middle  # 数组中找到目标值,直接返回下标return -1 

这里注意middle定义要在while循环里面,还有python整除用//。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/390602.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓基本布局(下)

TableLayout 常用属性描述collapseColumns设置需要被隐藏的列的列号。shrinkColumns设置允许被伸缩的列的列号。stretchColumns设置允许被拉伸的列的列号。 <TableLayout xmlns:android"http://schemas.android.com/apk/res/android"android:id"id/TableL…

状体管理-装饰器

State 自己的状态 注意:不是状态变量的所有更改都会引起刷新。只有可以被框架观察到的修改才会引起UI刷新。 1、boolean、string、number类型时&#xff0c;可以观察到数值的变化。 2、class或者Object时&#xff0c;可以观察 自身的赋值 的变化&#xff0c;第一层属性赋值的变…

CC++:贪吃蛇小游戏教程

❀创作不易&#xff0c;关注作者不迷路❀&#x1f600;&#x1f600; 目录 &#x1f600;贪吃蛇简介 &#x1f603;贪吃蛇的实现 &#x1f40d;生成地图 &#x1f40d;生成蛇模块 ❀定义蛇的结构体 ❀初始化蛇的相关信息 ❀初始化食物的相关信息 &#x1f40d;光标定位和…

[Spring] SpringBoot统一功能处理与图书管理系统

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏: &#x1f9ca; Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection与…

USB 2.0 规范摘录

文章目录 1、USB 体系简介2、USB 数据流模型四种传输类型 3、USB 物理规范和电气规范4、USB 协议层规范事务传输&#xff08;Transaction&#xff09;的流程 5、USB 框架6、USB 主机&#xff1a;硬件和软件7、USB HUB 规范数据的转发唤醒信号的转发USB HUB 的帧同步HUB Repeate…

前端常见场景、JS计算精度丢失问题(Decimal.js 介绍)

目录 一. Decimal.js 介绍 二. 常用方法 1. 创建 Decimal 实例 2.加法 add 或 plus 3.减法 sub 或 minus 4.乘法 times 或 mul 5.除法 div 或 dividedBy 6.取模 7.幂运算 8.平方根 9.保留小数位 toFixed方法(四舍五入) 三.项目应用 前端精度丢失问题通常由以下原因…

【Kubernetes】kubeadmu快速部署k8s集群

目录 一.组件部署 二.环境初始化 三.所有节点部署docker&#xff0c;以及指定版本的kubeadm 四.所有节点安装kubeadm&#xff0c;kubelet和kubectl 五.高可用配置 六.部署K8S集群 1.master01 节点操作 2.master02、master03节点 3.master01 节点 4.master02、master…

C语言 ——— 学习、使用 strcmp函数 并模拟实现

目录 strcmp函数的功能 学习strcmp函数​编辑 使用strcmp函数 模拟实现strcmp函数 strcmp函数的功能 strcmp函数的功能是字符串比较&#xff0c;两个字符串的对应位置的字符进行比较&#xff0c;直到字符不同或达到终止的 \0 字符为止 举例说明&#xff1a; 字符串1&am…

leetcode-二叉树oj题1(共三道)--c语言

目录 a. 二叉树的概念以及实现参照博客&#xff1a; 一、三道题的oj链接 二、每题讲解 1.单值二叉树 a. 题目&#xff1a; b. 题目所给代码 c. 思路 d. 代码&#xff1a; 2. 相同的树 a. 题目 b. 题目所给代码 c. 思路 d. 代码 3. 二叉树的前序遍历 a. 题目 b.…

前端-05-VSCode自定义代码片段console.log(js/ts配置)、代码段快捷提示放在首位

目录 配置VSCode自定义代码片段console.log()log代码段快捷提示放在首位 配置VSCode自定义代码片段console.log() 点击VSCode左下角设置图标&#xff0c;点击用户代码片段 点击用户代码片段后&#xff0c;VSCode上方出现弹窗如下图&#xff08;没有显示这两个文件的话搜索一下…

Redis结合Lua脚本的简单使用

我们就拿购物车举例子 现在有5个东西免费送&#xff0c;我们只能选择1个 例如 可乐 美年达 香蕉 苹果 薯片 我们选择后就放进redis里面 然后我们不能选重复&#xff0c;只能选不同 Lua脚本 我们redis使用lua脚本的时候&#xff0c;会传两个参数进去 一个是List<Strin…

MySQL:数据库权限与角色

权限 MySQL 的权限管理系统是保障数据库安全性的关键组件之一。它允许数据库管理员精确控制哪些用户可以对哪些数据库对象执行哪些操作。 自主存取控制 DAC&#xff08;DiscretionaryAccess Control)&#xff1a;用户对于不同的数据库对象有不同的存取权限&#xff0c;不同的…

fatal: Could not read from remote repository. 解决方法

问题描述&#xff1a; Git : fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists。 解决方法&#xff1a; 当在网上尝试大量方法仍然失败的时候&#xff0c;不妨试试这个方法。 在 github 上&…

thinkphp框架远程代码执行

一、环境 vulfocus网上自行下载 启动命令&#xff1a; docker run -d --privileged -p 8081:80 -v /var/run/docker.sock:/var/run/docker.sock -e VUL_IP192.168.131.144 8e55f85571c8 一定添加--privileged不然只能拉取环境首页不显示 二、thinkphp远程代码执行 首页&a…

鸿蒙媒体开发【拼图】拍照和图片

拼图 介绍 该示例通过ohos.multimedia.image和ohos.file.photoAccessHelper接口实现获取图片&#xff0c;以及图片裁剪分割的功能。 效果预览 使用说明&#xff1a; 使用预置相机拍照后启动应用&#xff0c;应用首页会读取设备内的图片文件并展示获取到的第一个图片&#x…

2024关于日本AI 领域TOP12 的大学介绍

1.东京大学 &#xff08;The University of Tokyo&#xff09; 位于&#xff1a;日本东京都文京区本郷七丁目3 番1 号 网址&#xff1a;東京大学 东京大学也被称为UTokyo 或东大&#xff0c;是日本第一所国立大学。作为领先的研究型 大学&#xff0c;东京大学提供基本所有…

8月17日|广州|Cocos开发者沙龙不见不散!

6月底举行的Cocos成都沙龙吸引了近200位开发者和10多家发行&#xff0c;得到了大家的一致好评。 Cocos广州沙龙即将到来&#xff0c;会邀请更多KOL和头部发行、渠道嘉宾分享行业经验&#xff0c;让大家实现技术干货、游戏合作、行业信息多丰收。 活动主题&#xff1a;小游戏与出…

vscode+git解决远程分支合并冲突

1&#xff09;远程分支和远程分支不复杂情况合并 例如readme的冲突 可直接在github上解决 删到只剩下 #supergenius002 合并冲突测试1/合并测试冲突1合并测试冲突2/合并测试冲突2就行 《《《/》》》也要删掉 2&#xff09;但如果是复杂的冲突&#xff0c;让我们回到vscod…

C++进阶:设计模式___适配器模式

前言 在C的基础语法的学习后,更进一步为应用场景多写代码.其中设计模式是有较大应用空间. 引入 原本在写容器中适配器类有关的帖子,发现适配模式需要先了解,于是试着先写篇和适配器模式相关的帖子 理解什么是适配器类,需要知道什么是适配器模式.适配器模式是设计模式的一种.笔…

剪画小程序:致敬奥运举重冠军:照片变成动漫风格!

在巴黎奥运会的赛场上&#xff0c;那些奥运冠军们的身影如同璀璨星辰&#xff0c;闪耀着无尽的光芒&#xff01; 看&#xff0c;举重冠军力拔山兮气盖世&#xff0c;那坚定的眼神中透露出无畏的勇气&#xff0c;爆发的力量更是震撼人心。 借助剪画&#xff0c;将这令人心潮澎湃…