java 数组获取子列

java 数组获取子列,第1张

不懂API就去查 别误导别人

public static void main(String[] args) {

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

int from = 2;

int to = 4;

int original[] = ArrayscopyOfRange(a, from, to);

for (int c : original) {

Systemerrprintln(c);

}

}

#include<stdioh>

#include<stdlibh>

#include<limitsh>

//求最大子

/这是算法导论中,线性时间规划的一道题

线性时间实现基于这样的思路:

如果a[1j]已经得到了其最大子数组,那么a[1j+1]最大子数组只能是两种情况

(1)a[1j+1]的最大子数组就是a[1j];

(2)a[1j+1]的最大子数组是a[ij+1],1<=i<=j;

那么,如何求得所谓的(2)中的a[ij+1]呢?

首先需要承认这样的事实,如果一个数组a[pr]求和得到负值,那么数组a[pr+1]的最大子数组肯定不会是a[pr+1],因为a[pr]+a[r+1]<a[r+1]

在以上程序中,我们用temp存储所谓的a[pr],只要a[pr]的求和是负值,那么从下一个a[r+1]值开始,temp重新从零开始求和,只要temp > summax,就更新summax,这样,我们一次遍历后,就能得到最大的summax,接下来,我们证明该算法是有效的

证明:

对于所有数组元素,这样的元素对数组进行划分,如果加上该元素之前temp>0且temp+a[i]<0,那么该元素a[i]是一个边界,这样,数组会形成好多段,每段结束元素都满足temp>0且temp+a[i]<0所以我们能得到多个划分块a[pq],每个划分快的和是负值,划分块有这样的性质,对任意p<=i<q,显然,sum(a[pi])>=0且sum(a[iq])<0;

我们要证明

(1)最大子数组一定在划分块之内

证明:

根据划分快性质,容易证明,只要子数组横跨多个划分快,其求和值必定小于某个单独的划 分快中的数组求和。

(2)一定存在首元素以划分块的首元素开始的最大子数组。

证明:

对于某个划分快a[pq],假设存在a[ij],其中p<i<=j<q,那么根据划分块性质,a[pi-1]+a[ij]>=a[ij]必定成立,得证。

所以,经历一次遍历,对于每个划分块,从首元素开始求和,得到最大值更新summax,一定能够得到最大子数组的值。

/

int maxsubset(int a,int l,int r) //l数组起始索引 r终止索引

{

int i,

temp=0,

summax=INT_MIN; //包含在limitsh中

for(i=l;i<=r;i++)

{

temp+=a[i];

if(temp > summax) summax=temp;

if(temp < 0) temp=0;

}

return summax;

}

int main(void)

{

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

int len = sizeof(a)/sizeof(int);

printf("the maxsubset:%d\n",maxsubset(a,0,(len-1)));

}

只回答第一个问题,第二个懒得写了。。。。其实只要有思路,什么都好说

package array;

import javautilArrayList;

import javautilList;

public class SubArray {

/

获取一个指定数组的所有连续子数组

@param fullArray

@return

/

public static List<Integer[]> getAllSubArray(Integer[] fullArray) {

List<Integer[]> subArrayList = new ArrayList<Integer[]>();

for (int i = 0; i < fullArraylength; i++) {

// 连续性子数组的第一个元素始终由最外层的循环获取,剩下的元素从后续元素中顺序添加。

// 记录内部循环每次循环后得到的数组。

Integer[] preArray = new Integer[1];

preArray[0] = fullArray[i];

for (int j = i + 1; j < fullArraylength; j++) {

// 在原有的子数组上面再加上一个元素组成新的数组。

if (appendElm(preArray, fullArray[j])length < fullArraylength) {

// 确保得到的是子数组,而不是原来数组的复制。

preArray = appendElm(preArray, fullArray[j]);

subArrayListadd(preArray);

}

}

}

return subArrayList;

}

public static Integer[] appendElm(Integer[] array, Integer toAppend) {

// 创建一个新的数组

Integer[] _array = new Integer[arraylength + 1];

// 复制数组到新的数组当中

for (int i = 0; i < arraylength; i++)

_array[i] = array[i];

// 追加最后一个元素

_array[_arraylength - 1] = toAppend;

return _array;

}

/

对数组求和

@param array

@return

/

public static int sumArray(Integer[] array) {

int sum = 0;

for (Integer n : array)

sum += nintValue();

return sum;

}

public static void showMaxSum(List<Integer[]> allArrayList) {

// 记录最大和得数组在list当中的下标。

int[] record = new int[allArrayListsize()];

int maxSum = 0;

int recordPoint = 0;

for (int i = 0; i < allArrayListsize(); i++) {

if (i == 0) {

// 第一个数组默认为最大的

record[0] = 0;

maxSum = sumArray(allArrayListget(i));

recordPoint = 1;

} else {

if (maxSum == sumArray(allArrayListget(i))) {

// 如果下一个数组的和与之前的最大值相同,则保存到record当中

recordPoint++;

record[recordPoint] = i;

} else if (maxSum < sumArray(allArrayListget(i))) {

record = new int[allArrayListsize() - i];

recordPoint = 0;

record[recordPoint] = i;

maxSum = sumArray(allArrayListget(i));

}

}

}

for (int i = 0; i <= recordPoint; i++) {

Integer[] subArray = allArrayListget(record[i]);

for (int j = 0; j < subArraylength; j++)

Systemoutprint(subArray[j]intValue() + " ");

Systemoutprintln(sumArray(subArray));

}

}

public static void main(String[] args) {

Integer[] fullArray = new Integer[] { new Integer(5), new Integer(0),

new Integer(2), new Integer(-6), new Integer(4) };

List<Integer[]> allSubArrayList = SubArraygetAllSubArray(fullArray);

SubArrayshowMaxSum(allSubArrayList);

}

}

LeetCode上 最长递增子序列 ,中等难度记录下解题思路

这是一道LIS题目,LIS(Longest Increasing Subsequence)最长上升(不下降)子序列。

假设传入一个数组 nums = [1,0,1,3,8,8,1,8] 从 i = 0 开始取子数组,要计算能取到的最长递增子数组

这里开始引入动态规划的概念,拥有一个数组 dp , dp 中的 dp[i] 对应的是 i 位置的数组能获取的最长递增数组

这里发现了一个不错的 线上LIS演示网站 ,结合这个网站来看整个过程

通过内外两层循环来解题外层循环 i 和内层循环 j

例如

所以最后总结下来

NSRange用法

NSRange的定义

typedef struct _NSRange

{

NSUInteger location;

NSUInteger length;

} NSRange;

NSRange是一个结构体,其中location是一个以0为开始的index,length是表示对象的长度。他们都是NSUInteger类型。 而NSUInteger类型的定义如下:

#if __LP64__ || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64

typedef unsigned long NSUInteger;

#else

typedef unsigned int NSUInteger;

#endif

例子:

下面这个例子,将输出IPA

NSString homebrew = @"Imperial India Pale Ale (IPA)";

// Starting at position 25, get 3 characters

NSRange range = NSMakeRange (25, 3);

// This would also work:

// NSRange range = {25, 3};

NSLog (@"Beer shortname: %@", [homebrew substringWithRange:range]);

搜索字符串

NSString homebrew = @"Imperial India Pale Ale (IPA)";

NSRange range = [homebrew rangeOfString:@"IPA"];

// Did we find the string "IPA"

if (rangelength > 0)

NSLog(@"Range is: %@", NSStringFromRange(range));

上面的程序将输出Range is: {25, 3}。NSStringFromRange()方法,将一个NSRange返回一个NSString。而另外一个函数NSRangeFromString()则是将NSString转换为NSRange

下面这个例子将从后向前反向搜索字符串:

NSString homebrew = @"Imperial India Pale Ale (IPA)";

// Search for the "ia" starting at the end of string

NSRange range = [homebrew rangeOfString:@"ia" options:NSBackwardsSearch];

// What did we find

if (rangelength > 0)

NSLog(@"Range is: %@", NSStringFromRange(range));

上面的程序将输出:Range is: {12, 2}

ac

如果你要获取一个字符串或者一个数组中的一个子集,那么使用NSRange会很方便的定义这个子集。

NSRange定义

Declaration: typedef struct _NSRange {

NSUInteger location;

NSUInteger length;

} NSRange;

创建NSRange的方法定义

Declaration: NSRange NSMakeRange (

NSUInteger loc,

NSUInteger len

);

例如获取一个数组的一个子集:

NSRange range = NSMakeRange(0, 5);

NSArray subArray = [selfstates subarrayWithRange:range];

这样就获得了这个数组中0开始的5个元素的子集。

Apache开发的常用工具类的包,个人感觉好用的类有:

方法:

判空的:isEmpty,isNotEmpty,isAnyEmpty,isNoneEmpty,isAllEmpty,

              isBlank,isNotBlank,isAnyBlank,isNoneBlank,isAllBlank

去除空白字符:strip,stripToEmpty

参数1的字符串  去除 参数2里的字符:strip,stripStart,stripEnd

判断是否相等(兼容空指针):equals,equalsIgnoreCase

字符串比较大小:compare,compareIgnoreCase

字符串是否包含某个字符或字符串:contains,containsIgnoreCase,containsWhitespace,containsAny

字符串替换:replaceOnce,replaceOnceIgnoreCase,replaceAll,replace

包裹字符串:wrap

解包裹:unwrap

字符串是否都为字母:isAlpha

字符串是否都为数字:isNumeric

字符串是否都为字母、数字:isAlphanumeric

字符串转数字(为了兼容空指针和非数字,可以设置默认值,默认为0):toInt,toLong,toFloat,toDouble等等

取最小值:min

取最大值:max

字符串是否为纯数字:isDigits

方法:nextBoolean,nextBytes,nextInt,nextLong,nextDouble,nextFloat

random:获取指定长度的随机字符串

randomAscii:获取指定长度的随机字符串,字符都是ASCII字符

randomAlphabetic:获取指定长度的随机字符串,字符都是字母

randomNumeric:获取指定长度的随机字符串,字符都是数字

randomAlphanumeric:获取指定长度的随机字符串,字符都是字母、数字

random(final int count, final String chars):获取count个随机字符,字符从chars 里面选

里面的方法大多有重载,如参数兼容int、long、double、Object等类型

clone:复制数组

nullToEmpty:如果数组对象为null,则声明一个空数组返回

subarray:指定开始位置、结束位置,获取子数组

isSameLength:判断两个数组长度是否一致

reverse:翻转数组顺序

swap:交换元素位置

contains:数组是否包含某个对象

toObject:原生类型数组 转  包装类数组

toPrimitive:包装类数组 转 原生类型数组

parseDate:解析字符串,得到Date对象

isSameDay:两个日期对象是否同一天

isSameInstant:两个对象是否表示同一时刻

日期增加(年、月、日、时、分、秒):addYears,addMonths,addDays,addHours,addMinutes,addSeconds,addMilliseconds

设置日期的某一项(年、月、日、时、分、秒):setYears,setMonths,setDays,setHours,setMinutes,setSeconds

toCalendar:日期对象转日历对象

truncatedEquals:日期比较,可以比较到年或月或日等

format:格式化输出,参数一可以传毫秒数,也可以传Date对象或Calendar对象

据题目的要求,求一维数组中的最长递增子序列,也就是找一个标号的序列b[0],b[1],…,b[m](0 <= b[0] < b[1] < … < b[m] < N),使得array[b[0]]<array[b[1]]<…<array[b[m]]。

根据无后效性的定义我们知道,将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态来说,它以前各阶段的状态无法直接影响它未来的决策,而只能间接地通过当前的这个状态来影响。换句话说,每个状态都是历史的一个完整总结。

同样的,仍以序列1,-1,2,-3,4,-5,6,-7为例,我们在找到4之后,并不关心4之前的两个值具体是怎样,因为它对找到6没有直接影响。因此,这个问题满足无后效性,可以通过使用动态规划来解决。

可以通过数字的规律来分析目标串:1,-1,2,-3,4,-5,6,-7。

以上就是关于java 数组获取子列全部的内容,包括:java 数组获取子列、C++求数组最大子数组,请教这个哪里出错了。 要求数组大小1<=n<=5000 元素大小[-5000,5000]、求C++或JAVA编写的以下程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9548703.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存