查找序列中具有最大1的子字符串


16

介绍

我想找到最子串1的在序列0的和1的。

输入值

您的程序有两个输入,即序列和子字符串长度。

序列是任意数量的0“和1”:

01001010101101111011101001010100010101101010101010101101101010010110110110

子串长度是任意的正的非零整数:

5

输出量

您的程序应输出给定长度的第一个子串的起始索引,该子串包含最多1的。使用以上输入,输出为:

10

字符串中的第一个字符从索引处开始0

计分

最短的代码胜出!

规则

  • 您的程序必须始终为任何有效输入输出正确的索引。
  • 您可以从默认选项为正的任何答案中选择输入/输出方法。请指定您在答案中选择的方法。

您的标题和简介说“找到最大1的子字符串”。但是您的程序描述说您要给出一个子串的长度,并寻找第一个子串的索引。那么,我们应该假设标题和简介错误吗?大多数人似乎正在解决第一部分。谁赢?
swstephe 2015年

@swstephe我不确定我是否理解您的困惑。如果最多有多个子字符串绑定在一起,则1输出找到的第一个子字符串。您用该子字符串中第一个字符的索引标识子字符串。有帮助吗?
hmatt1

好的,因此您要破坏子字符串的顺序,并返回第一个具有最大1的子字符串的索引?听起来您正在寻找1的子字符串。
swstephe 2015年

如果我们给出了不可行的长度(例如,length = 99),“是否必须始终为任何给定输入输出正确的索引”的要求是否仍然适用?
smci 2015年

您可以假定@smci为有效输入。您不必处理子串长度比序列长的情况。
hmatt1 2015年

Answers:


11

Dyalog APL,11

(-∘1+⍳⌈/)+/

在这里尝试。用法:

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

说明

这是一个二进位(含义为二进制)函数,该函数从左开始获取子串长度,从右开始获取序列。其结构如下:

   ┌───┴────┐
 ┌─┴──┐     /
 ∘  ┌─┼─┐ ┌─┘
┌┴┐ + ⍳ / +  
- 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.我解释了任务的方式是,我需要找到指定的长度有一个字符串的第一个指数m的,这里m是最大
Zgarb

10

Ruby,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 2015年

错误:f(ss, 999)将返回0(而不是None)。你能解决这个问题吗?这可以说是违反了规则1
SMCI

@smci我不知道你在说什么。我应该如何知道变量中的内容ssNone在任何情况下都不是期望的输出,因为答案是整数。
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

的值x用于检查哪个子字符串的数字最大为1。从0到字符串的长度减去子字符串的长度(变量l)开始循环。从循环(%%a)中的当前点开始获取子字符串,c将其设置为从开始的输入字符串%%a,并采用%2(给定的子字符串长度)字符。0从中删除任何c,然后将的值与c进行比较x-即111大于,11因此我们可以使用'string'进行大于比较。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

C#(正则表达式),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);}}

实际的正则表达式并不长,但是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的s 数均小于或等于。

得出第一个结果将给出答案,因为其前面的所有子字符串在其前面都有一些子字符串1,且带有更多的's',并且我们检查了大于当前索引的任何索引都具有小于或等于的1's'。

(而且我学到了一些不错的东西:“堆栈”在回溯时得以恢复)。


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编译器/执行器

说明:

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用1的序列计算卷积n,然后找到最大值。使用可以轻松进行卷积conv,并且该max函数返回第一个最大值的位置。必须减去1结果索引,因为Matlab索引始于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

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]

您可以通过定义infix函数来节省2个字节:n#l=...
Zgarb 2015年

您可以对使用infix函数p。另外,我认为这样做0是多余的(尽管没有括号,并且您可能需要一个空格代替0)。
骄傲的哈斯克勒

3

JavaScript(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。这应减少4个字节,即69字节的最终长度。此外,你可能也许能够替换&&&。但是很好的一个~~把戏!
伊斯梅尔·米格尔

@IsmaelMiguel您需要初始化x,否则首先出错t > x。您需要初始化r:try F("00000")。And &&需要模拟和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应在命令行上分别定义为搜索字符串和子字符串的长度。

这也可以在具有substr_count()和功能的C语言中使用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()
        );
    }
}

将输入作为方法参数。

它能做什么:

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字节

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字节

本来打算使用.matches(regex),但是它与上面的python解决方案几乎相同,所以我尝试了一个滑动窗口。这是新功能,因此如果有人有指点,将很高兴听到它们。

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 2015年
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.