ค้นหาสตริงย่อยที่มีค่ามากที่สุด 1 ลำดับ


16

บทนำ

ฉันต้องการที่จะหาย่อยที่มีมากที่สุด1's ในลำดับของ0' และ1's

อินพุต

โปรแกรมของคุณมีสองอินพุตลำดับและความยาวซับสตริง

ลำดับคือจำนวนใด ๆ0'และ1' s:

01001010101101111011101001010100010101101010101010101101101010010110110110

ยาว substringเป็นที่ไม่ใช่ศูนย์จำนวนเต็มบวกใด ๆ

5

เอาท์พุต

โปรแกรมของคุณควรส่งออกดัชนีเริ่มต้นของ substring แรกของการกำหนดความยาวที่มีมากที่สุด1's ด้วยอินพุตข้างต้นผลลัพธ์คือ:

10

0ตัวอักษรตัวแรกในสตริงเริ่มต้นที่ดัชนีของ

เกณฑ์การให้คะแนน

รหัสที่สั้นที่สุดชนะ!

กฎระเบียบ

  • โปรแกรมของคุณจะต้องส่งออกดัชนีที่ถูกต้องสำหรับอินพุตที่ถูกต้องใด ๆ
  • คุณสามารถเลือกวิธีการอินพุต / เอาต์พุตของคุณจากคำตอบใด ๆ ที่มีคะแนนบวกเกี่ยวกับตัวเลือกเริ่มต้น โปรดระบุวิธีการที่คุณเลือกในคำตอบของคุณ

ชื่อและคำแนะนำของคุณบอกว่า "ค้นหาสตริงย่อยที่มี 1 รายการมากที่สุด" แต่คำอธิบายโปรแกรมของคุณบอกว่าคุณให้ความยาวสตริงย่อยและค้นหาดัชนีของสตริงย่อยแรก ดังนั้นเราควรสมมติว่าชื่อและบทนำผิดหรือเปล่า? คนส่วนใหญ่ดูเหมือนจะแก้ไขส่วนแรก ใครชนะ?
swstephe

@swstephe ฉันไม่แน่ใจว่าฉันเข้าใจความสับสนของคุณ หากมีสตริงย่อยมากกว่าหนึ่งรายการเชื่อมโยงกับส่วนใหญ่1คุณจะแสดงสตริงย่อยแรกที่พบ คุณระบุสตริงย่อยด้วยดัชนีของอักขระตัวแรกในสตริงย่อยนั้น มันช่วยได้ไหม
hmatt1

ตกลงดังนั้นคุณกำลังทำลายลำดับในสตริงย่อยและส่งกลับดัชนีของสตริงย่อยแรกที่มี 1 ค่ามากที่สุดหรือไม่ ดูเหมือนว่าคุณกำลังมองหาสตริงย่อยของ 1 รายการ
swstephe

ความต้องการ "ต้องส่งออกดัชนีที่ถูกต้องสำหรับอินพุตที่กำหนด" ยังคงใช้อยู่หรือไม่หากเราให้ความยาวที่ไม่สามารถทำได้เช่น length = 99
smci

@smci คุณสามารถถือว่าอินพุตที่ถูกต้อง คุณไม่ต้องจัดการกับกรณีที่ความยาวซับสตริงยาวกว่าลำดับ
hmatt1

คำตอบ:


11

Dyalog APL, 11

(-∘1+⍳⌈/)+/

ลองที่นี่ การใช้งาน:

   f ← (-∘1+⍳⌈/)+/
   4 f 0 1 1 0 1 1 1 0 0 0 0 1 1
1

คำอธิบาย

นี่คือฟังก์ชัน dyadic (หมายถึงไบนารี) ที่รับความยาวซับสตริงจากด้านซ้ายและลำดับจากด้านขวา โครงสร้างของมันมีดังต่อไปนี้:

   ┌───┴────┐
 ┌─┴──┐     /
 ∘  ┌─┼─┐ ┌─┘
┌┴┐ + ⍳ / +  
- 1   ┌─┘    
      ⌈      

คำอธิบายจากการระเบิด:

(-∘1+⍳⌈/)+/
(       )+/  ⍝ Take sums of substrings of given length, and feed to function in parentheses
    + ⌈/     ⍝ The array of sums itself, and its maximum
     ⍳       ⍝ First index of right argument in left
 -∘1         ⍝ Subtract 1 (APL arrays are 1-indexed)

ตัวอย่างเช่นลองทำ4และ0 1 1 0 1 1 1 0เป็นอินพุต ครั้งแรกที่เราใช้ฟังก์ชั่นให้กับพวกเขาและได้รับ+/ 2 3 3 3 3จากนั้น+และ⌈/นำไปใช้กับอาร์เรย์นี้ให้ตัวเองและ3และ2 3 3 3 3 ⍳ 3ประเมินผล2ตั้งแต่3แรกเกิดขึ้นเป็นองค์ประกอบที่สอง เราลบ1และรับ1ผลสุดท้าย


ในตัวอย่างของคุณความยาวคือ 4 แต่ไม่มี 4 รายการเดียวกันในแถว (01101110) ดังนั้นทำไมมันจึงส่งออกอะไรเลย
โทมัสเวลเลอร์

@ThomasW ตัวอย่างในความท้าทายที่ไม่ได้มี 5 รายการเดียวกันในแถวอย่างใดอย่างหนึ่งและยังส่งออกเป็น 10 วิธีที่ผมตีความงานคือว่าผมต้องไปหาดัชนีแรกของการย่อยของระยะเวลาที่กำหนดที่มีmคนที่mเป็น สูงสุด.
Zgarb

10

ทับทิม, 42

f=->s,n{(0..s.size).max_by{|i|s[i,n].sum}}

รับอินพุตโดยเรียกมันเช่น

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

สิ่งนี้เปรียบเทียบสตริงย่อยโดยใช้ค่า ASCII ทั้งหมดและส่งคืนดัชนีสูงสุด ฉันไม่แน่ใจว่าmax_byข้อมูลจำเพาะทับทิมจำเป็นต้องมีเสถียรภาพหรือไม่ แต่ดูเหมือนว่าจะอยู่ในการใช้งาน C


6

Python 2, 56

lambda s,l:max(range(len(s)),key=lambda i:sum(s[i:i+l]))

ยอมรับอาร์เรย์ของจำนวนเต็มตามด้วยความยาว


นี้ต้องอาร์เรย์ของจำนวนเต็มเป็น input ดังนั้นหากคุณเริ่มต้นด้วยสตริงที่คุณต้องทำ:[int(s) for s in "010010...0"]
smci

Bug: f(ss, 999)จะคืนค่า 0 (แทนที่จะเป็น None) คุณสามารถแก้ไขได้ไหม เนื้อหานี้ละเมิดกฎข้อที่ 1
smci

@smci ฉันไม่รู้ว่าคุณกำลังพูดถึงอะไร ฉันควรจะรู้ว่าสิ่งที่อยู่ในตัวแปรssหรือไม่ Noneไม่เคยเป็นผลลัพธ์ที่ต้องการในทุกกรณีเนื่องจากคำตอบคือจำนวนเต็ม
feersum

5

รุ่นที่ - 222

เห็นได้ชัดว่าแบทช์เป็นภาษาที่สมบูรณ์แบบสำหรับการทำงานประเภทนี้

@echo off&setLocal enableDelayedExpansion&set s=%1&set l=-%2
:c
if defined s set/Al+=1&set "s=%s:~1%"&goto c
set s=%1&set x=0&for /l %%a in (0,1,%l%)do set c=!s:~%%a,%2!&set c=!c:0=!&if !c! GTR !x! set x=!c!&set y=%%a
echo !y!

Un-golfed / dissected:

ตั้งค่าเริ่มต้น. ตัวแปรsคือสตริงอินพุตและlจะเป็นความยาวของสตริงอินพุตลบความยาวสตริงย่อย (เริ่มต้นที่ลบ%2ซึ่ง%2เป็นความยาวสตริงย่อยที่กำหนด)

@echo off
setLocal enableDelayedExpansion
set s=%1
set l=-%2

รับความยาวของอินพุตlโดยใช้โซลูชันความยาวสตริงแบตช์บริสุทธิ์ซึ่งจะทำให้ตัวแปรsมีสตริงอินพุตอยู่ดังนั้นเราจึงตั้งค่าอีกครั้ง

:c
if defined s (
    set /A l += 1
    set "s=%s:~1%"
    goto c
)
set s=%1

ค่าของxใช้เพื่อตรวจสอบว่าสตริงย่อยใดมีจำนวนมากที่สุด 1 รายการ เริ่มการวนซ้ำตั้งแต่ 0 ถึงความยาวของสตริงลบความยาวของสตริงย่อย (ตัวแปรl) รับสตริงย่อยเริ่มต้นจากจุดปัจจุบันในลูป ( %%a) cตั้งเป็นสตริงอินพุตเริ่มต้นที่%%aและ%2อักขระ (ความยาวสตริงย่อยที่กำหนด) ค่าใด ๆ0จะถูกลบออกจากcนั้นค่าของการcเปรียบเทียบกับx- 111คือจำนวนที่มากกว่า11เราจึงสามารถใช้ 'สตริง' เพื่อทำมากกว่าการเปรียบเทียบ yถูกตั้งค่าเป็นตำแหน่งปัจจุบันในสตริง - ซึ่งเป็นผลลัพธ์ในที่สุด

set x=0
for /l %%a in (0, 1, %l%) do (
    set c=!s:~%%a,%2!
    set c=!c:0=!
    if !c! GTR !x! (
        set x=!c!
        set y=%%a
    )
)
echo !y!

ใช้ตัวอย่าง OPs -

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

5

C # (Regex), 196

class Test{static void Main(string[]a){System.Console.Write(System.Text.RegularExpressions.Regex.Match(a[1],"(?=((?<o>1)|0){"+a[0]+"})(?!.+(?=[10]{"+a[0]+"})(?!((?<-o>1)|0){"+a[0]+"}))").Index);}}

regex ที่เกิดขึ้นจริงนั้นไม่นานนัก แต่ตัว fluff ทั้งหมดที่จำเป็นสำหรับโปรแกรม C # ในการรวบรวมขนาดของรหัสสองเท่า

regex จริงตั้งค่าความยาวเป็น 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): มองไปข้างหน้าในการอ่าน 5 ตัวอักษรโดยไม่ต้องบริโภคและผลักดันให้ทุก1ท่านเข้า o'กอง'
  • (?=[10]{5})(?!((?<-o>1)|0){5}): ที่ตำแหน่งที่มีอักขระ 5 ตัวอยู่ข้างหน้ามีรายการไม่เพียงพอใน "สแต็ก" ที่oจะโผล่ออกมานั่นคือสตริงย่อยมี1มากกว่าสิ่งที่เรามีในตำแหน่งปัจจุบันอย่างเคร่งครัด
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): ตำแหน่งตามที่อธิบายไว้ข้างต้นไม่สามารถพบได้สำหรับส่วนที่เหลือของสตริงคือทุกตำแหน่งมีน้อยกว่าหรือเท่ากับจำนวน1ของ

การผลแรกให้คำตอบตั้งแต่สตริงทั้งหมดในด้านหน้าของมันมีบางส่วน substring ข้างหน้ามีมากขึ้น1's และเรามีการตรวจสอบว่าดัชนีมีขนาดใหญ่กว่าดัชนีปัจจุบันมีน้อยกว่าหรือเท่ากับจำนวน1ของ

(และฉันเรียนรู้สิ่งที่ดี: "สแต็ค" ถูกเรียกคืนจากการย้อนรอย)


1
เจ๋งมากฉันไม่คิดว่าคุณจะทำมันได้ด้วย regex
ประวัติศาสตร์

4

Pyth , 12

Mho/<>GNHZUG

ฟังก์ชันนี้กำหนดฟังก์ชันgซึ่งต้องการรายการตัวเลขและตัวเลขเป็นอินพุต เช่น

Mho/<>GNHZUGg[0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0)5

คุณสามารถทดสอบได้ที่นี่: Pyth Compiler / Executor

คำอธิบาย:

Mho/<>GNHZUG
M             defines a function g(G,H), G is the sequence, H the sequence length
  o       UG  orders the numbers between 0 and len(G)-1 according to the following key
    <>GNH     take the subsequence G[N:N+5]
   /     Z    count the zeros in this subsequence (this is the key)
 h            return the first value of the sorted list (minimum)

ทางเลือก:

Mho_s<>GNHUG

คุณสามารถได้คำตอบที่มีความยาวเท่ากันโดยใช้โปรแกรมที่รับค่าสตริง (01001 ... ) จากนั้นจำนวน: ho/<>zNQ\0Uzน่าเสียดายที่การนับบนสตริงจะไม่แปลงสิ่งที่คุณต้องการเป็นสตริงโดยอัตโนมัติ :(
FryAmTheEggman

4

J, 15 14 ตัวอักษร

   ([:(i.>./)+/\)

   5 ([:(i.>./)+/\) 0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0
10

ฉันพบว่ามันน่าสนใจเมื่อภาษาจริงเอาชนะภาษาที่สร้างขึ้นโดยเฉพาะสำหรับการตีกอล์ฟ รายการ K ของฉันถูกกินหรือฉันจะโพสต์ไว้ แต่มันมาถึง 20 ตัวอักษรต่อไป
JasonN

4

Matlab (42)

อนุญาตsแสดงว่าสตริงและnความยาว substring rผลที่ได้คือ

คำนวณการsหาลำดับของnสิ่งที่มีอยู่แล้วหาค่าสูงสุด Convolution สามารถทำได้อย่างง่ายดายด้วยconvและmaxฟังก์ชันจะคืนค่าตำแหน่งของค่าสูงสุดแรก มันเป็นสิ่งจำเป็นที่จะลบ1ที่จะส่งผลให้ดัชนีเพราะ Matlab การจัดทำดัชนีเริ่มต้นที่ไม่10

[~, r] = max(conv(s, ones(1,n), 'valid'));
r = r-1;

แข็งแรงเล่นกอล์ฟ:

[~,r]=max(conv(s,ones(1,n),'valid'));r=r-1

4

Haskell, 64 62 ไบต์

n#l=0-(snd$maximum[(sum$take n$drop x l,-x)|x<-[0..length l]])

การใช้งาน:

5#[0,1,0,0,1,0,1,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0]

คุณสามารถบันทึก 2 ไบต์โดยกำหนดฟังก์ชั่นมัด:n#l=...
Zgarb

pคุณสามารถใช้ฟังก์ชั่นสำหรับมัด ฉันคิดว่า0มันซ้ำซ้อน (แม้ว่าจะไม่ได้เป็นวงเล็บและคุณอาจต้องการช่องว่างแทนที่จะเป็น0)
ภูมิใจ Haskeller

3

JavaScript (ES6) 73

ฟังก์ชันส่งคืนค่าที่ร้องขอ สำหรับลูปจะสแกนสตริงอินพุตที่รักษาผลรวมสะสมไว้บันทึกตำแหน่งของค่าสูงสุด

F=(a,n)=>(x=>{for(r=t=i=x;a[i];t>x&&(x=t,r=i-n))t+=a[i]-~~a[i++-n]})(0)|r

Ungolfed

F=(a, n) => {
   for(x = r = t = i = 0; a[i]; i++)
     t += a[i] - ~~a[i-n], // ~~ convert undefined values (at negative index) to 0
     t > x && (x=t, r=i-n+1);
   return r;
}

ทดสอบในคอนโซล FireFox / FireBug

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

เอาท์พุต 10


เพื่อลดรหัสของคุณคุณไม่จำเป็นต้องกำหนดตัวแปรและx rสิ่งนี้ควรลด 4 ไบต์เป็นความยาวสุดท้ายของ 69 ไบต์ นอกจากนี้คุณอาจอาจจะสามารถแทนที่ด้วย&& &แต่สิ่งที่ดีกับ~~เคล็ดลับ!
Ismael Miguel

@IsmaelMiguel คุณต้อง init x ข้อผิดพลาดอื่น ๆ t > xในตอนแรก คุณจำเป็นต้อง init r: F("00000")ลอง และ && จำเป็นต้องจำลองและif
edc65

คุณพูดถูก ผมไม่ได้สังเกตเห็นว่าคุณได้รับการคาดหวังว่ามันจะไม่สนใจ(x=t, r=i-n+1)ถ้าต่ำกว่าหรือเท่ากับt xนั่นเป็นการใช้การประเมินที่ขี้เกียจดี! ฉันหวังว่ามันจะถูกสับไปที่ไหนสักแห่ง แต่ฉันคิดว่าคุณทำทุกอย่างเรียบร้อยแล้ว
Ismael Miguel

3

PHP (96)

for($a=$b=$c=0;(($d=@substr_count($s,1,$a,$n))>$c&&($b=$a)&&($c=$d))||$a++<strlen($s););echo $b;

http://3v4l.org/J4vqa

ตัวแปร$sและ$nควรกำหนดไว้บนบรรทัดคำสั่งเพื่อค้นหาสตริงและความยาวสตริงย่อยตามลำดับ

นอกจากนี้ยังจะทำงานในภาษา C เหมือนใด ๆ กับฟังก์ชั่นที่เหมาะสมสำหรับการและ substr_count()strlen()


3

Mathematica, 38 36

f=#-1&@@Ordering[-MovingAverage@##]&

ตัวอย่าง:

f[{0,1,0,0,1,0,1,0,1,0,1,1,0,1,1,1,1,0,1,1,1,0,1,0,0,1,0,1,0,1,0,0,0,1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,1,0},5]

เอาท์พุท:

10


2

C # (Linq), 148 ไบต์

using System.Linq;class C{int F(string s,int l){return s.IndexOf(s.Skip(l-1).Select((c,i)=>s.Substring(i,l)).OrderBy(p=>-p.Sum(c=>c)).First());}}

จัดรูปแบบ:

using System.Linq;

class C
{
    int F(string s, int l)
    {
        return s.IndexOf(
            s
                .Skip(l - 1)
                .Select((c, i) => s.Substring(i, l))
                .OrderBy(p => -p.Sum(c => c))
                .First()
        );
    }
}

รับอินพุตเป็น params เมธอด

มันทำอะไร:

string result = s // string is also char collection
    .Skip(l - 1) // make it collection shorter by l-1
    .Select((c, i) => s.Substring(i, l)) // so we can iterate, and select all substrings
    .OrderBy(p => -p.Sum(c => c)) // order substrings descending by sum of characters
    .First() // take first (most ones)

return s.IndexOf(result); // find index of result string

2

สกาลา - 70 ไบต์

readLine.sliding(readInt).zipWithIndex.maxBy(x=>x._1.count(_=='1'))._2

แต่ด้วยฟังก์ชั่นชื่อตราบใดที่zipWithIndexฉันเดาว่า Scala ไม่ใช่ตัวเลือกที่ดีที่สุดสำหรับการเล่นกอล์ฟ


2

C, 245 185

#include <stdio.h>
main(int argc,char **argv){char *p,*q;int i,s,m=0;for(p=argv[1];*p;p++){for(s=0,q=p;q-p<atoi(argv[2])&&*q;q++)s+=*q-'0';if(s>m){m=s;i=p-argv[1];}}printf("%d\n", i);}

จัดรูปแบบ:

#include <stdio.h>
main(int argc, char **argv) {
        char *p, *q;
        int i, s, m = 0;
        for (p = argv[1]; *p; p++) {
                for (s = 0, q = p; q - p < atoi(argv[2]) && *q; q++)
                        s += *q - '0';
                if (s > m) {
                        m = s;
                        i = p - argv[1];
                }
        }
        printf("%d\n", i);
}

การใช้งาน:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

1

CJam, 25 21 ไบต์

q~_,,{1$>2$<:+~}$(]W=

ทดสอบที่นี่

รับอินพุตเป็นจำนวนเต็มสำหรับความยาวสตริงย่อยและอาร์เรย์เป็นศูนย์และอันตามลำดับ:

5 
[0 1 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 0 1 0 1 1 0 1 1 0 1 1 0]

คำอธิบาย

q~_,,{1$>2$<:+~}$(p];
q~                    "Read and evaluate the input.";
  _,                  "Duplicate the sequence and get its length N.";
    ,                 "Get an array [0 1 ... N-1].";
     {         }$     "Sort this array stably by the result of the given block.";
      1$              "Copy the sequence.";
        >             "Slice off the first i bits.";
         2$           "Copy the substring length.";
           <          "Truncate the sequence.";
            :+        "Get the sum to find the number of 1s.":
              ~       "Bitwise complement in order to sort from highest to lowest.";
                 (    "Shift off the first index from the sorted list.";
                  ]   "Wrap the entire stack in an array.";
                   W= "Extract the last element (the result), discarding the rest.";

ผลลัพธ์จะถูกพิมพ์โดยอัตโนมัติเมื่อสิ้นสุดโปรแกรม

โปรดทราบว่าฉันกำลังพิจารณาชิ้นส่วนที่เริ่มต้นใกล้กับจุดสิ้นสุดมากกว่าความยาวสตริงย่อยที่ต้องการ แต่ก็ไม่เป็นไรเพราะมันเป็นสตริงย่อยของสตริงย่อยที่ถูกต้องล่าสุดและดังนั้นจึงจะไม่มี1สตริงย่อยที่ถูกต้องล่าสุด


1

Java 329 ไบต์

กำลังจะปลูกฝัง. จับคู่ (regex) แต่มันจะใกล้เคียงกับโซลูชั่นของไพ ธ อนด้านบนดังนั้นฉันจึงลองใช้หน้าต่างบานเลื่อนแทน ใหม่ที่นี่ดังนั้นหากใครมีคำแนะนำใด ๆ ยินดีที่จะได้ยินพวกเขา

public class ssMostOnes{
public static void main(String[] a){
    int b=0,w=0;
    for(int i=0;i<a[0].length()-Integer.valueOf(a[1]);i++){
        int c=a[0].substring(i,i+Integer.valueOf(a[1])).length() - a[0].substring(i,i+Integer.valueOf(a[1])).replace("1","").length();
        if(c>w){w=c;b=i;}
    }
    System.out.println(b);
}

}


เคล็ดลับ: คุณสามารถเริ่มต้นiในบรรทัดที่สาม ช่องว่างส่วนใหญ่สามารถลบได้ ใช้System.out.print((ไม่จำเป็นต้องขึ้นบรรทัดใหม่) แทนที่จะคุณสามารถใช้Integer.valueOf( new Integer(
Ypnypn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.