首页
技术博客
PHP教程
数据库技术
前端开发
HTML5
Nginx
php论坛
新用户注册
|
会员登录
PHP教程
技术博客
编程问答
PNG素材
编程语言
前端技术
Android
PHP教程
HTML5教程
数据库
Linux技术
Nginx技术
PHP安全
WebSerer
职场攻略
JavaScript
开放平台
业界资讯
大话程序猿
登录
极速注册
取消
热门标签 | HotTags
微信开放平台
百度
paddle
微信
微信开发
微信公众平台
百度小程序
twitter
支付宝
facebook
当前位置:
开发笔记
>
开放平台
> 正文
php数组的一些常见操作汇总_PHP-php教程
作者:人心城府深我如z何故做清纯 | 来源:互联网 | 2017-05-14 02:17
数组是最基本的数据结构,关于数组的操作是程序员最经常用到的。这里将一些常用的操作写成函数。
数组求和
给定一个含有n个元素的整型数组a,求a中所有元素的和。可能您会觉得很简单,是的,的确简单,但是为什么还要说呢,原因有二,第一,这道题要求用递归法,只用一行代码。第二,这是我人生中第一次面试时候遇到的题,意义特殊。
简单说一下,两种情况:
如果数组元素个数为0,那么和为0。
如果数组元素个数为n,那么先求出前n - 1个元素之和,再加上a[n - 1]即可。
代码如下:
// 数组求和
int sum(int *a, int n)
{
return n == 0 ? 0 : sum(a, n - 1) + a[n - 1];
} 求数组的最大值和最小值
给定一个含有n个元素的整型数组a,找出其中的最大值和最小值。
常规的做法是遍历一次,分别求出最大值和最小值,但我这里要说的是分治法(Divide and couquer),将数组分成左右两部分,先求出左半部份的最大值和最小值,再求出右半部份的最大值和最小值,然后综合起来求总体的最大值及最小值。这是个递归过程,对于划分后的左右两部分,同样重复这个过程,直到划分区间内只剩一个元素或者两个元素。
代码如下:
// 求数组的最大值和最小值,返回值在maxValue和minValue
void MaxandMin(int *a, int l, int r, int& maxValue, int& minValue)
{
if(l == r) // l与r之间只有一个元素
{
maxValue = a[l] ;
minValue = a[l] ;
return ;
}
if(l + 1 == r) // l与r之间只有两个元素
{
if(a[l] >= a[r])
{
maxValue = a[l] ;
minValue = a[r] ;
}
else
{
maxValue = a[r] ;
minValue = a[l] ;
}
return ;
}
int m = (l + r) / 2 ; // 求中点
int lmax ; // 左半部份最大值
int lmin ; // 左半部份最小值
MaxandMin(a, l, m, lmax, lmin) ; // 递归计算左半部份
int rmax ; // 右半部份最大值
int rmin ; // 右半部份最小值
MaxandMin(a, m + 1, r, rmax, rmin) ; // 递归计算右半部份
maxValue = max(lmax, rmax) ; // 总的最大值
minValue = min(lmin, rmin) ; // 总的最小值
}
求数组的最大值和次大值
给定一个含有n个元素的整型数组,求其最大值和次大值。
思想和上一题类似,同样是用分治法,不多说了,直接看代码:
代码如下:
// 求数组的最大值和次大值,返回值在max和second中
void MaxandMin(int *a, int left, int right, int &max, int &second)
{
if(left == right)
{
max = a[left] ;
secOnd= a[left] ;
}
else if(left + 1 == right)
{
max = a[left] > a[right] ? a[left] : a[right] ;
secOnd= a[left]
}
else
{
int mid = left + (right - left) / 2 ;
int leftmax ;
int leftmin ;
MaxandMin(a, left, mid, leftmax, leftmin) ;
int rightmax ;
int rightmin ;
MaxandMin(a, mid + 1, right, rightmax, rightmin) ;
max = leftmax > rightmax ? leftmax : rightmax ;
secOnd= leftmax
}
}
求数组中出现次数超过一半的元素
给定一个n个整型元素的数组a,其中有一个元素出现次数超过n / 2,求这个元素。据说是百度的一道面试题。
设置一个当前值和当前值的计数器,初始化当前值为数组首元素,计数器值为1,然后从第二个元素开始遍历整个数组,对于每个被遍历到的值a[i]。
如果a[i]==currentValue,则计数器值加1。
如果a[i] != currentValue, 则计数器值减1,如果计数器值小于0,则更新当前值为a[i],并将计数器值重置为1。
代码如下:
// 找出数组中出现次数超过一半的元素
int Find(int* a, int n)
{
int curValue = a[0] ;
int count = 1 ;
for (int i = 1; i 另一个方法是先对数组排序,然后取中间元素即可,因为如果某个元素的个数超过一半,那么数组排序后该元素必定占据数组的中间位置。
求数组中元素的最短距离
给定一个含有n个元素的整型数组,找出数组中的两个元素x和y使得abs(x - y)值最小。
先对数组排序,然后遍历一次即可:
代码如下:
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b ;
}
void MinimumDistance(int* a, int n)
{
// Sort
qsort(a, n, sizeof(int), compare) ;
int i ; // Index of number 1
int j ; // Index of number 2
int minDistance = numeric_limits
::max() ;
for (int k = 0; k
{
if (a[k + 1] - a[k]
{
minDistance = a[k + 1] - a[k] ;
i = a[k] ;
j = a[k + 1] ;
}
}
cout <<"Minimum distance is: " <
cout <<"i = " <
}
如果三个数组都无序,可以先对a, b进行排序,然后对c中任意一个元素都在b和c中做二分搜索。
代码如下:
// Find the unique common element in 3 arrays
// O(NlogN)
int UniqueCommonItem(int *a, int *b, int *c, int n)
{
// sort array a
qsort(a, n, sizeof(int), compare) ; // NlogN
// sort array b
qsort(b, n, sizeof(int), compare) ; // NlogN
// for each element in array c, do a binary search in a and b
// This is up to a complexity of N*2*logN
for (int i = 0; i
{
if(BinarySearch(a, n, c[i]) && BinarySearch(b, n, c[i]))
return c[i] ;
}
return - 1 ; // not found
} 也可以对a进行排序,然后对于b和c中任意一个元素都在a中进行二分搜索。
代码如下:
// Find the unique common element in 3 arrays
// O(NlogN)
int UniqueCommonItem1(int *a, int *b, int *c, int n)
{
// sort array a
qsort(a, n, sizeof(int), compare) ; // NlogN
// Space for time
bool *bb = new bool[n] ;
memset(bb, 0, n) ;
bool *bc = new bool[n] ;
memset(bb, 0, n) ;
// for each element in b, do a BS in a and mark all the common element
for (int i = 0; i
{
if(BinarySearch(a, n, b[i]))
bb[i] = true ;
}
// for each element in c, do a BS only if b[i] is true
for (int i = 0; i
{
if(b[i] && BinarySearch(a, n, c[i]))
return c[i] ;
}
return - 1 ; // not found
} 排序和二分搜索代码如下:
代码如下:
// Determine whether a contains value k
bool BinarySearch(int *a, int n, int k)
{
int left = 0 ;
int right = n - 1 ;
while (left <= right)
{
int mid = (left + right) ;
if(a[mid]
left = mid + 1 ;
if(a[mid] == k)
return true ;
else
right = mid - 1 ;
}
return false ;
}
// Compare function for qsort
int compare(const void* a, const void* b)
{
return *(int*)a - *(int*)b ;
} 总结一下,对于在数组中进行查找的问题,可以分如下两种情况处理:
如果给定的数组有序,那么首先应该想到Binary Search,所需O(logn)。
如果给定的数组无序,那么首先应该想到对数组进行排序,很多排序算法都能在O(nlogn)时间内对数组进行排序,然后再使用二分搜索,总的时间复杂度仍是O(nlogn)。
如果能做到以上两点,大多数关于数组的查找问题,都能迎刃而解。
找出数组中唯一的重复元素
给定含有1001个元素的数组,其中存放了1-1000之内的整数,只有一个整数是重复的,请找出这个数。
求出整个数组的和,再减去1-1000的和即可,代码略。
找出出现奇数次的元素
给定一个含有n个元素的整型数组a,其中只有一个元素出现奇数次,找出这个元素。
因为对于任意一个数k,有k ^ k = 0,k ^ 0 = k,所以将a中所有元素进行异或,那么个数为偶数的元素异或后都变成了0,只留下了个数为奇数的那个元素。
int FindElementWithOddCount(int *a, int n)
{
int r = a[0] ;
for (int i = 1; i
求数组中满足给定和的数对
给定两个有序整型数组a和b,各有n个元素,求两个数组中满足给定和的数对,即对a中元素i和b中元素j,满足i + j = d(d已知)。
两个指针i和j分别指向数组的首尾,然后从两端同时向中间遍历,直到两个指针交叉。
代码如下:
// 找出满足给定和的数对
void FixedSum(int* a, int* b, int n, int d)
{
for (int i = 0, j = n - 1; i
= 0)
{
if (a[i] + b[j]
++i ;
else if (a[i] + b[j] == d)
{
cout <
++i ;
--j ;
}
else // a[i] + b[j] > d
--j ;
}
} 最大子段和
给定一个整型数组a,求出最大连续子段之和,如果和为负数,则按0计算,比如1, 2, -5, 6, 8则输出6 + 8 = 14。
编程珠玑上的经典题目,不多说了。
代码如下:
// 子数组的最大和
int Sum(int* a, int n)
{
int curSum = 0;
int maxSum = 0;
for (int i = 0; i
{
if (curSum + a[i] <0)
curSum = 0;
else
{
curSum += a[i] ;
maxSum = max(maxSum, curSum);
}
}
return maxSum;
} 最大子段积
给定一个整型数足a,求出最大连续子段的乘积,比如 1, 2, -8, 12, 7则输出12 * 7 = 84。
与最大子段和类似,注意处理负数的情况。
代码如下:
// 子数组的最大乘积
int MaxProduct(int *a, int n)
{
int maxProduct = 1; // max positive product at current position
int minProduct = 1; // min negative product at current position
int r = 1; // result, max multiplication totally
for (int i = 0; i
{
if (a[i] > 0)
{
maxProduct *= a[i];
minProduct = min(minProduct * a[i], 1);
}
else if (a[i] == 0)
{
maxProduct = 1;
minProduct = 1;
}
else // a[i] <0
{
int temp = maxProduct;
maxProduct = max(minProduct * a[i], 1);
minProduct = temp * a[i];
}
r = max(r, maxProduct);
}
return r;
} 数组循环移位
将一个含有n个元素的数组向右循环移动k位,要求时间复杂度是O(n),且只能使用两个额外的变量,这是在微软的编程之美上看到的一道题。
比如数组 1 2 3 4循环右移1位 将变成 4 1 2 3, 观察可知1 2 3 的顺序在移位前后没有改变,只是和4的位置交换了一下,所以等同于1 2 3 4 先划分为两部分 1 2 3 | 4,然后将1 2 3逆序,再将4 逆序 得到 3 2 1 4,最后整体逆序 得到 4 1 2 3。
代码如下:
// 将buffer中start和end之间的元素逆序
void Reverse( int buffer[], int start, int end )
{
while ( start
{
int temp = buffer[ start ] ;
buffer[ start++ ] = buffer[ end ] ;
buffer[ end-- ] = temp ;
}
}
// 将含有n个元素的数组buffer右移k位
void Shift( int buffer[], int n, int k )
{
k %= n ;
Reverse( buffer, 0, n - k - 1) ;
Reverse( buffer, n - k, n - 1 ) ;
Reverse( buffer, 0, n - 1 ) ;
} 字符串逆序
给定一个含有n个元素的字符数组a,将其原地逆序。
可能您觉得这不是关于数组的,而是关于字符串的。是的。但是别忘了题目要求的是原地逆序,也就是不允许额外分配空间,那么参数肯定是字符数组形式,因为字符串是不能被修改的(这里只C/C++中的字符串常量),所以,和数组有关了吧,只不过不是整型数组,而是字符数组。用两个指针分别指向字符数组的首位,交换其对应的字符,然后两个指针分别向数组中央移动,直到交叉。
代码如下:
// 字符串逆序
void Reverse(char *a, int n)
{
int left = 0;
int right = n - 1;
while (left
{
char temp = a[left] ;
a[left++] = a[right] ;
a[right--] = temp ;
}
} 组合问题
给定一个含有n个元素的整型数组a,从中任取m个元素,求所有组合。比如下面的例子:
a = 1, 2, 3, 4, 5
m = 3
输出:
1 2 3, 1 2 4, 1 2 5, 1 3 4, 1 3 5, 1 4 5
2 3 4, 2 3 5, 2 4 5
3 4 5
典型的排列组合问题,首选回溯法,为了简化问题,我们将a中n个元素值分别设置为1-n。
代码如下:
// n选m的所有组合
int buffer[100] ;
void PrintArray(int *a, int n)
{
for (int i = 0; i
cout <
cout <
}
bool IsValid(int lastIndex, int value)
{
for (int i = 0; i
{
if (buffer[i] >= value)
return false;
}
return true;
}
void Select(int t, int n, int m)
{
if (t == m)
PrintArray(buffer, m);
else
{
for (int i = 1; i <= n; i++)
{
buffer[t] = i;
if (IsValid(t, i))
Select(t + 1, n, m);
}
}
} 合并两个数组
给定含有n个元素的两个有序(非降序)整型数组a和b。合并两个数组中的元素到整型数组c,要求去除重复元素并保持c有序(非降序)。例子如下:
a = 1, 2, 4, 8
b = 1, 3, 5, 8
c = 1, 2, 3, 4, 5, 8
利用合并排序的思想,两个指针i,j和k分别指向数组a和b,然后比较两个指针对应元素的大小,有以下三种情况:
a[i]
a[i] == b[j],则c[k]等于a[i]或b[j]皆可。
a[i] > b[j],则c[k] = b[j]。
重复以上过程,直到i或者j到达数组末尾,然后将剩下的元素直接copy到数组c中即可。
代码如下:
// 合并两个有序数组
void Merge(int *a, int *b, int *c, int n)
{
int i = 0 ;
int j = 0 ;
int k = 0 ;
while (i
{
if (a[i]
{
c[k++] = a[i] ;
++i ;
}
else if (a[i] == b[j])// 如果a和b元素相等,则插入二者皆可,这里插入a
{
c[k++] = a[i] ;
++i ;
++j ;
}
else // a[i] > b[j] // 如果b中元素小,则插入b中元素到c
{
c[k++] = b[j] ;
++j ;
}
}
if (i == n) // 若a遍历完毕,处理b中剩下的元素
{
for (int m = j; m
c[k++] = b[m] ;
}
else//j == n, 若b遍历完毕,处理a中剩下的元素
{
for (int m = i; m
c[k++] = a[m] ;
}
} 重排问题
给定含有n个元素的整型数组a,其中包括0元素和非0元素,对数组进行排序,要求:
排序后所有0元素在前,所有非零元素在后,且非零元素排序前后相对位置不变。
不能使用额外存储空间。
例子如下:输入 0, 3, 0, 2, 1, 0, 0,输出 0, 0, 0, 0, 3, 2, 1。
此排序非传统意义上的排序,因为它要求排序前后非0元素的相对位置不变,或许叫做整理会更恰当一些。我们可以从后向前遍历整个数组,遇到某个位置i上的元素是非0元素时,如果a[k]为0,则将a[i]赋值给a[k],a[k]赋值为0。实际上i是非0元素的下标,而k是0元素的下标。
代码如下:
void Arrange(int* a, int n)
{
int k = n - 1 ;
for (int i = n - 1; i >= 0; --i)
{
if (a[i] != 0)
{
if (a[k] == 0)
{
a[k] = a[i] ;
a[i] = 0 ;
}
--k ;
}
}
}
百度
算法
写下你的评论吧 !
吐个槽吧,看都看了
会员登录
|
用户注册
推荐阅读
百度
PHP 编程疑难解析与知识点汇总
本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ...
[详细]
蜡笔小新 2024-12-28 12:22:34
百度
深入解析Android自定义View面试题
本文探讨了Android Launcher开发中自定义View的重要性,并通过一道经典的面试题,帮助开发者更好地理解自定义View的实现细节。文章不仅涵盖了基础知识,还提供了实际操作建议。 ...
[详细]
蜡笔小新 2024-12-28 11:15:04
百度
Understanding Life: A Forward-Living, Backward-Reflecting Paradox
Søren Kierkegaard famously stated that life can only be understood in retrospect but must be lived moving forward. This perspective delves into the intricate relationship between our lived experiences and our reflections on them. ...
[详细]
蜡笔小新 2024-12-28 10:17:59
百度
计算机网络复习:第五章 网络层控制平面
本文探讨了网络层的控制平面,包括转发和路由选择的基本原理。转发在数据平面上实现,通过配置路由器中的转发表完成;而路由选择则在控制平面上进行,涉及路由器中路由表的配置与更新。此外,文章还介绍了ICMP协议、两种控制平面的实现方法、路由选择算法及其分类等内容。 ...
[详细]
蜡笔小新 2024-12-27 22:54:11
百度
Go语言基础:Hello World 实践
本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ...
[详细]
蜡笔小新 2024-12-27 21:29:35
百度
线性Kalman滤波器在多自由度车辆悬架主动控制中的应用研究
本文探讨了线性Kalman滤波器(LKF)在不同自由度(2、4、7)的车辆悬架系统中进行主动控制的应用。通过详细的仿真分析,展示了LKF在提升悬架性能方面的潜力,并总结了调参过程中的关键要点。 ...
[详细]
蜡笔小新 2024-12-27 20:47:55
百度
HDFS与Hive中的数据存储和管理机制
本文探讨了Hive中内部表和外部表的区别及其在HDFS上的路径映射,详细解释了两者的创建、加载及删除操作,并提供了查看表详细信息的方法。通过对比这两种表类型,帮助读者理解如何更好地管理和保护数据。 ...
[详细]
蜡笔小新 2024-12-27 20:21:48
百度
新浪笔试题
1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ...
[详细]
蜡笔小新 2024-12-27 19:32:17
百度
C++实现经典排序算法
本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ...
[详细]
蜡笔小新 2024-12-27 19:25:14
百度
使用动态规划算法求解0-1背包问题
本文介绍如何利用动态规划算法解决经典的0-1背包问题。通过具体实例和代码实现,详细解释了在给定容量的背包中选择若干物品以最大化总价值的过程。 ...
[详细]
蜡笔小新 2024-12-27 19:17:15
百度
深入理解设计模式与七大原则
本文详细探讨了Java中的24种设计模式及其应用,并介绍了七大面向对象设计原则。通过创建型、结构型和行为型模式的分类,帮助开发者更好地理解和应用这些模式,提升代码质量和可维护性。 ...
[详细]
蜡笔小新 2024-12-27 19:10:10
百度
Java并发编程:LinkedBlockingQueue的实际应用
本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ...
[详细]
蜡笔小新 2024-12-27 18:51:49
百度
USACO 2014 Jan - Moolympics区间记录优化算法
题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ...
[详细]
蜡笔小新 2024-12-27 18:14:31
百度
深入理解C++中的KMP算法:高效字符串匹配的利器
本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ...
[详细]
蜡笔小新 2024-12-27 14:45:30
百度
LeetCode 991:故障计算器的最优解法
探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ...
[详细]
蜡笔小新 2024-12-27 14:34:44
人心城府深我如z何故做清纯
这个家伙很懒,什么也没留下!
Tags | 热门标签
微信开放平台
百度
paddle
微信
微信开发
微信公众平台
百度小程序
twitter
支付宝
facebook
RankList | 热门文章
1
布莱顿为凯塞多标价8500万英镑,曼联与利物浦或加入竞争
2
JDK下载与安装指南
3
PHPStorm 快捷键指南:Mac与Windows平台全解析
4
探讨批量插入联系人时的性能优化策略
5
探索百度WebFE团队打造的强大HTML5上传插件Web Uploader
6
Vue CLI 中的 Proxy 配置详解
7
SQL查询中使用LIKE与CONCAT结合的方法
8
‘晔’字详解:新华字典中的读音、笔画与应用
9
理解路径概念:绝对路径与相对路径
10
protobuf 使用心得:解析与编码陷阱
11
解决sslocal连接重置问题
12
php + layui 文件上传 以及 拖拽上传
13
深入理解Java SE 8新特性:Lambda表达式与函数式编程
14
ARM平台下构建SSH服务端并实现远程访问
15
大数据量下的SQL分页查询性能优化策略
PHP1.CN | 中国最专业的PHP中文社区 |
DevBox开发工具箱
|
json解析格式化
|
PHP资讯
|
PHP教程
|
数据库技术
|
服务器技术
|
前端开发技术
|
PHP框架
|
开发工具
|
在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved |
京公网安备 11010802041100号
|
京ICP备19059560号-4
| PHP1.CN 第一PHP社区 版权所有