1. 数组

编程入门 行业动态 更新时间:2024-10-10 00:22:29

1. <a href=https://www.elefans.com/category/jswz/34/1771288.html style=数组"/>

1. 数组


前言

我在leetcode上刷了一些算法和学习了c++语法后,经常对c++中的一些基础操作不太熟练,如链表的插入、删除、遍历二叉树等,这些操作对我来说应该熟记于心,滚瓜烂熟。


一、数组的定义及相关操作

1.数组是一块连续的内存,并按照顺序存储数据,创建数组时,需要先指定数组的容量大小,在根据大小分配内存,因为需要先进行内存的分配,所以数据的空间利用率不高,经常有空闲的区域。
2.数组可以看成是一个哈希表,其下标为Key,下表对应的数据为Value,可以使用时间复杂度O(1)进行查找
3.C++中的STL中的vector,就是一个动态数组,vector和普通数组的区别是,vector是动态分配内存的,每次扩充内存,是前一次的两倍

1.1 数组的声明

数组的声明需要指定数据类型和元素数量
类型 名称 [ 元素数量 ];
double balance [10];

1.2 数组的初始化

double balance[5] = {10.0, 5, 5.0, 2.0, 3.0}

1.3 vector——c++中的特殊数组(比数组好用的数组)

vector不光数组的大小是可以灵活设置的,还有很多相关的函数可以使用

vector的定义: vector<int> vector_name

size():返回向量中元素的个数。
push_back(value):将一个元素添加到向量的末尾。
pop_back():删除向量末尾的元素。
insert(position, value):在指定位置插入一个元素。
erase(position):删除指定位置的元素。
clear():删除向量中的所有元素。
empty():检查向量是否为空,返回一个布尔值。
front():返回向量中第一个元素的引用。
back():返回向量中最后一个元素的引用。
at(index):返回指定索引位置的元素的引用,带有边界检查。
resize(new_size):改变向量的大小,可以增加或减少元素的数量。
reserve(new_capacity):改变向量的容量,实际上并不改变向量的大小。
swap(other_vector):交换两个向量的内容。
begin() 和 end():返回指向向量首元素和尾后元素的迭代器。

1.3 题目1:返回数组中重复的数字(力扣442题)

题目描述:给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 。请你找出所有出现 两次 的整数,并以数组形式返回。

1.3.1 完成代码1——原地哈希

时间复杂度o(n),空间复杂度o(1)

#include<iostream>
#include<string>
#include <vector>
using namespace std;
vector <int> find_fuc(vector<int> &nums)
{int nums_len = nums.size();int n = nums_len;vector<int> ret;for (auto &num : nums){int x = (num - 1) % nums_len;nums[x] += nums_len;}while (n-- > 0){if (nums[n] > 2 * nums_len) ret.push_back(n);return ret;
}
void test1()
{//vector<int> nums = { 10,2,8,9,10,10,10,7,3,2,5 ,7};vector<int> nums = {};int nums_len = nums.size();vector<int> results = find_fuc(nums);cout << "重复的数据为:";for (const auto& result : results){cout << (result+1) % nums_len << " ";}
}
int main()
{test1();return 0;
}
1.3.1.1代码中相关命令的学习
  1. auto:auto是关键字,可以自动推导数据类型,好处是简化代码,提高代码的可读性
    auto num = 10;
    auto name = “zzy”

  2. const auto& result : results
    这段代码中声明了result变量,该变量每次从results中引用一个值,使用 & 的目的是不对results进行拷贝,直接使用,可以节省空间。使用const关键字的目的是只能读取result的值,不能进行修改,保证代码的健壮性。

  3. for (const auto& result : results)
    这里的 for(int result:results),是一种范围基本循环,results可以是数组、向量、列表等容器,每次将容器中的内容传输到result。

  4. ret.push_back(n)
    每次向ret向量中的尾部传入一个值

1.3.2完成代码二——哈希表

时间复杂度o(n),空间复杂度o(n)
创建一个动态数组当作哈希表

#include<iostream>
#include<string>
#include <vector>
using namespace std;vector <int> find_fuc(vector<int> &nums)
{int nums_len = nums.size();int n = 0;int* countings = new int[nums_len]();//int countings[nums_len] = {0};vector<int> ret;for (int &num : nums){int x = num - 1;countings[x] += 1;}for(int i = 0; i < nums_len; i++){n++;if (countings[i] >= 2) ret.push_back(n);//	cout << n <<":"<< nums[n]<< endl;}delete[] countings;return ret;
}void test1()
{
//	vector<int> nums = { 10,2,8,9,10,10,10,7,3,2,5 ,7};vector<int> nums = {1,1,1,1,1,5,5,3,1,5,3,4,5,6,9,9};int nums_len = nums.size();vector<int> results = find_fuc(nums);cout << "重复的数据为:";for (const auto& result : results){cout << result % nums_len << " ";}
}int main()
{test1();return 0;
}
1.3.2.1代码内容学习

上述代码,我在运行时出现了一些问题

问题1:

定义数组时出错,报错原因时数组定义时,nums_len是一个变量导致的,而数组的空间大小,是需要在编译的时候就定义好的

相关代码:	int countings[nums_len] = {0};

解决方法,设置一个动态数组

动态数组的设置命令 int* countings = new int[nums_len]();

使用动态数组的时候要注意,使用完成后一定要手动释放空间,不然会造成内存泄漏

释放空间命令 delete[] countings;

在这里,出现的c++内存分配的情况,在大型项目中,需要合理的分配内存的使用情况,而堆(heap)时由开发人员手动进行分配和释放的,在使用时非常灵活,所以一些大型数据或对象中,经常使用堆的方式来创建

使用new在堆上创建对象的几种方式

创建单个对象:		MyClass* obj = new MyClass;
创建对象数组:		MyClass* objArray = new MyClass[5];
创建对象并初始化:	MyClass* obj = new MyClass(42);

使用delete释放内存的方式:

释放对象:	  delete obj;
释放对象数组: delete[] objArray;
问题2:

无法使用范围-based for 循环传递数据,也就是这种形式:for (const auto& counting : countings)
因为countings是针类型,不是数组、容器、列表、字符串的形式,所以不能用

1.4多维数组

多维数组的定义:type name[size1][size2][size3];
定义一个整型的二维数组:int threedim[2][2] = {{1,2},{4,5}}

1.4.1 题目:二维数组中的查找

在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的个二维数组和一个整数,判断数组中是否含有该整数。

#include<iostream>
#include<string>
#include <vector>
using namespace std;
bool Find(int* matrix, int rows, int columns, int number)
{bool found = false;if (matrix != nullptr && rows > 0 && columns > 0){int row = 0;int column = columns - 1;while (row < rows && column >= 0){//cout << "matrix[row * columns + column]:" << matrix[] << endl;if (matrix[row * columns + column] == number){found = true;break;}else if (matrix[row * columns + column] > number)--column;else++row;}}return found;
}
void Test1()
{int matrix[][4] = { {1, 2, 8, 9}, {2, 4, 9, 12}, {4, 7, 10, 13}, {6, 8, 11, 15} };cout << Find((int*)matrix, 4, 4, 16) << endl;
}int main()
{Test1();return 0;
}
1.4.1.1 代码中遇到的问题

1.如果输入的二维数组是空的,那么在判断的时候就需要设置空指针的判断

判断空指针:if (matrix != nullptr)

这里的nullptr常用于初始化空类型的指针

2.为什么Find函数中可以使用 if (matrix[row * columns + column] == number)来判断二位数组对应位置是否等于指定数,而在find函数外部,matix[nums]输出的却是地址?

这是因为Find(int* matrix, int rows, int columns, int number)输入的二维数组的指针,也就是首地址,所以在Find函数内部输出martix[num]输出的是int类型的值,而Find函数外部,使用martix[num]输出的是二维数组中的num行的首地址。

更多推荐

1. 数组

本文发布于:2023-12-06 23:44:55,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1669387.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数组

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!