시퀀스에서 1이 가장 많은 부분 문자열 찾기


16

소개

내가 가장과 문자열 찾으려면 1'의 순서로들 0들과' 1의.

입력

프로그램에는 시퀀스와 부분 문자열 길이의 두 가지 입력이 있습니다.

그만큼 순서는 임의의 수입니다 0's와 1의 :

01001010101101111011101001010100010101101010101010101101101010010110110110

그만큼 하위 문자열 길이는 임의의 0이 아닌 양의 정수 :

5

산출

프로그램은 주어진 길이의 첫 번째 부분 문자열의 시작 색인을 가장 많이 포함해야합니다. 1 . 위의 입력에서 출력은 다음과 같습니다.

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

설명

이것은 왼쪽에서 부분 문자열 길이와 오른쪽에서 순서를 취하는 2 차원 (이진수 의미) 함수입니다. 그 구조는 다음과 같습니다.

   ┌───┴────┐
 ┌─┴──┐     /
 ∘  ┌─┼─┐ ┌─┘
┌┴┐ + ⍳ / +  
- 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)

예를 들어, 이제 봅시다 40 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) 왜 아무것도 출력하지 않습니까?
Thomas Weller

@ThomasW. 챌린지의 예제에는 행에 5 개의 동일한 항목이 없지만 출력은 10입니다. 작업을 해석하는 방법은 주어진 길이의 하위 문자열에서 첫 번째 색인을 찾아야한다는 mm입니다. 최대.
Zgarb

10

루비, 42

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

호출하여 입력을받습니다. 예 :

f['01001010101101111011101001010100010101101010101010101101101010010110110110',5]

총 ASCII 값을 사용하여 하위 문자열을 비교하고 최대 색인을 반환합니다. max_byRuby 사양이 안정적이어야 하는지 확실하지 않지만 C 구현에있는 것 같습니다.


6

파이썬 2, 56

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

정수 배열과 길이를 허용합니다.


여기에는 입력으로 정수 배열이 필요하므로 문자열로 시작하면 다음을 수행해야합니다.[int(s) for s in "010010...0"]
smci

버그 : f(ss, 999)None 대신 0을 반환합니다. 고칠 수 있습니까? 이것은 틀림없이 규칙 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!

골퍼 해제 / 해부 :

초기 설정. 변수 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

값은 x1이 가장 큰 하위 문자열을 확인하는 데 사용됩니다. 하위 문자열 길이 (변수 l)를 빼고 0에서 문자열 길이까지 루프를 시작합니다 . 루프의 현재 지점에서 시작하여 하위 문자열을 가져오고 ( %%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!

OP 사용 예-

h:\>sub1.bat 01001010101101111011101001010100010101101010101010101101101010010110110110 5
10

5

196 년 C # (Regex)

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

실제 정규 표현식은 그리 길지 않지만 C # 프로그램이 코드 크기의 두 배를 컴파일하는 데 필요한 모든 보풀이 있습니다.

길이를 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.

첫 번째 결과를 취하면 답이 나옵니다. 앞에있는 모든 하위 문자열에는 더 많은 하위 문자열이 있기 때문에 1 이 있고 현재 인덱스보다 큰 인덱스의 수보다 작거나 같은지 확인하기 수 1있습니다.

(그리고 나는 좋은 것을 배운다 : "스택"은 역 추적시 복원된다.


1
매우 멋지다. 정규 표현식 으로이 작업을 수행 할 수 있다고 짐작하지 못했습니다.
histocrat

4

피 이스 , 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문자열 길이를. 결과는 r입니다.

s일련의 시퀀스로 컨벌루션을 계산 n한 다음 최대 값을 찾으십시오. 컨볼 루션은 쉽게 이루어집니다 conv, 그리고 max기능의 위치를 반환 첫째 최대. 1Matlab 인덱싱은에서 시작 1하지 않기 때문에 결과 인덱스 로 빼야 합니다 0.

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

골프 :

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

4

하스켈, 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

에 대한 infix 함수를 사용할 수 있습니다 p. 또한, 나는 0중복 이라고 생각합니다 (괄호는 아니지만 0) 대신 공백이 필요할 수 있습니다 .
자랑스런 Haskeller

3

자바 스크립트 (ES6) 73

요청 된 값을 반환하는 함수입니다. for 루프는 누적 합계를 유지하면서 입력 문자열을 스캔하여 최대 값의 위치를 ​​저장합니다.

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

언 골프

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


코드를 줄이기 위해, 당신은 변수를 정의 할 필요가 없습니다 xr. 최종 길이는 69 바이트 인 4 바이트를 줄여야합니다. 또한, 당신은 아마 대체 할 수 있습니다 &&&. 그러나 ~~트릭이 좋은 사람 !
Ismael Miguel

@IsmaelMiguel x를 초기화해야합니다 t > x. 그렇지 않으면 처음에는 오류가 발생 합니다. r을 초기화해야합니다 : try F("00000"). 그리고 &&는 에뮬레이션을 위해 필요하며if
edc65

당신은 완전히 옳습니다. 보다 작거나 같은 (x=t, r=i-n+1)경우 무시할 것으로 예상되는 것을 보지 못했습니다 . 게으른 평가를 잘 사용합니다! 어딘가에서 잘릴 수 있었으면 좋겠지 만 모든 작업을 완료했다고 생각합니다. tx
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

매스 매 티카, 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()
        );
    }
}

메소드 매개 변수로 입력을받습니다.

그것이하는 일 :

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=

여기에서 테스트하십시오.

입력을 부분 문자열 길이의 정수로, 0과 1의 배열을 시퀀스로 취합니다.

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마지막 유효한 부분 문자열보다 더 많은 s를 가지지 않기 때문에 괜찮습니다 .


1

자바 329 바이트

.matches (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.