最大子阵列


21

将给定数组的“最大子数组”定义为“具有最大和的(连续)子数组”。请注意,没有“非零”要求。输出该和。

如果可能,请提供代码说明。

样本输入1:

1 2 3 -4 -5 6 7 -8 9 10 -11 -12 -13 14

样本输出1: 24

描述1:
最大的总和是通过切除6 7 -8 9 10和求和而得出的。

样本输入2:-1 -2 -3
样本输出2:0
描述2:很简单:)空的子数组是“最大的”。

需求:

  • 除了标准输入外,什么也不要读,输出应该输出到标准输出。
  • 适用标准漏洞限制

排名:最短的程序赢得此


5
编写一个尽可能短的程序。我建议删除此要求,因为它要求我们检查用我们的语言编写的每个程序,并确保使用最短的程序。
Okx

要求2也不清楚。是图书馆吗?自定义库?外包程序?标准漏洞已经禁止使用后者。
Leaky Nun

14
除标准输入外,请勿读取任何内容,除标准输出外,请勿写入任何内容。-为什么?
Xcoder先生17年

2
非常相似,可能是骗子。也很相似
xnor

Answers:


10

外壳6个 4字节

▲ṁ∫ṫ

在线尝试!

      -- implicit input (list) xs  - eg. [-1,2,3]
   ṫ  -- get all tails of xs       -     [[-1,2,3],[2,3],[3],[]]
 ṁ∫   -- map & concat cumsum       -     [0,-1,1,4,0,2,5,0,3,0]
▲     -- get maximum               -     5


4

Pyth,8个字节

eS+0sM.:

在线尝试!


怎么样?

eS + 0sM。:Q-Q是隐式的,表示输入。假设它是[-1,-2,-3]。

      。:-所有连续的非空子列表。我们有[[-1],[-2],[-3],[-1,-2],[-2,-3],[-1,-2,-3]。
    sM-获取每个子列表的总和。[-1,-2,-3,-3,-5,-6]
  +0-将0附加到总和列表中。[0,-1,-2,-3,-3,-5,-6]
eS-最大元素。S给我们[-6,-5,-3,-3,-2,-1,0],而e返回0,即最后一个元素。

4

05AB1E,4个字节

Ό0M

在线尝试!

-1感谢Adnan


与Okx的答案相同的技巧:ÎŒOM应该工作4个字节。
阿德南(Adnan)

@Adnan谢谢,我认为内置的只有“ 1和输入” ...等等...对吗?他们不应该串联在一起吗?
暴民埃里克(Erik the Outgolfer)'17年

不,M在堆栈的扁平化版本中搜索最大的数字。
阿德南(Adnan)

@Adnan好的...这对我来说是个新闻大声笑
Outgolfer的Erik


3

C ++,197个 195 187字节

-10字节归功于Zacharý

#include<vector>
#include<numeric>
int f(std::vector<int>v){int i=0,j,t,r=0;for(;i<v.size();++i)for(j=i;j<v.size();++j){t=std::accumulate(v.begin()+i,v.begin()+j,0);if(t>r)r=t;}return r;}

您可以在第一个for循环后删除括号吗?
扎卡里

另外,为什么你有lh反正?
扎卡里

@Zacharýl和h是子数组的开始和结束索引
HatsuPointerKun

3

R,54个字节

a=b=0;for(x in scan()){a=max(x,a+x);b=max(a,b)};cat(b)

在线尝试!

算法取自:最大子数组问题

R,65个字节

y=seq(x<-scan());m=0;for(i in y)for(j in y)m=max(m,sum(x[i:j]));m

在线尝试!

  • x从stdin中读取。
  • 设置y为的索引x
  • 在所有可能的非空子集上迭代两次。
  • 比较一个子集的总和m(最初是m=0)。
  • 将最大值存储在中m
  • 打印值为m

R,72个字节

n=length(x<-scan());m=0;for(i in 1:n)for(j in i:n)m=max(m,sum(x[i:j]));m

在线尝试!

  • x从stdin中读取。
  • 对所有可能的非空子集进行全面搜索。
  • 比较一个子集的总和m(最初是m=0)。
  • 将最大值存储在中m
  • 打印值为m

其他不成功的想法

58个字节

Reduce(max,lapply(lapply(seq(x<-scan()),tail,x=x),cumsum))

63字节

Reduce(max,lapply(seq(x<-scan()),function(i)cumsum(tail(x,i))))

72字节

m=matrix(x<-scan(),n<-length(x),n);max(apply(m*lower.tri(m,T),2,cumsum))

1
a=b=0也可以。另外,您需要处理输出的打印。当作为完整程序运行(通过source)时,它不会打印任何内容。
JAD

@JarkoDubbeldam,我已经添加了cat(b),但是如果带有echo=TRUE它,就足以要求b打印输出。
djhurio

我猜对R中如何运行完整程序还没有一个明确的定义。命令行中有rscript,R本身有源。但是通常在运行脚本时需要的标志包含在字节数中。(我个人还没有设法使rscript与scan配合使用,但这是另一回事。–
JAD

您可以使用T=F而不是a=b=0保存两个字节,因为max它将强制转换bnumeric
朱塞佩

3

Haskell,28个字节

maximum.scanl((max<*>).(+))0

在线尝试!


最大值不是总是从中返回的最后一个元素scanl吗?所以foldl((max<*>).(+))0??
matthias

NVM我看到了我的错误!
matthias

@matthias如果您看到编辑历史记录,则会看到我犯了sma错误。:-)
H.PWiz



2

Haskell41 33字节

import Data.List
g=maximum.concatMap(map sum.inits).tails
maximum.(scanl(+)0=<<).scanr(:)[]

在线尝试!多亏莱科尼


1
允许匿名函数作为提交,因此您可以删除g=。而不是concatMap您可以=<<从列表中使用monad:在线尝试!(33个字节)。
Laikoni '17

1

Japt,11个字节

£ãY mxÃc rw

在线尝试!

说明

£ãY mxÃc rw
m@ãY mx} c rw   // Ungolfed
m@     }        // Map the input array by the following function, with Y=index
  ãY            //   Get all subsections in input array length Y
     mx         //   Sum each subsection
         c rw   // Flatten and get max

备用方法,11个字节

来自@ETHproductions; 根据蛮力的果壳答案

£sY å+Ãc rw

获取输入数组的所有尾部,并对每个尾部进行累加。然后展平数组并获得最大值。

在线尝试!


很好,真的很好。当我较早看到它时,我并未尝试实施此挑战,但我确实想到了另一种技术,并期望它能出现在15个字节左右,所以这很棒。
ETHproductions '17

看一下Husk的答案,还有另一种有效的方法:(£sY å+Ãc rw也是11个字节)
ETHproductions'Aug 13''17

@ETHproductions非常好,我将其添加到此答案中作为替代方法。是否可以通过reduce / concat的某种组合进行改进,例如Husk的答案?
贾斯汀·马里纳

1

Ruby,61 59 57字节

我刚刚开始学习Ruby,所以这就是我想出的。

s=0
p [gets.split.map{|i|s=[j=i.to_i,s+j].max}.max,0].max

我首先在这本未完成的书的芬兰语版本中看到了这种算法。第23页对此进行了很好的解释。

在线尝试!


1

JavaScript,58个字节

m=Math.max;x=y=>eval("a=b=0;for(k of y)b=m(a=m(a+k,k),b)")

Golfed JS实现的Kadane算法。制作得越短越好。欢迎提出建设性建议!

我从这篇文章了解到:返回值eval-当其最后statment是一个for循环-基本上是目前最后一个值循环。凉!

编辑:感谢贾斯汀和赫尔曼的建议,节省了四个字节。


您可以return用替换为{...;return b;}eval("...;b")因为eval返回最后一条语句。
贾斯汀·马里纳

@JustinMariner谢谢!总是在这里学习新的东西:)
Gaurang Tandon

您可以通过删除来删除另外两个字节;b,因为它是从for循环中返回的
Herman L

@HermanLauenstein哦,哇,谢谢,这很有用!
Gaurang Tandon's




0

k,14个字节

|/,/+\'(1_)\0,

在线尝试!

            0, /prepend a zero (in case we're given all negatives)
       (1_)\   /repeatedly remove the first element, saving each result
    +\'        /cumulative sum over each result, saving each result
  ,/           /flatten (fold concat)
|/             /maximum (fold max)

0

APL,31 29 27字节

⌈/∊∘.{+/W[X/⍨⍺≤X←⍳⍵]}⍨⍳⍴W←⎕

在线尝试!(已修改,因此它将在TryAPL上运行)

怎么样?

  • ∊∘.{+/W[X/⍨⍺≤X←⍳⍵]}⍨⍳⍴W←⎕ 生成子向量的总和
  • ⌈/ 最大

0

CJam,24个字节

q~:A,{)Aew{:+}%}%e_0+:e>

以数字数组为输入的函数。

在线尝试

q~:A   e# Store array in 'A' variable
,{)Aew e# Get every possible sub-array of the array
{:+}%  e# Sum every sub array
}e_    e# flatten array of sums
0+     e# Add zero to the array
:e>    e# Return max value in array

0

MY,11个字节

⎕𝟚35ǵ'ƒ⇹(⍐↵

在线尝试!我现在在TIO!oo!

怎么样?

  • =评估输入
  • 𝟚 =子向量
  • 35ǵ'= chr(0x53)(Σ,总和)
  • ƒ =字符串作为MY函数
  • =地图
  • ( =适用
  • =最大值
  • =用换行符输出。

总和是固定的(0在空数组上),以便此工作。产品也已修复。


0

J,12个字节

[:>./@,+/\\.

类似于zgrep的K解决方案:所有后缀的扫描和(生成矩阵),raz,max

在线尝试!

注意

对于不太多的字节,您可以获得一个有效的解决方案(打高尔夫球的19个字节):

[: >./ [: ({: - <./)\ +/\

0

公理,127字节

f(a:List INT):Complex INT==(n:=#a;n=0=>%i;r:=a.1;for i in 1..n repeat for j in i..n repeat(b:=reduce(+,a(i..j));b>r=>(r:=b));r)

这将是O(#a ^ 3)Algo; 我从C ++复制它...结果

(3) -> f([1,2,3,-4,-5,6,7,-8,9,10,-11,-12,-13,14])
   (3)  24
                                                    Type: Complex Integer
(4) -> f([])
   (4)  %i
                                                    Type: Complex Integer
(5) -> f([-1,-2,3])
   (5)  3
                                                    Type: Complex Integer

0

Scala,105个字节

val l=readLine.split(" ").map(_.toInt);print({for{b<-l.indices;a<-0 to b+2}yield l.slice(a,b+1).sum}.max)

我没有找到更好的方法来生成子列表数组。


0

Java 8,242字节

import java.util.*;v->{List a=new Stack();for(String x:new Scanner(System.in).nextLine().split(" "))a.add(new Long(x));int r=0,l=a.size(),i=l,j,k,s;for(;i-->0;)for(j=l;--j>1;r=s>r?s:r)for(s=0,k=i;k<j;)s+=(long)a.get(k++);System.out.print(r);}

在这里尝试。

不使用STDIN / STDOUT要求的106个字节。

a->{int r=0,l=a.length,i=l,j,k,s;for(;i-->0;)for(j=l;--j>1;r=s>r?s:r)for(s=0,k=i;k<j;s+=a[k++]);return r;}

在这里尝试。

说明:

import java.util.*;      // Required import for List, Stack and Scanner

v->{                     // Method with empty unused parameter and no return-type
  List a=new Stack();    //  Create a List
  for(String x:new Scanner(System.in).nextLine().split(" "))
                         //  Loop (1) over the STDIN split by spaces as Strings
    a.add(new Long(x));  //   Add the String converted to a number to the List
                         //  End of loop (1) (implicit / single-line body)
  int r=0,               //  Result-integer
      l=a.size(),        //  Size of the List
      i=l,j,k,           //  Index-integers
      s;                 //  Temp sum-integer
  for(;i-->0;)           //  Loop (2) from `l` down to 0 (inclusive)
    for(j=l;--j>1;       //   Inner loop (3) from `l-1` down to 1 (inclusive)
        r=               //     After every iteration: change `r` to:
          s>r?           //      If the temp-sum is larger than the current `r`:
           s             //       Set `r` to the temp-sum
          :              //      Else:
           r)            //       Leave `r` the same
      for(s=0,           //    Reset the temp-sum to 0
          k=i;k<j;)      //    Inner loop (4) from `i` to `j` (exclusive)
        s+=(long)a.get(k++);
                         //     Add the number at index `k` in the List to this temp-sum
                         //    End of inner loop (4) (implicit / single-line body)
                         //   End of inner loop (3) (implicit / single-line body)
                         //  End of loop (2) (implicit / single-line body)
  System.out.print(r);   //  Print the result to STDOUT
}                        // End of method
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.