Tìm chuỗi con có nhiều nhất 1 trong chuỗi


16

Giới thiệu

Tôi muốn tìm chuỗi con có nhiều nhất 1trong một chuỗi các 01.

Đầu vào

Chương trình của bạn có hai đầu vào , chuỗi và độ dài chuỗi con.

Các chuỗi là bất kỳ số lượng 0's và 1' s:

01001010101101111011101001010100010101101010101010101101101010010110110110

Độ dài chuỗi con là bất kỳ số nguyên khác không dương:

5

Đầu ra

Chương trình của bạn sẽ xuất chỉ mục bắt đầu của chuỗi con đầu tiên có độ dài nhất định có chứa nhiều nhất 1. Với đầu vào trên, đầu ra là:

10

Ký tự đầu tiên trong chuỗi bắt đầu tại một chỉ mục của 0.

Chấm điểm

Mã ngắn nhất sẽ thắng!

Quy tắc

  • Chương trình của bạn phải luôn xuất chỉ mục chính xác cho bất kỳ đầu vào hợp lệ nào.
  • Bạn có thể chọn phương thức nhập / xuất từ ​​bất kỳ câu trả lời nào có điểm tích cực trên các tùy chọn mặc định . Vui lòng chỉ định phương pháp bạn chọn trong câu trả lời của bạn.

Tiêu đề và giới thiệu của bạn cho biết "tìm chuỗi con có nhiều nhất 1". Nhưng mô tả chương trình của bạn nói rằng bạn đang đưa ra độ dài chuỗi con và tìm kiếm chỉ mục của chuỗi con đầu tiên. Vì vậy, chúng ta nên cho rằng tiêu đề và giới thiệu là sai? Hầu hết mọi người dường như đang giải quyết phần đầu tiên. Ai thắng?
bước vào

@swstephe Tôi không chắc là tôi hiểu sự nhầm lẫn của bạn. Nếu có nhiều hơn một chuỗi con được buộc trong hầu hết các chuỗi 1, bạn xuất ra chuỗi con đầu tiên bạn tìm thấy. Bạn xác định các chuỗi con với chỉ mục của ký tự đầu tiên trong chuỗi con đó. cái đó có giúp ích không?
hmatt1

Được rồi, vì vậy bạn đang phá vỡ chuỗi trong chuỗi con và trả về chỉ mục của chuỗi con đầu tiên có nhiều nhất 1? Có vẻ như bạn đang tìm kiếm chuỗi con của 1.
bước vào

Yêu cầu "phải luôn luôn xuất chỉ mục chính xác cho bất kỳ đầu vào cụ thể nào" vẫn được áp dụng nếu chúng tôi đưa ra độ dài không khả thi, ví dụ: length = 99?
smci

@smci bạn có thể giả sử cho đầu vào hợp lệ. Bạn không phải xử lý trường hợp độ dài chuỗi con dài hơn chuỗi.
hmatt1

Câu trả lời:


11

Thuốc nhuộm APL, 11

(-∘1+⍳⌈/)+/

Hãy thử nó ở đây. Sử dụng:

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

Giải trình

Đây là một hàm dyadic (có nghĩa là nhị phân) lấy độ dài chuỗi con từ bên trái và chuỗi từ bên phải. Cấu trúc của nó là như sau:

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

Giải thích bằng vụ nổ:

(-∘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)

Ví dụ, hãy lấy 40 1 1 0 1 1 1 0làm đầu vào. Đầu tiên chúng ta áp dụng hàm +/cho chúng và lấy 2 3 3 3 3. Sau đó, +⌈/áp dụng cho mảng này tự cung cấp và 3, và 2 3 3 3 3 ⍳ 3đánh giá 2, vì 3lần đầu tiên xảy ra như là phần tử thứ hai. Chúng tôi trừ 1và nhận 1kết quả cuối cùng.


Trong ví dụ của bạn, độ dài là 4, nhưng không có 4 mục giống nhau trong một hàng (01101110), vậy tại sao nó lại xuất ra bất cứ thứ gì?
Thomas Weller

@ThomasW. Ví dụ trong thử thách cũng không có 5 mục giống nhau, và kết quả đầu ra là 10. Cách tôi diễn giải nhiệm vụ là tôi cần tìm chỉ mục đầu tiên của một chuỗi con có độ dài cho trước m, trong đó mcó tối đa.
Zgarb

10

Ruby, 42

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

Lấy đầu vào bằng cách gọi nó, vd

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

Điều này so sánh các chuỗi con bằng cách sử dụng tổng giá trị ASCII của chúng và trả về chỉ số tối đa. Tôi không chắc chắn nếu max_bythông số kỹ thuật của Ruby được yêu cầu phải ổn định nhưng có vẻ như nó đang được triển khai C.


6

Con trăn 2, 56

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

Chấp nhận một mảng các số nguyên, sau đó là chiều dài.


Điều này cần một mảng các số nguyên làm đầu vào, vì vậy nếu bạn bắt đầu bằng một chuỗi, bạn cần phải làm:[int(s) for s in "010010...0"]
smci 27/1/2015

Lỗi: f(ss, 999)sẽ trả về 0 (thay vì Không có). Bạn có thể sửa nó không? Điều này được cho là vi phạm quy tắc 1.
smci 27/1/2015

@smci Tôi không biết bạn đang nói về cái gì. Làm thế nào tôi có thể biết những gì trong biến ss? Nonekhông bao giờ là đầu ra mong muốn trong mọi trường hợp vì câu trả lời là một số nguyên.
frageum

5

Mẻ - 222

Batch rõ ràng là ngôn ngữ hoàn hảo cho loại hoạt động này.

@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!

Không chơi gôn / mổ xẻ:

Thiết lập ban đầu. Biến slà chuỗi đầu vào và lsẽ là độ dài của chuỗi đầu vào, trừ đi độ dài của chuỗi con (được khởi tạo ở âm %2trong đó %2là độ dài của chuỗi con đã cho).

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

Lấy độ dài của đầu vào dưới dạng l, sử dụng giải pháp độ dài chuỗi Batch thuần túy - điều này mang lại biến schứa chuỗi đầu vào, do đó chúng tôi sẽ đặt lại.

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

Giá trị của xđược sử dụng để kiểm tra chuỗi con nào có số lượng lớn nhất là 1. Bắt đầu một vòng lặp từ 0 đến độ dài của chuỗi, trừ đi độ dài của chuỗi con (biến l). Lấy chuỗi con bắt đầu từ điểm hiện tại trong vòng lặp ( %%a), cđược đặt làm chuỗi đầu vào bắt đầu từ %%avà lấy %2các ký tự (độ dài chuỗi con đã cho). Bất kỳ 0s nào được xóa khỏi c, sau đó giá trị của cđược so sánh với x- tức 111là một số lớn hơn 11vì vậy chúng ta chỉ có thể sử dụng 'chuỗi' để làm lớn hơn so với so sánh. ysau đó được đặt thành vị trí hiện tại trong chuỗi - cuối cùng được xuất ra.

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!

Sử dụng ví dụ OP -

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 thực tế không dài lắm, nhưng tất cả các lông tơ cần thiết cho một chương trình C # để biên dịch gấp đôi kích thước của mã.

Regex thực tế, đặt độ dài thành 5:

(?=((?<o>1)|0){5})(?!.+(?=[10]{5})(?!((?<-o>1)|0){5}))
  • (?=((?<o>1)|0){5}): Nhìn về phía trước để đọc 5 ký tự mà không tốn, và đẩy tất cả 1vào "ngăn xếp" o.
  • (?=[10]{5})(?!((?<-o>1)|0){5}): Tại một vị trí có 5 ký tự phía trước, không có đủ mục trong "ngăn xếp" ođể bật ra, tức là chuỗi con có nhiều 1hơn những gì chúng ta có ở vị trí hiện tại.
  • (?!.+(?=[10]{5})(?!((?<-o>1)|0){5})): Không thể tìm thấy một vị trí như được mô tả ở trên cho phần còn lại của chuỗi, tức là tất cả các vị trí có ít hơn hoặc bằng số 1's.

Lấy kết quả đầu tiên sẽ đưa ra câu trả lời, vì tất cả các chuỗi con phía trước nó đều có một số chuỗi con phía trước với nhiều hơn 1và chúng tôi đã kiểm tra xem bất kỳ chỉ số nào lớn hơn chỉ số hiện tại có ít hơn hoặc bằng số lượng của 1.

(Và tôi học được một điều hay: "ngăn xếp" được khôi phục khi quay lại).


1
Rất tuyệt, tôi sẽ không đoán bạn có thể làm điều này với một biểu thức chính quy.
lịch sử

4

Bình 12 tháng 12

Mho/<>GNHZUG

Điều này xác định một hàm g, trong đó yêu cầu một danh sách các số và một số làm đầu vào. Ví dụ

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

Bạn có thể kiểm tra nó ở đây: Trình biên dịch / thực thi Pyth

Giải trình:

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)

Thay thế:

Mho_s<>GNHUG

Bạn có thể nhận được câu trả lời có cùng độ dài bằng cách sử dụng chương trình lấy một chuỗi các giá trị (01001 ...) sau đó là số: ho/<>zNQ\0UzĐáng buồn thay, đếm trên một chuỗi không tự động chuyển đổi những gì bạn đang tìm kiếm thành một chuỗi :(
FryAmTheEggman

4

J, 15 14 ký tự

   ([:(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

Tôi thấy thú vị khi các ngôn ngữ thực đánh bại các ngôn ngữ được tạo riêng cho môn đánh gôn. Mục K của tôi đã bị ăn hoặc tôi đã đăng nó, nhưng dù sao nó cũng có tới 20 ký tự.
JasonN

4

Matlab (42)

Hãy sbiểu thị chuỗi và nđộ dài chuỗi con. Kết quả là r.

Tính tích chập svới một chuỗi các ncái, sau đó tìm cực đại. Chuyển đổi được thực hiện dễ dàng với convmaxhàm trả về vị trí của mức tối đa đầu tiên . Cần phải trừ đi 1chỉ số kết quả, bởi vì lập chỉ mục Matlab bắt đầu từ lúc 1không 0.

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

Chơi gôn

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

4

Haskell, 64 62 byte

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

Sử dụng:

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]

Bạn có thể lưu 2 byte bằng cách xác định hàm infix:n#l=...
Zgarb

bạn có thể sử dụng hàm infix cho p. Ngoài ra, tôi nghĩ 0là không cần thiết (mặc dù dấu ngoặc đơn không có và bạn có thể cần một khoảng trắng thay vì đó 0).
tự hào

3

JavaScript (ES6) 73

Một hàm trả về giá trị được yêu cầu. Vòng lặp for quét chuỗi đầu vào giữ tổng cộng đang chạy, lưu vị trí của giá trị tối đa.

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

Bị đánh cắp

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;
}

Kiểm tra trong bảng điều khiển FireFox / FireBug

F("01001010101101111011101001010100010101101010101010101101101010010110110110",5)

Đầu ra 10


Để giảm mã của bạn, bạn không cần xác định các biến xr. Điều này sẽ giảm 4 byte, là độ dài cuối cùng của 69 byte. Ngoài ra, bạn có thể có thể thay thế &&bằng &. Nhưng một trong những tốt đẹp với các ~~mẹo!
Ismael Miguel

@IsmaelMiguel bạn cần init x, lỗi khác lúc đầu t > x. Bạn cần init r: thử F("00000"). Và && là cần thiết để mô phỏng vàif
edc65

Bạn hoàn toàn đúng. Tôi không nhận thấy rằng bạn đang mong đợi nó bỏ qua (x=t, r=i-n+1)nếu tthấp hơn hoặc bằng x. Đó là một cách sử dụng tốt của đánh giá lười biếng! Tôi ước nó có thể bị băm nhỏ ở đâu đó, nhưng tôi đoán bạn đã làm tất cả công việc.
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

các biến $s$nnên được xác định trên dòng lệnh tương ứng với chuỗi tìm kiếm và độ dài chuỗi con.

Điều này cũng sẽ hoạt động trong bất kỳ ngôn ngữ giống như C với các chức năng phù hợp cho substr_count()strlen().


3

Toán học, 38 36

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

Thí dụ:

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]

Đầu ra:

10


2

C # (Linq), 148 byte

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());}}

Định dạng:

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()
        );
    }
}

Lấy đầu vào là tham số phương thức.

Những gì nó làm:

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

Scala - 70 byte

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

Nhưng với tên hàm miễn là zipWithIndex, tôi đoán Scala không phải là lựa chọn tốt nhất cho môn đánh gôn.


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);}

Định dạng:

#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);
}

Sử dụng:

$ ./m1s 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

1

CJam, 25 21 byte

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

Kiểm tra nó ở đây.

Lấy đầu vào là một số nguyên cho độ dài chuỗi con và một mảng các số 0 và một số dưới dạng chuỗi:

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]

Giải trình

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.";

Kết quả được in tự động vào cuối chương trình.

Lưu ý rằng tôi cũng đang xem xét các lát bắt đầu gần cuối hơn độ dài chuỗi con mong muốn, nhưng không sao, vì chúng là chuỗi con của chuỗi con hợp lệ cuối cùng và do đó sẽ không bao giờ có nhiều 1s hơn chuỗi con hợp lệ cuối cùng đó.


1

Java 329 byte

đã định cấy một .matches (regex), nhưng nó sẽ gần giống với các giải pháp python ở trên, vì vậy tôi đã thử một cửa sổ trượt thay thế. mới ở đây, vì vậy nếu bất cứ ai có bất kỳ con trỏ nào vui mừng khi nghe chúng.

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);
}

}


Một số mẹo: Bạn có thể khởi tạo itrong dòng thứ ba. Hầu hết các khoảng trắng có thể được loại bỏ. Sử dụng System.out.print((không cần dòng mới). Thay vì Integer.valueOf(, bạn có thể sử dụng new Integer(.
Ypnypn
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.