测试一个字符串是否可以用子字符串组成!


23

给定一个字符串s和一个数组/列表l,请确定是否s可以使用中的零件制成l

例如,如果字符串为"Hello, world!"且列表为[' world!', 'Hello,'],则程序/函数应返回真实值,因为您可以排列列表以形成字符串。以下列表也将返回真实值:['l', 'He', 'o, wor', 'd!']。试想一下'l',在字符串中需要填充的地方。所以可以,您可以重复列表中的元素以形成字符串。如果不能形成字符串,则应返回假值。IO的标准方法和标准漏洞适用。

测试用例:

Input (In the form of s, l)
Output (1 if possible, 0 if impossible)

"Hello, world!", ["l", "He", "o, wor", "d!"]
1

"la lal al ", ["la", " l", "al "]
1

"this is a string", ["this should return falsy"]
0

"thi is a string", ["this", "i i", " a", " string"]
0

"aaaaa", ["aa"]
0

"foo bar foobar", ["foo", "bar", " ", "spam"]
1

"ababab", ["a","ba","ab"]
1

"", ["The string can be constructed with nothing!"]
1

不要紧,如果数组包含多个比实际需要构建主串串?
毛茸茸的

在这种情况下,返回值应该是多少?
毛茸茸的

@蓬松的特鲁西 如果有多余的部分,则可以使用所有非多余部分来构造字符串。我将添加一个测试用例。
“ SparklePony同志” 17年

3
我建议添加此测试用例:"ababab", ["a","ba","ab"]
数学迷

3
我建议您添加一个包含正则表达式元字符的测试用例。
乔伊,

Answers:


11

Brachylog,8个字节

~c¬{∋¬∈}

在线尝试!

这真的很慢。花费了大约37秒的“你好,世界!” 我的PC上的测试用例,在TIO上超时。

这通过输入变量获取字符串,并通过输出变量获取列表

说明

             String = ?, List = .

             It is possible to find…
~c           …a deconcatenation of ?…
  ¬{   }     …such that it is impossible…
    ∋¬∈      …that an element of that deconcatenation is not an element of .

“ la lal al”超过60秒...
RosLuP

1
@RosLuP使用此输入和["la", " l", "al "]列表,它在我的计算机上终止,并false.在6800秒后正确回答,“仅” 1,130亿个推论。
Fatalize

我觉得用这种语言编写任何东西都会导致程序无法在TIO上运行haha。
魔术章鱼缸

@carusocomputing该语言对于大多数程序而言并不算慢,只是在某些情况下,由于该程序的声明性,导致执行时间非常缓慢(可以通过
缩短

@Fatalize errr ...我的意思是说打高尔夫球不写东西,似乎指令越少,“问题”的范围越广,所需的计算就越多。似乎是解决理论数学问题的绝佳语言。
魔术章鱼缸

7

Mathematica,29个字节

StringMatchQ[#,""|##&@@#2..]&

说明:

             #,               (* The first argument *)
StringMatchQ[                 (* matches the string pattern *)
               ""|##&         (*   Alternatives *)
                     @@       (*     applied to *)
                       #2     (*     the second argument *)
                         ..   (*   repeated *)
                           ]&

边界线作弊解决方案,21字节

StringMatchQ[#,#2..]&

由于数学是一种象征性的编程语言,有表达之间没有区别* List[a,b,...]Alternatives[a,b,...]比他们如何互动与其他符号和显示方式(其他的{a,b,...}a|b|...,分别)。当在的第二个参数中StringMatchQ使用Alternatives表达式时,将其视为字符串模式,因此我们可以8通过将第二个参数用作Alternatives表达式来节省上述解决方案的字节数。

*从技术上讲List也是Locked,这可以防止用户Unprotect阅读它并更改其行为。


1
{x,y,z}x|y|z字符串模式匹配相同。我认为您可以""|##&@@#2..用just 代替#2..
不是一棵树

5

Pyth,23个字节

AQW&GhGJ.(G0Vf!xJTH aG>JlN;G

接受类似的输入[['string'],['list', 'of', 'parts']]。输出是一个空列表或一个内部包含值的列表。在Pyth中,包含任何内容(甚至是空字符串(['']))的列表的计算结果为true。

在线尝试!

说明:

                             | Implicit: Q = eval(input())
AQ                           | Assign the first value of Q to G and the second to H
  W&GhG                      | While G is not empty and G doesn't contain an empty string:
       J.(G0                 |  Pop the first value of G and store into J
            Vf!xJTH          |  For N in elements in H that match the beginning of J:
                             |   Additional space for suppressing printing 
                    aG>JlN   |   Append to G the elements of J from the length of N to the end
                          ;  | End all loops
                           G | Print G

该解决方案不断尝试从字符串开头删除所有可能的部分,并跟踪它仍需要查看哪些值。

如果我们在while循环的每次迭代之后查看G测试用例中的值,[['ababab'],['a','ba','ab']]那么我们将得到:

['ababab']
['babab', 'abab']
['abab', 'bab']
['bab', 'bab', 'ab']
['bab', 'ab', 'b']
['ab', 'b', 'b']
['b', 'b', '']
['b', '']
['']   <---Remember, this evaluates to True

并且,在测试案例中[['aaaaa'],['aa']],这是我们得到的:

['aaaaa']
['aaa']
['a']
[]   <---And this evaluates to False

我创建了另一个测试用例,[['aaaaaa'],['a','aa','aaa']]输出是这样的:

['', 'aaa', 'aa', 'a', 'aa', 'a', '', 'a', '', 'aa', 'a', '', 'a', '', '', 'a', '', '']

输出列表中包含一堆垃圾,但这仍然是一个真实值。


5

Perl 5,39个字节

38个字节的代码+ -p标志。

map{chop;$v.="\Q$_\E|"}<>;$_=/^($v)*$/

在线尝试!

对于输入"Hello, world!", ["l", "He", "o, wor", "d!"](实际上由换行符分隔),它构造模式l|He|o, wor|d!|(由于,元字符已转义\Q..\E),然后查看第一个字符串是否与匹配此模式/^($v)*$/

在TryItOnline上,请注意,必须有一个尾随的换行符。


“你好,世界!我愿意,我愿意!” 此输入中带有“ l”后的空格不会产生任何结果
RosLuP

@RosLuP您能给我一个TryItOnline链接吗?(我不明白您的意思是什么。请注意,“ false”实际上不打印任何内容,因为这是Perl)
Dada

那么对于虚假打印没有什么?在这种情况下,请问一下,但是这个无输出值对我来说似乎没有太大用处……
RosLuP

@RosLuP是的。在Perl中,undef是大多数内置函数返回的虚假值。而且在打印时,它实际上什么也不打印。而这正是我在做的。对于类似C的语言,打印“ 1/0”是很自然的,但是对于Perl,打印“ 1 / undef”是很自然的方式。
达达

没有任何输出有一个歧义“正在运行还是程序结束为假?”
RosLuP

4

PHP,69字节

<?=($s=$_GET[0])>""?ctype_digit(strtr($s,array_flip($_GET[1])))?:0:1;

测试用例


非常聪明,花了我几分钟来了解您在做什么。+1思维开箱即用
Martijn

该令人讨厌的边缘案例的假阴性结果["", ["The string can be constructed with nothing!"]]
乔纳森·艾伦

@JonathanAllan做的是一个空字符串吗?
约尔格Hülsermann

是的,空分区问题是许多解决方案中的问题。
乔纳森·艾伦

3

Python 2,141字节

lambda s,l:s in[''.join(i)for r in range(len(s)+1)for j in combinations_with_replacement(l,r)for i in permutations(j)]
from itertools import*

在线尝试!

极其低效。第一个测试用例在TIO上超时。


3

JavaScript(ES6),59个字节

接受子a字符串数组和字符串s以currying语法(a)(s)。返回false/ true

a=>g=s=>!s||a.some(e=>s.split(e)[0]?0:g(s.slice(e.length)))

已评论

a =>                          // main function that takes 'a' as input
  g = s =>                    // g = recursive function that takes 's' as input
    !s ||                     // if 's' is empty, return true (success!)
    a.some(e =>               // else, for each element 'e' in 'a':
      s.split(e)[0] ?         //   if 's' doesn't begin with 'e':
        0                     //     do nothing
      :                       //   else:
        g(s.slice(e.length))  //     remove 'e' at the beginning of 's' and
    )                         //     do a recursive call on the remaining part

测试用例


3

哈斯克尔,35个字节

#接受String和的列表String,然后返回Bool

s#l=elem s$concat<$>mapM("":)(l<$s)

在线尝试!

只是不要介意我遗漏的测试用例,因为即使使用-O2,它也损坏了我微薄的笔记本电脑。我怀疑GHC不会融合中间的30517578125元素列表,它的共享太多,无法迅速收集垃圾,而且由于测试用例不正确,因此程序必须生成所有这些...如果可以,请随意尝试处理。

mapM("":)(l<$s)是列出length s元素列表的所有方式的列表,这些元素可以为空字符串或来自的字符串l


3

Pyth,17 15 11 14字节

AQ|!G}Ym-dH./G

空字符串的要求已更改,增加了3个字节。

说明

AQ|!G}Ym-dH./G
AQ                     Save the input into G, H.
           ./G         Get all partitions of G.
       m-dH            Check if the parts are in H.
     }Y                The empty list should be present if and only
                           if the string can be made...
  |!G                  ... or the string might be empty.

旧版本

AQ}Ym-dH./G

更短在宇宙的生命中运行!

说明

AQ}Ym-dH./G
AQ                  Save the input into G, H.
        ./G         Get all partitions of G.
    m-dH            Check if the parts are in H.
  }Y                The empty list should be present if and only
                        if the string can be made.

AQ&G}GsMs.pMy*HlG

这太慢了,但它适用于我的(很小的)测试用例。

说明

AQ&G}GsMs.pMy*HlG
AQ                  Save the input into G, H.
             *HlG   Repeat the list of substrings for each character of G.
            y       Take the power set.
         .pM        Take every permutation of each set of substrings.
      sMs           Get a list of all the joined strings.
    }G              Check if G is one of them.
  &G                Make sure G is not empty.

3

果冻14 12 8字节

;FŒṖḟ€Ạ¬

在线尝试!

怎么运行的

;FŒṖḟ€Ạ¬   - main function, left argument s, right argument l
;F         - concatenate to the string the list, flattened to deal with "" as string
  ŒṖ       - Get all partitions of s, that is, all ways to make s from substrings
     €     - For each partition...
    ḟ      -   Filter out (exclude) those elements which are not in... 
           -   (implicit right arg) the list l. This leaves the empty set (falsy) if the partition can be made of elements from the list
      Ạ    - If any element is falsy (thus constructable from l), return 0; else return 1
       ¬   - Apply logical not to this, to yield the proper 1 = constructable from list, 0 otherwise.

"", ["The string can be constructed with nothing"]@JonathanAllan 修复了案例中的错误


假阴性"", ["The string can be constructed with nothing!"]
乔纳森·艾伦

它会慢很多,但是;FŒṖḟ⁹$€Ạ¬会解决。
乔纳森·艾伦

...并且您可以为其使用隐式的right参数,因此您不需要the $;FŒṖḟ€Ạ¬
乔纳森·艾伦

恩,这就是我不对每个测试用例进行测试所得到的。通过用¬总是以正确的参数“”返回true的操作替换,我也许能够维持8个字节。
fireflame241

^好吧,我让它回到了8 :)
乔纳森·艾伦


2

Pyth,10 8字节

f!-TQ./+zh

测试套件

这将在STDIN的第一行中包含列表,在第二行中包含字符串(不带引号)。

首先,将列表存储在中Q,并将字符串存储在中z。接下来,我们形成的所有可能分区z。每个分区都会被过滤(f)以检查它是否仅使用了Q。为此,我们Q从中删除T要分区的的所有元素,并在逻辑上用取反!,以便仅Q保留每个元素所在的分区。

为了解决''没有分区的问题,我们将字典的第一个单词添加到z中,这样它就不会是一个空字符串。


测试套件遗漏了底线(一个空字符串)-是否需要引用?用空行或""它似乎无法通过这种情况。
乔纳森·艾伦

空字符串没有分区,因此实际上在这里给出错误的答案。该死,我会设法解决的。
isaacg '17

我为Jelly建议的解决方法是将输入字符串与平坦的输入数组连接起来,也许您可​​以这样做?
乔纳森·艾伦

@JonathanAllan我做了类似的事情,谢谢。
isaacg

的情况下,"", [""]"", []没有被覆盖-让我们不要去那里:)
乔纳森·艾伦

2

PowerShell,61 58 57字节

{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};+!$s}

在线尝试!

旧解决方案:

{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};[int]!$s}
{$s,$l=$_;$l|sort -d length|%{$s=$s.replace($_,'')};0+!$s}  

这个几乎是不可读的,所以我建议对其进行一些更改。我可以肯定,其他大多数人也会同意。
Rɪᴋᴇʀ

感谢您对我的解决方案更正的原因的解释。
Andrei Odegov '17

1

Python 2,64字节

lambda s,l:len(re.findall("^("+"|".join(l)+")*$",s))>0
import re

在线尝试!


我认为这并不完全有效,请尝试("aaaaaaa",["aa","aaa"])
xnor

@xnor我更新了它。快来了解一下,正则表达式非常适合此功能。
尼尔

4
应该会失败('x', '.'),但我猜不会。
乔伊,

1
@nfnneil你呢?您的最后修改是10小时前。
丹尼斯,

1
... "Hello", ["\w"]等等
乔纳森·艾伦

1

PowerShell,78岁

$s,$l=$args;!($s-creplace(($l|sort -d length|%{[regex]::escape($_)})-join'|'))

非常简单的基于正则表达式的方法。


1

CJam(16字节)

{Ma+1$,m*:e_\a&}

这是一个匿名块(函数),用于获取字符串和堆栈上的字符串数组。在线演示

它使用明显的算法:

{        e# Declare a block. Call the args str and arr
  Ma+    e#   Add the empty string to the array
  1$,m*  e#   Take the Cartesian product of len(str) copies of (arr + [""])
  :e_    e#   Flatten each element of the Cartesian product into a single string
  \a&    e#   Intersect with an array containing only str
}

如果str无法创建,则返回值为空数组/字符串(falsy),如果可以创建,则返回值为包含str(真,即使str本身为空字符串)的数组。


@RosLuP,我不确定您的意思。那个特定的测试用例执行得如此之快,以至于我实际上无法计时。其他测试用例确实需要花费很长时间才能执行,但是规范不包含任何时间限制。
彼得·泰勒

@RosLuP,在线演示。但是我不明白你的抱怨是什么。
彼得·泰勒

1

C ++(Bcc),287个字节

#include<algorithm.h>
f(a,b)char*a,**b;{int i,j,k,v,p[256];if(!a||!b||!*b)return-1;for(v=0;v<256&&b[v];++v)p[v]=v;if(v>=256)return-1;la:for(i=0,j=0;j<v&&a[i];){for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k);j=b[p[j]][k]?(i-=k),j+1:0;}if(a[i]&&next_permutation(p,p+v)) goto la;return i&&!a[i];}

因为我没有写或使用过多的next_permutation()我不知道是否还可以。我不知道这是否是解决方案的100%,也可能是质量过高了。这里的一个字符串列表是一个指向char的指针数组。以NULL结尾的算法很简单,如果列表中的所有字符串都与参数“ a”匹配,则有一个线性尝试的算法,还有另一个算法会置换字符串列表的索引,因此它尝试所有可能的组合。

解开它,在这里测试代码和结果

#include<stdio.h>
g(a,b)char*a,**b;
{int i,j,k,v,p[256];
 if(!a||!b||!*b) return -1;
 for(v=0;v<256&&b[v];++v) p[v]=v;
 if(v>=256)      return -1; // one array of len >256 is too much
la: 
 for(i=0,j=0;j<v&&a[i];)
   {for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k); 
    j=b[p[j]][k]?(i-=k),j+1:0;
   } 
 if(a[i]&&next_permutation(p,p+v)) goto la;
 return i&&!a[i];  
}

#define F for
#define P printf

test(char* a, char** b)
{int i;
 P("f(\"%s\",[",a);
 F(i=0;b[i];++i) 
       P("\"%s\"%s", b[i], b[i+1]?", ":"");
 P("])=%d\n", f(a,b));
}

main()
{char *a1="Hello, world!",    *b1[]={"l","He", "o, worl", "d!",      0};//1
 char *a2="la lal al ",       *b2[]={"la", " l", "al ",              0};//1
 char *a3="this is a string", *b3[]={"this should return falsy",     0};//0
 char *a4="thi is a string",  *b4[]={"this", "i i", " a", " string", 0};//0
 char *a5="aaaaa",            *b5[]={"aa",                           0};//0
 char *a6="foo bar foobar",   *b6[]={"foo","bar"," ","spam",         0};//1
 char *a7="ababab",           *b7[]={"a","ba","ab",                  0};//1
 char *a8="",                 *b8[]={"This return 0 even if has to return 1", 0};//0
 char *a9="ababc",            *b9[]={"a","abc", "b", 0};//1

  test(a1,b1);test(a2,b2);test(a3,b3);test(a4,b4);test(a5,b5);test(a6,b6);
  test(a7,b7);test(a8,b8);test(a9,b9);
}

f("Hello, world!",["l", "He", "o, worl", "d!"])=1
f("la lal al ",["la", " l", "al "])=1
f("this is a string",["this should return falsy"])=0
f("thi is a string",["this", "i i", " a", " string"])=0
f("aaaaa",["aa"])=0
f("foo bar foobar",["foo", "bar", " ", "spam"])=1
f("ababab",["a", "ba", "ab"])=1
f("",["This return 0 even if has to return 1"])=0
f("ababc",["a", "abc", "b"])=1

这将在gcc C ++编译器中进行编译

#include<algorithm>

int f(char*a,char**b){int i,j,k,v,p[256];if(!a||!b||!*b)return -1;for(v=0;v<256&&b[v];++v)p[v]=v;if(v>=256)return -1;la:;for(i=0,j=0;j<v&&a[i];){for(k=0;b[p[j]][k]==a[i]&&a[i];++i,++k);j=b[p[j]][k]?(i-=k),j+1:0;}if(a[i]&&std::next_permutation(p,p+v))goto la;return i&&!a[i];}

必须爱C ++!:)
MEMark

1

Python,66个字节

lambda s,l:s==''or any(x==s[:len(x)]and f(s[len(x):],l)for x in l)

取消高尔夫:

def f(s,l):
    if s=='': 
        return 1
    for x in l:
        if s.startswith(x) and f(s[len(x):],l):
            return 1
    return 0

0

Microsoft Sql Server,353个字节

u as(select s.n,s collate Latin1_General_BIN s,l collate Latin1_General_BIN l,
row_number()over(partition by l.n order by len(l)desc)r from s,l where s.n=l.n),
v as(select n,s,l,replace(s,l,'')c,r from u where r=1 union all
select u.n,u.s,u.l,replace(v.c,u.l,''),u.r from v,u where v.n=u.n and v.r+1=u.r)
select s,iif(min(c)='',1,0)u from v group by n,s

在线测试。

可读版本:

with s as(
  select n,s
  from(values(1,'Hello, world!'),
             (2,'la lal al '),
             (3,'this is a string'),
             (4,'thi is a string'),
             (5,'aaaaa'),
             (6,'foo bar foobar'),
             (7,'ababab'),
             (8,''))s(n,s)),
l as(
  select n,l
  from(values(1,'l'),(1,'He'),(1,'o, wor'),(1,'d!'),
             (2,'la'),(2,' l'),(2,'al '),
             (3,'this should return falsy'),
             (4,'this'),(4,'i i'),(4,' a'),(4,' string'),
             (5,'aa'),
             (6,'foo'),(6,'bar'),(6,' '),(6,'spam'),
             (7,'a'),(7,'ba'),(7,'ab'),
             (8,'The string can be constructed with nothing!'))l(n,l)),
--The solution starts from the next line.
u as(
  select s.n,
    s collate Latin1_General_BIN s,
    l collate Latin1_General_BIN l,
    row_number()over(partition by l.n order by len(l)desc)r
  from s,l
  where s.n=l.n),
v as(
  select n,s,l,replace(s,l,'')c,r from u where r=1
    union all
  select u.n,u.s,u.l,replace(v.c,u.l,''),u.r
  from v,u
  where v.n=u.n and v.r+1=u.r
)
select s,iif(min(c)='',1,0)u from v group by n,s

0

C,140字节

我敢肯定,在C语言中,有一种更短的方法可以做到这一点,但我想创建一个解决方案来测试所有可能的子字符串组合,而不是通常的find / replace方法。

char p[999];c,o;d(e,g,l,f)int*e,**g,**l;{c=f&&c;for(l=g;*l;)strcpy(p+f,*l++),(o=strlen(p))<strlen(e)?d(e,g,0,o):(c|=!strcmp(e,p));return c;}

在线尝试

取消高尔夫:

#include <string.h>
#include <stdio.h>

char buf[999];
int result;
int temp;

int test(char *text, char **ss, char **ptr, int length) 
{
    if (length == 0)
        result = 0;

    for(ptr = ss; *ptr; ptr++)
    {
        strcpy(buf + length, *ptr);
        temp = strlen(buf);
        if (temp < strlen(text))
        {
            // test recursivly
            test(text, ss, 0, temp);
        }
        else
        {
            if (strcmp(buf, text) == 0)
                result = 1;
        }
    }
    return result;
}

int main()
{
    char *text = "Hello,World";
    char *keywords[] = { "World", "Hello", ",", 0 };
    printf("%d", test(text, keywords, 0, 0));
}
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.