数据结构与算法2--数组常见操作

2023-11-18

数据结构与算法2--数组常见操作

 

数组是最常见也是我们使用最多的数据结构了,它是一块连续的内存空间,以下标来描述空间的位置,C++中int arr[len]表示的的数组一旦配置后大小就无法改变,vector<int> v表示的数组可以动态增加。以下是笔者根据数组的特性和平时使用情况完成的一些基本功能,后续将根据使用情况再增加相关功能。

 

1、功能

00-打印数组
01-合并两个有序的数组
02-将数组排序为最小数字
03-查找连续的子序列
04-数组中逆序对
05-求素数对
06-求数组中是否有重复的数
07-求数组中和为S的数对
08-给定数组求新数组

 

2、代码

#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;

/*
该文件夹包含array相关的各类常用功能和算法
*/

/*Menu
00-打印数组
01-合并两个有序的数组
02-将数组排序为最小数字
03-查找连续的子序列
04-数组中逆序对
05-求素数对
06-求数组中是否有重复的数
07-求数组中和为S的数对
08-给定数组求新数组
*/

void PrintArray(const int arr[],const int len);//00
void PrintArray(const vector<int> &arr);//00
void MergeSortedArray(int A[],int m,int B[],int n);//01
string PrintMinNumber(vector<int> nums);//02
vector<vector<int> > FindContinuousSequence(int sum);//03
int InversePairs1(vector<int> data);//04-1循环方法
int InversePairs2(vector<int> data);//04-2归并方法
int GetSuShuNum(int n);//05
bool IfDuplicate(vector<int> v,int &num);//06
vector<int> FindNumbersWithSum(vector<int> array,int sum);//07

//00-打印数组
void PrintArray(const int arr[],const int len)
{	
	cout<<'[';
	for(int i=0;i<len;i++)
		(i==(len-1))?(cout<<arr[i]<<']'<<endl):(cout<<arr[i]<<',');
}
void PrintArray(const vector<int> &arr)
{
	cout<<'[';
	for(int i=0;i<arr.size();i++)
		(i==(arr.size()-1))?(cout<<arr[i]<<']'<<endl):(cout<<arr[i]<<',');
}
//01-合并两个有序的数组
void MergeSortedArray(int A[],int m,int B[],int n)
{
    //合并B到A中,假设A空间足够大
	int m1 = m-1;
	int n1 = n-1;
	int s = m1+n1+1;
	while(m1>=0 && n1>=0)
	{
		if(A[m1]>=B[n1])
		{
			A[s--] = A[m1--];
		}else
		{
			A[s--] = B[n1--];
		}
	}
	if(n1>=0)
	{
		for(int i=0;i<=n1;i++)
			A[i] = B[i];
	}
}
void TestMergeSortedArray()
{
	int A[9] = {1,2,3,4,5};
	int B[4] = {2,4,6,8};
	MergeSortedArray(A,5,B,4);
	PrintArray(A,9);
}
//02-将数组排序为最小数字
bool CompareNumbers(int n1,int n2)
{
	stringstream itoa;
	itoa<<n1;
	string str1 = itoa.str();
	itoa<<n2;
	string str2 = itoa.str(); 
	if(str1<str2)
		return true;
	else
		return false;//3<=34 true;23<=345 true;13<=124 false
}
string PrintMinNumber(vector<int> nums)
{
    //例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
	string str="";
	if(nums.size()==0)
		return str;
	sort(nums.begin(),nums.end(),CompareNumbers);
	for(int i=0;i<nums.size();i++)
	{
		stringstream itoa;
		itoa<<nums[i];
		str+= itoa.str();
	} 
	return str;
}
void TestPrintMinNumber()
{
	int arr[]={3,32,321};//含0的时候应该特殊处理,当前方法会把0放在末尾,实际最好把0放在第一个数字后面
	vector<int> v(arr,arr + sizeof(arr)/sizeof(int));
	string str = PrintMinNumber(v);
	cout<<str<<endl;
}
//03-查找连续的子序列
vector<vector<int> > FindContinuousSequence(int sum) {
	//输出所有和为Sum的连续正数序列。序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序
	vector<vector<int> > vret;        
	int n = sqrt(2*sum);//n((n+1)/2= sum
	for(int i=2;i<=n;++i)	
	{
		vector<int> tmp;
		if(i&0x01)
		{
			if((sum%i)==0)
			{
				int mid = sum/i;
				int first = mid - i/2;
				for(int j=0;j<i;++j,++first)
					tmp.push_back(first);
				vret.push_back(tmp);
			}
		}else{
			if((2*(sum/i) +1)*i/2 == sum) //(2*(sum/i) +1为中间两个值之和
			{
				int first = sum/i - i/2 +1;
				for(int j=0;j<i;++j,++first)
					tmp.push_back(first);
				vret.push_back(tmp);       
			}
		}
	}
	return vret;
}
void TestFindContinuousSequence()
{
	vector<vector<int> >v;
	v = FindContinuousSequence(21);
	for(int i=0;i<v.size();i++)
		PrintArray(v[i]);
}
//04-数组中逆序对
int InversePairs1(vector<int> data) {
	long long ret = 0;
	//* 时间复杂度O(n^2)
	for(int i=0;i<data.size()-1;i++)
	{
		for(int j=i+1;j<data.size();j++)
			if(data[i]>data[j])
				ret++;
	}
	return (ret%1000000007);
}
int InversePairsCore(vector<int> &data, vector<int> &copy,int start, int end) {
	if(start==end){
		copy[start] = data[end];
		return 0;
	}
	int len = (end-start)/2;
	int left = InversePairsCore(copy,data,start,start+len);
	int right = InversePairsCore(copy,data,start+len+1,end);
	//i初始化为前半段最后一个数字的下标
	int i = start + len;
	//j初始化为后半段最后一个数字的下标
	int j = end;
	int indexCopy = end;
	int count = 0;
	while(i>=start && j>=(start+len+1))
	{
		if(data[i]>data[j])
		{
			copy[indexCopy--] = data[i--];
			count += j-start-len;
		}else
		{
			copy[indexCopy--] = data[j--];
		}
	}
	for(;i>=start;--i)
	{
		copy[indexCopy--] = data[i];
	}
	for(;j>=start+len+1;--j)
	{
		copy[indexCopy--] = data[j];
	}
	return left+right+count;
}
int InversePairs2(vector<int> data) {
	int ret = 0;
	if(data.size()==0)
		return 0;
	std::vector<int> vcopy;
	for(int i=0;i<data.size();i++)
		vcopy.push_back(data[i]);
	ret = InversePairsCore(data,vcopy,0,data.size()-1);
	vcopy.clear();
	return (ret%1000000007);
}
void TestInversePairs()
{
	//在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
	//输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
	int arr[]={1,2,3,4,5,6,7,0};
	vector<int> v(arr,arr+sizeof(arr)/sizeof(int));
	cout<<InversePairs2(v)<<endl;
}
//05-求素数对
bool IsSuShu(int n)
{
	bool ret= true;
	if(n==1)
		return false;
	for(int i=2;i<=sqrt(n);i++)
	{
		if(n%i==0)
			return false;
	}
	return ret;
}
void SumSuShu(int left,vector<int> v,int &num)
{
	if(left==0)
	{
		num++;
		return;
	}else if(left>0 && v.size()>0)
	{
		vector<int> v1 = v;
		for(int i=0;i<v.size();i++)
		{
			int tmp = v1[0];
			v1.erase(v1.begin()+0);
			SumSuShu(left-tmp,v1,num);
		}
	}else
	{
		return ;
	}
}
int GetSuShuNum(int n)
{
	//给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输入值小于1000。如,输入为10, 程序应该输出结果为2。(共有两对质数的和为10,分别为(5,5),(3,7))
	int ret = 0;
	vector<int> v;
	for(int i=1;i<=n;i++)
	{
		if(IsSuShu(i))
		{
			v.push_back(i);
		}
	}
	//使用递归查找有效数对
	PrintArray(v);
	int len = v.size();
	for(int i=0;i<len;i++)
	{
		int tmp = v[0];
		v.erase(v.begin()+0);
		SumSuShu(n-tmp,v,ret);
	}
	return ret;
}
void TestGetSuShuNum()
{
	int n = 10;
	cout<<n<<":"<<GetSuShuNum(n)<<endl;
}
//06-求数组中是否有重复的数
bool IfDuplicate(vector<int>v,int &num)
{
	//长度为n的数组v,其每个元素大小在0-n-1之间,num保存重复的数
	if(v.size()==0)
		return false;
	for(int i=0;i<v.size();i++)
	{
		if(v[i]<0 || v[i]>(v.size()-1))
			return false;
	}
	for (int i = 0; i < v.size(); ++i)
	{
		while(v[i]!=i)
		{
			if(v[i] == v[v[i]])
			{
				num = v[i];
				return true;
			}
			int tmp = v[i];
			v[i] = v[v[i]];
			v[tmp] = tmp;
		}
	}
	return false;
}
void TestIfDuplicate()
{
	int num  = 0;
	int arr[] = {1,2,3,4,5,6,7,7,8,9,9,10};
	std::vector<int> v(arr,arr+sizeof(arr)/sizeof(int));
	(IfDuplicate(v,num))?(cout<<"True\t"<<num<<endl):cout<<"False\t"<<endl;
}
//07-求数组中和为S的数对
vector<int> FindNumbersWithSum(vector<int> array,int sum)
{
	//输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,
	//如果有多对数字的和等于S,输出两个数的乘积最小的。
	vector<int> vret;
	int min = 0;
	int max = array.size()-1;
	while(min<max)
	{
		if(array[min]+array[max]==sum)
		{
			vret.push_back(array[min]);
			vret.push_back(array[max]);
			return vret;
		}
		while(min<max && (array[min]+array[max]>sum)) --max;
		while(min<max && (array[min]+array[max]<sum)) ++min;
	}
return vret;
}
void TestFindNumbersWithSum()
{
	int arr[] = {1,2,3,4,5,6,9,10,11,15,17,19,30};
	vector<int> v(arr,arr+sizeof(arr)/sizeof(int));
	std::vector<int> vret = FindNumbersWithSum(v,15);
	PrintArray(vret);
}
//08--给定数组求新数组
vector<int> multiply(const vector<int>& A) {
	//给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素
	//B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
    vector<int> v1,v2,vret;
    int ret = 1;
    int len = A.size();
    for(int i=0;i<len;i++)
    {
        if(i>0){ret = ret*A[i-1];v1.push_back(ret);}
        else v1.push_back(1);
    }
    ret = 1;
    for(int j=len-1;j>=0;--j)
    {
        if(j<len-1){ret=ret*A[j+1];v2.push_back(ret);}
        else v2.push_back(1);
    }
    for(int i=0;i<len;i++)
    {
        vret.push_back(v1[i]*v2[len-1 -i]);
    }
    return vret;
}
void TestMultiply()
{
	int arr[] = {1,2,3,4,5};
	PrintArray(arr,5);
	vector<int> v(arr,arr+sizeof(arr)/sizeof(int));
	vector<int> vret = multiply(v);
	PrintArray(vret);
}

int main()
{
//01-合并两个有序的数组
	//TestMergeSortedArray();
//02-将数组排序为最小数字
	//TestPrintMinNumber();
//03-查找连续的子序列
	//TestFindContinuousSequence();
//04-数组中逆序对
	//TestInversePairs();
//05-求素数对
	//TestGetSuShuNum();
//06-求数组中是否有重复的数
	//TestIfDuplicate();
//07-求数组中和为S的数对
	//TestFindNumbersWithSum();
//08-给定数组求新数组
	TestMultiply();
	return 0;
}

 

3、说明

当前已在mingw32(gcc 4.9.2)上测试通过。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构与算法2--数组常见操作 的相关文章

  • 如何在MVVM中管理多个窗口

    我知道有几个与此类似的问题 但我还没有找到明确的答案 我正在尝试深入研究 MVVM 并尽可能保持纯粹 但不确定如何在坚持模式的同时启动 关闭窗口 我最初的想法是向 ViewModel 发送数据绑定命令 触发代码来启动一个新视图 然后通过 X
  • 将复选框添加到 UniformGrid

    我正在尝试将复选框动态添加到 wpf 中的统一网格中 但看起来网格没有为它们分配足够的空间 所以它们都有点互相重叠 这就是我将它们添加到后面的代码中的方法 foreach string folder in subfolders PathCh
  • 访问私人成员[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 通过将类的私有成员转换为 void 指针 然后转换为结构来访问类的私有成员是否合适 我认为我无权修改包含我需要访问的数据成员的类 如果不道德 我
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • pthread_cond_timedwait() 和 pthread_cond_broadcast() 解释

    因此 我在堆栈溢出和其他资源上进行了大量搜索 但我无法理解有关上述函数的一些内容 具体来说 1 当pthread cond timedwait 因为定时器值用完而返回时 它如何自动重新获取互斥锁 互斥锁可能被锁定在其他地方 例如 在生产者
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 如何避免情绪低落?

    我有一个实现状态模式每个状态处理从事件队列获取的事件 根据State因此类有一个纯虚方法void handleEvent const Event 事件继承基础Event类 但每个事件都包含其可以是不同类型的数据 例如 int string
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用 libcurl 检查 SFTP 站点上是否存在文件

    我使用 C 和 libcurl 进行 SFTP FTPS 传输 在上传文件之前 我需要检查文件是否存在而不实际下载它 如果该文件不存在 我会遇到以下问题 set up curlhandle for the public private ke

随机推荐

  • Java对象的实例化过程

    JAVA new流程 实例化过程 java对象的实例化过程
  • 主成分分析法(三):计算步骤

    主成分分析系列 主成分分析 一 基本思想与主成分估计方法 主成分分析 二 特征值因子的筛选 主成分分析法 三 计算步骤 目录 一 主成分分析简述 二 主成分分析法的步骤 1 对原始数据进行标准化处理 2 计算相关系数矩阵R 3 计算特征值和
  • pip install总是报错:ValueError: Trusted host URL must include a host part: ‘#‘

    一 问题现象 报错信息如下 Traceback most recent call last File user name anaconda3 bin pip line 11 in
  • Matlab求解基于RRT算法的自定义垛型的路径避障

    目录 背景 1 RRT搜索算法 2 基于Matlab的RRT搜索算法 3 基于Matlab的自定义垛型绘制 4 基于RRT算法的自定义垛型的路径避障 背景 在码垛机械臂路径规划过程中 需要根据现有箱子的码垛状态 给出下一个箱子的最佳码放无碰
  • 自定义一个softirq

    本文章添加自己定义一个额外的软中断 首先添加软中断种类 MY SOFTIRQ enum HI SOFTIRQ 0 TIMER SOFTIRQ NET TX SOFTIRQ NET RX SOFTIRQ BLOCK SOFTIRQ BLOCK
  • c语言之-umask()函数

    此函数的主要作用是在创建文件时设置或者屏蔽掉文件的一些权限 一般与open 函数配合使用 umask 设置建立新文件时的权限遮罩 相关函数 creat open 表头文件 sys types h sys stat h 定义函数 mode t
  • java数据类型陷阱_java学习_3.原生数据类型使用陷阱

    原生数据类型使用陷阱 Pitfall of Primitive Data Type 1 Java中的原生数据类型共有8种 1 整型 使用int表示 32位 2 字节型 使用byte表示 表示 128 127之间的256个整数 8位 3 短整
  • 8 种流行的计算机视觉应用

    计算机视觉是人工智能的一部分 它使计算机能够从计算机化的图片 视频中获取重要数据 并根据这些数据提出建议 简单地说 你可以理解 如果人工智能允许计算机思考 那么计算机视觉就会鼓励它们去看 注意到和理解 这是在深度学习和机器学习的帮助下完成的
  • 深入理解Solidity——作用域和声明

    作用域和声明 Scoping and Declarations 已声明的变量将具有其字节表示为全0的初始值 变量的初始值是任何类型的典型 零状态 zero state 例如 bool的初始值为false uint或int类型的默认值为0 对
  • FBX SDK的环境配置与FbxLine结构的输出

    FBX SDK的环境配置与FbxLine结构的输出 近期项目中 用到了FBX SDK 根据官网教程与博客等相关资料 在使用过程中主要发现了两点问题 1 FBX SDK的环境配置网上说法不一 2 FbxLine结构体官网教程没有给出具体例子
  • antd a-form-model 动态表单 自定义校验柯里化

    1 需求 前端通过后端字段遍历formItem 由于字段可能是金额 电话号码等 单独if太多了太麻烦 所以想到柯里化 2 代码 响应请求 xxx then res gt if res data list length 0 return fa
  • ftp客服端实现自动更新文件(带更新完自动启动功能)-python

    ftp客服端实现自动更新文件 带自动启动功能并封装为带配置文件的工具 python 前言 一 项目环境和结构 二 使用介绍 三 程序封装和注册服务 四 填坑 希望读者能用到 总结 前言 由于工位机不可能做到实时看守 当更新程序的时候我们还得
  • wxWidgets:使用wxDataViewCtrl类的示例

    wxWidgets 使用wxDataViewCtrl类的示例 wxWidgets是一个跨平台的C 图形用户界面 GUI 库 它提供了丰富的控件和功能 使开发者能够轻松构建跨平台的应用程序 其中的wxDataViewCtrl类是一个强大的控件
  • SVM(支持向量机)原理与应用

    1 支持向量机 支持向量机 Support Vector Machine SVM 是一类按监督学习 supervised learning 方式对数据进行二元分类的广义线性分类器 generalized linear classifier
  • vue flex 布局实现div均分自动换行

    vue flex 布局实现div均分自动换行 许久没有更新了 今天才意外发现以前还是没有看懂盒模型 今天才算看懂了 首先我们今天来看一下想要实现的效果是什么 当然适配是必须的 1920 或者 1376都测试过 效果如图所选中区域所示 一 关
  • 【博客管理】短期长期计划【置顶】

    短期计划 2016 项目 内容 拟完成时间 完成情况 未完成原因 链接 颜色恒常图像增强 递归高斯 英 5 9 page5 total13 1 13 连接 颜色恒常图像增强 递归高斯 英 5 10 0 0 无 颜色恒常图像增强 递归高斯 英
  • 一台浮点计算机 数码为,导论简答.doc

    第一章 一 1 什么是计算机 计算机系统是一种能够按照事先存储的程序 自动 高速的对数据进行输入 处理 输出和存储的系统 一个计算机系统包括硬件和软件两大部分 2 解释冯 诺依曼所提出的 存储程序 概念 把程序和数据都以二进制的形式同意存放
  • Session机制

    除了使用Cookie Web应用程序中还经常使用Session来记录客户端状态 Session是服务器端使用的一种记录客户端状态的机制 使用上比Cookie简单一些 相应的也增加了服务器的存储压力 什么是Session Session是另一
  • Anaconda新建虚拟环境并配置

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 python学习之新建环境配置 一 查看当前环境 二 创建新的虚拟环境 三 pycharm新建的虚拟环境添加及环境更换 python学习之新建环境配置 前提 Ana
  • 数据结构与算法2--数组常见操作

    数据结构与算法2 数组常见操作 数组是最常见也是我们使用最多的数据结构了 它是一块连续的内存空间 以下标来描述空间的位置 C 中int arr len 表示的的数组一旦配置后大小就无法改变 vector