サブシーケンスの最大合計を見つける


11

整数のシーケンスが与えられた場合、シーケンスのサブシーケンス(連続した位置の整数)の最大合計を見つけます。サブシーケンスは空にすることができます(この場合、合計は0です)。

入力は標準入力から読み込まれ、1行に1つの整数が入ります。最大の合計を標準出力に書き込む必要があります。

私はあなたのために小さなジェネレータを書きました:

#include <stdio.h>
#include <assert.h>


/* From http://en.wikipedia.org/wiki/Random_number_generation */
unsigned m_w;
unsigned m_z;

unsigned get_random()
{
  m_z = 36969 * (m_z & 65535) + (m_z >> 16);
  m_w = 18000 * (m_w & 65535) + (m_w >> 16);
  return (m_z << 16) + m_w;  /* 32-bit result */
}

int main(int argc, char **argv)
{
  int i;

  assert(argc == 3);
  m_w = atoi(argv[1]);
  m_z = atoi(argv[2]);

  i = 10;
  while (i--);
    get_random();

  i = atoi(argv[2]);
  while (i--)
    printf("%d\n", (int) get_random() << 8 >> 22);

  return 0;
}

例:

$ printf "1\n2\n-1\n4\n" | ./sum
6
$ printf "0\n-2\n-3\n" | ./sum
0

$ ./a.out 1 1 | ./sum
387
$ ./a.out 1 10 | ./sum
571
$ ./a.out 1 100 | ./sum
5867
$ ./a.out 1 1000 | ./sum
7531
$ ./a.out 1 10000 | ./sum
27268
$ ./a.out 1 100000 | ./sum
101332
$ ./a.out 1 1000000 | ./sum
187480
$ ./a.out 1 10000000 | ./sum
666307
  • ./sum 私の解決策です
  • ./a.out ジェネレーターです

ソリューションは、上記のすべてのテストに対して妥当な時間内に実行する必要があります(前回のテストケースでは1.2秒で実行されます)。

最短のコードが優先されます。

編集:上記のテストのいずれかで実行した例を提供してください。


が必要#include <stdlib.h>ですatoi()
ポールR

私自身のcソリューションは、最後のテストケースで4秒かかり、ソリューションに非常に興味があります。
Dongshengcn

最初にファイルに書き込み、次にファイルから読み取り、パイプを使用しないようにしてください。
アレクサンドル

25行目のジェネレータにエラーがあると思いますwhile (i--);が、セミコロンで終わるべきではありませんか?
ユーザー不明

assert(argc == 3):-)それは私がユーザーフレンドリーなプログラムと呼んでいるものです!:-)
エマニュエルランドホルム

回答:


3

ルビー、53文字

p$<.inject(-1.0/s=0){|a,b|[s=[0,s+b.to_i].max,a].max}

ここの最後のテストケースには約28秒かかります。


6

Python、91 84 64文字

s=m=0
try:
 while 1:s=max(s+input(),0);m=max(m,s)
except:print m

最後のテストケースで約14 12 72秒かかります。編集:Paul Rが見つけたアルゴリズムを使用。編集:を使用してインポートを無効にしましたinput()


6

C、100文字


main(){char s[80];int i,m=0,n=0;while(gets(s)){i=atoi(s);n=n+i>0?n+i:0;m=m>n?m:n;}printf("%d\n",m);}


ICC 11.1を使用した2.67 GHz Core i7での最終テストケース(10000000) 実行時間= 1.14秒(以前:gcc 4.2.1を使用すると1.44秒)。

注:上記のソリューションに使用されるアルゴリズムは、Jon BentleyによるProgramming Pearlsからのものです。どうやらこのアルゴリズムは、カダネのアルゴリズムとして知られています。


3

ハスケル(88 64)

Kadaneのアルゴリズムの実装。

main=interact$show.maximum.scanr(\x->max x.(x+))0.map read.lines

2

Python-114文字

import sys
s=map(int,sys.stdin.readlines())
l=range(len(s)+1)
print`max(sum(s[i:j])for i in l[:-1]for j in l[i:])`

それは確かに必要なほど高速ではありませんが、問題なく動作します。


これはO(N ^ 2)であり、チャレンジの要件を確実に満たしません。
アレクサンドル

2

Python、動的プログラミングを使用-92文字

import sys
s=map(int,sys.stdin.readlines())
f=h=0
for x in s:h=max(0,h+x);f=max(f,h)
print f

2

J(34 33文字)

このソリューションはKadaneのアルゴリズムのバリアントを実装し、妥当な速度です。

echo>./0,([>.+)/\.0".];._2(1!:1)3

説明は次のとおりです。

  • u/ y–の項目間にu 挿入される動詞y。たとえば、の+/ 1 2 3 4ようなもの1 + 2 + 3 + 4です。あるJ中のすべての動詞は右関連していることを通知は、-/ 1 2 3 4似ている1 - (2 - (3 - 4))との交互の和を計算します1 2 3 4
  • x >. yxおよびの最大値y
  • x ([ >. +) yxおよびの最大値x + y[ >. +は暗黙の記法の動詞であり、と同じに評価されx >. x + yます。
  • ([ >. +)/ yy合計が最大のの空でないプレフィックス。
  • u\. y–のuすべての接尾辞に適用されますy。特別なコードは、u/\. y2次時間ではなく線形で実行されるように一般的なケースを処理することに注意してください。
  • ([ >. +)/\. y–の各位置から始まる最大の空でない部分配列を示すベクトルy
  • 0 , ([ >. +)/\. y–の0空のサブ0配列の長さと同様に、前の結果の前に追加されyます。
  • >./ 0 , ([ >. +)/\. y–の最大の部分配列y
  • 0 ". ];._2 (1!:1) 3 –数値のベクトルにマーシャリングされた標準入力。
  • >./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3 –標準入力の最大のサブアレイ。

1

ルビー、68文字

m=-2**31;n=0;$<.lines.map{|x|n+=x.to_i;n=0 if n<0;m=n if n>m};puts m

また、少し遅いですが、1分から10000000回のテストを30分強で完了します。ほとんどの時間は最後のテストに費やしました...

インデントされたバージョン:

m=-2**31
n=0
$<.lines.map {|x|
  n+=x.to_i
  n=0 if n<0
  m=n if n>m
}
puts m

1

C ++、192文字

#include <iostream>
#include <string>
#include <stdlib.h>
#define S std::
main(){long a=0,m=0,M=0;char s[9];while(S cin.getline(s,9)){a+=atoi(s);if(m>a)m=a;if(M<a-m)M=a-m;}S cout<<M<<S endl;}

私のラップトップではかなり高速に動作します(最後のテストでは4秒)。


cstdlibないstdlib.h
オールドリンブ

1
{if((r+$1)>0)
   r=r+$1 
 else r=0; 
 if(m<r) 
   m=r;
}
END{print m}

awkコード(66)、非常に遅い、最後のテストケースで8秒以上

dwang@dwang-ws ~/Playground/lss $ time ./random 1 10000000 | awk -f lss.awk
666307

real    0m6.705s
user    0m8.671s
sys 0m0.052s
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.