分割字符串


23

挑战

给定一个字符串和一个数字,将字符串分成许多相等大小的部分。例如,如果数字为3,则无论字符串有多长,都应将其分为3个部分。

如果字符串的长度未均匀地除以所提供的数字,则应四舍五入每一小节的大小并返回“剩余”字符串。例如,如果输入字符串的长度为13,数字为4,则应返回四个大小均为3的字符串,再加上大小为1的其余字符串。

如果没有余数,您可能根本不返回一个或返回空字符串。

所提供的数字保证小于或等于字符串的长度。例如,"PPCG", 7将不会出现输入,因为"PPCG"无法将其分为7个字符串。(我想正确的结果将是(["", "", "", "", "", "", ""], "PPCG")。将其简单地禁止作为输入会更容易。)

像往常一样,I / O是灵活的。您可以返回一对字符串和余数字符串,或者返回一个以余数结尾的字符串列表。

测试用例

"Hello, world!", 4 -> (["Hel", "lo,", " wo", "rld"], "!") ("!" is the remainder)
"Hello, world!", 5 -> (["He", "ll", "o,", " w", "or"], "ld!")
"ABCDEFGH", 2 -> (["ABCD", "EFGH"], "") (no remainder; optional "")
"123456789", 5 -> (["1", "2", "3", "4", "5"], "6789")
"ALABAMA", 3 -> (["AL", "AB", "AM"], "A")
"1234567", 4 -> (["1", "2", "3", "4"], "567")

计分

这是,因此每种语言中最短的答案将获胜。

使您的解决方案实际使用您语言的除法运算符的加分(不是😛)。


1
奖励积分?噢,我必须这么做
Matthew Roh


Related,但没有什么部分与此挑战相同。
musicman523

为了更清楚,请添加一个测试用例PPCG7所以其余的是PPCG
约尔格Hülsermann

@JörgHülsermann不允许输入。我添加了与该类型输入有关的更多详细信息,并重新格式化了内容。
musicman523

Answers:




5

点子,21字节

20个字节的代码,-n标志+1 。

a~C(#a//b*XX)XbP$$$'

将输入作为命令行参数;输出字符串,其余以换行符分隔。在线尝试!

说明

正则表达式操作的乐趣!

abcdefg我们以字符串和3数字为例。我们构造了regex (.{2})(.{2})(.{2}),它匹配两个字符的三个游程并将它们存储在三个捕获组中。然后,使用Pip的regex匹配变量,我们可以打印1)捕获组的列表["ab";"cd";"ef"],以及2)未匹配的字符串的其余部分"g"

                      a,b are cmdline args; XX is the regex `.` (match any one character)
    #a//b             Len(a) int-divided by b: the length of each chunk
         *XX          Apply regex repetition by that number to `.`, resulting in something
                        that looks like `.{n}`
  C(        )         Wrap that regex in a capturing group
             Xb       Repeat the whole thing b times
a~                    Match the regex against a
               P$$    Print $$, the list of all capture groups (newline separated via -n)
                  $'  Print $', the portion of the string after the match

5

Haskell,62个字节

#是取a String和an Int并返回Strings 列表的运算符。

用作"Hello, world!"#4

s#n|d<-length s`div`n=[take(d+n*0^(n-i))$drop(i*d)s|i<-[0..n]]

在线尝试!

怎么运行的

  • s是输入字符串n,是非余数。
  • d是每个“正常”片段的长度。div是整数除法。
  • 列表理解构造n+1片段,最后一个构成其余部分。
    • i从迭代0n,包括。
    • 对于每块,首先从的开头ping 正确数量的(i*d)初始字符,然后从结果中选择一个初始子字符串n。dropstake
    • 子字符串长度应为 d,其余部分除外。
      • 实际余数必须短于n,否则正常部分将被加长。
      • take如果给定的长度太大,则返回整个字符串,因此我们可以>=n-1对其余部分使用任何数字。
      • 该表达式d+n*0^(n-i)给出dif i<nd+nif i==n。它使用的0^x1时间x==0,但是0如果x>0

我需要注意在哪里可以使用列表推导。
qfwfq


4

C ++ 14、209180字节

有点长,但是使用除法运算符:

#include<bits/stdc++.h>
using q=std::string;using z=std::vector<q>;z operator/(q s,int d){int p=s.length()/d,i=0;z a;for(;i<d+1;){a.push_back(s.substr(i++*p,i^d?p:-1));}return a;}

用法:

vector<string> result = string("abc")/3;

在线版本:http//ideone.com/hbBW9u


4

Pyth,9个字节

cz*L/lzQS

在线尝试

怎么运行的

首先Q被自动初始化为eval(input())z并被自动初始化为input()

cz*L/lzQSQ
     lz      length of z
    /  Q     integer division by Q
  *L         times every element of
        SQ       [1, 2, …, Q]
cz           chop z at those locations


3

,107字节

fn f(s:&str,n:usize)->(Vec<&str>,&str){let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

在线尝试!

格式:

fn q129259(s: &str, n: usize) -> (Vec<&str>, &str) {
    let c = s.len() / n;
    ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
}

这只是简单地将map索引索引到源的正确切片上strcollectVec),然后切下其余部分。

不幸的是,我无法将其关闭(74个字节):

|s,n|{let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

由于编译器失败

error: the type of this value must be known in this context
 --> src\q129259.rs:5:18
  |
5 |          let c = s.len() / n;
  |                  ^^^^^^^

如果我提供的类型s:&str,则生命周期错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^^^^^^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 4:18...
 --> src\q129259.rs:4:19
  |
4 |       (|s: &str, n| {
  |  ___________________^
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |______^
note: ...so that reference does not outlive borrowed content
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 3:58...
 --> src\q129259.rs:3:59
  |
3 |   fn q129259<'a>(s: &'a str, n: usize) -> (Vec<&str>, &str) {
  |  ___________________________________________________________^
4 | |     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
8 | | }
  | |_^
note: ...so that expression is assignable (expected (std::vec::Vec<&'a str>, &'a str), found (std::vec::Vec<&str>, &str))
 --> src\q129259.rs:4:5
  |
4 | /     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |_____________^

3

视网膜,92字节

(.+)¶(.+)
$2$*1¶$.1$*1¶$1
(1+)¶(\1)+
$1¶$#2$*1¶
\G1(?=1*¶(1+))
$1¶
¶¶1+

O^$`.

¶1+$

O^$`.

在线尝试!说明:第一个阶段将部分数目转换为一元,并且还获取字符串的长度。然后,第二阶段将长度除以零件数,剩下任何余数。第三阶段再次将结果乘以零件数。这样可以为我们提供正确数量的正确长度的字符串,但是它们还没有内容。现在可以在第四阶段删除零件数量。第五阶段反转所有字符。这具有使用占位符字符串切换原始内容的效果,但是尽管现在位置正确,但是顺序相反。占位符已达到目的,在第六阶段被删除。最后,第七阶段将字符恢复为原始顺序。


3

Perl 6、36字节

{$^a.comb.rotor($a.comb/$^b xx$b,*)}

在线尝试!

返回字符串列表的列表,其中最后一个元素为其余元素(如果有)。

说明:

{                                  }  # Anonymous code block
 $^a.comb                             # Split the string into a list of chars
         .rotor(                  )   # And split into
                            xx$b      # N lists
                $a.comb/$^b           # With string length/n size
                                ,*    # And whatever is left over  

2

JavaScript(ES6),77个字节

(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]

返回由两个元素组成的数组:分割后的字符串部分和其余部分。

测试片段

f=
(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]
<div oninput="O.innerHTML=I.value&&J.value?JSON.stringify(f(I.value,+J.value)):''">String: <input id=I> Number: <input id=J size=3></div>
<pre id=O>


2

Japt,18个字节

¯W=Ul fV)òW/V pUsW

在线测试!(使用-Q标志可视化输出)

说明

¯W=Ul fV)òW/V pUsW  : Implicit: U = input string, V = input integer
   Ul fV            : Floor U.length to a multiple of V.
 W=                 : Assign this value to variable W.
¯       )           : Take the first W characters of U (everything but the remainder).
         òW/V       : Partition this into runs of length W / V, giving V runs.
              pUsW  : Push the part of U past index W (the remainder) to the resulting array.
                    : Implicit: output result of last expression


2

Python,95、87、76 73字节

def f(s,n):
 a=[];i=len(s)/n
 while n:a+=s[:i],;s=s[i:];n-=1
 print a+[s]

在线尝试!


欢迎来到PPCG!我在您的帖子中添加了“在线尝试”链接。我认为您可以通过使其成为完整程序而不是功能来稍微缩短解决方案。在线尝试!
musicman523

2

05AB1E,12个字节

²g¹‰`s¹.D)R£

在线尝试!

说明

²g¹‰`s¹.D)R£
²g           # Push length of string
  ¹          # Push amount of pieces
   ‰         # divmod of the two
    `s       # Flatten the resulting array and flip it around
      ¹.D    # Repeat the resulting length of the pieces amount of pieces times(wow that sounds weird)
         )   # Wrap stack to array
          R  # Reverse (so the remainder is at the end)
           £ # Split the input string into pieces defined by the array

1
通过反转输入顺序可以达到 9个字节
凯文·克鲁伊森

2

Brachylog,16个字节

kʰ↙Xḍ₎Ylᵛ&ht↙X;Y

在线尝试!

将输入作为列表[string, number],将输出作为列表[remainder, parts]。(为清晰起见,在“ Hello,world!”测试用例中,逗号用分号代替,因为字符串片段没有加引号。)

                    The input
 ʰ                  with its first element
k ↙X                having the last X elements removed
    ḍ               and being cut into a number of pieces
     ₎              where that number is the last element of the input
      Y             is Y
       lᵛ           the elements of which all have the same length,
         &          and the input
          h         's first element
           t↙X      's last X elements
              ;     paired with
               Y    Y
                    are the output.

(我还用分号替换了代码中的逗号,以实现一致的输出格式。使用逗号,没有余数的情况将只输出没有空余数的部分,并且出于某些目的,那样很好,我没有真的知道为什么会这样...)

在这变成一个完整的16字节之后,我尝试根据+₁ᵗ⟨ġl⟩工作来做一些事情,但是随着修复程序变得越来越长,我决定暂时只保留最初的解决方案。



2

Excel公式,185个 173 165 161 149字节

以下内容应作为数组公式(Ctrl+ Shift+ Enter)输入:

=MID(A1,(ROW(OFFSET(A1,,,B1+1))-1)*INT(LEN(A1)/B1)+1,INT(LEN(A1)/B1)*ROW(OFFSET(A1,,,B1+1))/IF(ROW(OFFSET(A1,,,B1+1))=B1+1,1,ROW(OFFSET(A1,,,B1+1))))

其中A1包含您的输入(例如12345678)和B1除数。这也使用Excel的除法运算符获得奖金。

在将公式作为数组公式输入后,在公式栏中突出显示它,并使用求值F9以返回结果,例如:

Excel formula evaluation showing split groups

-12个字节:将每个字节替换INDIRECT("1:"&B1+1)OFFSET(A1,,,B1+1),每次发生可节省2个字节,加上一些整齐的删除多余的括号。

-8个字节:删除冗余INDEX功能。

-4个字节:返工“剩余”处理。

-12个字节:INT(LEN(A1)/B1)通过抵消ROW(OFFSET(A1,,,B1+1))-1 生成的数组来消除冗余。




1

Mathematica,58个字节

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&

以字符列表和正整数为输入的纯函数。例如,最后一个测试用例由

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&[{"1","2","3","4","5","6","7"},4]

并返回:

{{{"1"}, {"2"}, {"3"}, {"4"}}, {"5", "6", "7"}}

1

Haskell,120 88字节(感谢ØrjanJohansen!)

是否div算除法运算符?

我很好奇该如何减少,我还没有学到所有技巧。

q=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-q n s=f:g r,(a,b)<-q(n*x)s=(g a,b)

2
使用最基本的技巧进行快速重写:t=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-t n s=f:g r,(a,b)<-t(n*x)s=(g a,b)。因此,(1)重复使用的标识符可能会缩写,特别是如果它很长。(2)警卫和模式守卫几乎总是比短let... inwhereif then else。(3)模式匹配通常比相等性测试更好。(好吧,let在模式防护方面还不是那么基本,我最近从这里的其他人那里学到了。)并查看codegolf.stackexchange.com/questions/19255/…
与Orjan约翰森

1
另外,请查看Haskell打高尔夫球的技巧,以获取一些有用的技巧。
sudee

@ØrjanJohansen谢谢!我忘记了分号是有效的,而let在后卫中则是相当狡猾的。但是较短的代码更具可读性,对吗?
qfwfq

1

欧姆,3个字节(无竞争?)

lvσ

非竞争性的,因为尚未在TIO中实现内置功能,并且我没有PC可以方便地测试它是否在最新的回购协议中有效。

内置¯\\ _(ツ)_ /¯。我使用了错误的内置设备...但是,嘿,周围还有其他设备。现在,我两次使用了错误的内置函数(或者一个内置函数对余数使用了错误)。

Do I get bonus points because v is (floor) division?


1
This doesn't split in the way required. e.g. the Hello, world! 5 testcase is wrong. Try it online!
Ørjan Johansen

Well I'm going to look for another built-in....
Roman Gräf

1

CJam, 16 bytes

{_,2$//_2$<@@>s}

Anonymous block expecting the arguments on the stack and leaves the result on the stack after.

Try it online!

Explanation

Expects arguments as number "string".

_,              e# Copy the string and get its length.
  2$            e# Copy the number.
    /           e# Integer divide the length by the number.
     /          e# Split the string into slices of that size.
      _         e# Copy the resulting array.
       2$       e# Copy the number.
         <      e# Slice the array, keeping only the first <number> elements.
          @@    e# Bring the number and original array to the top.
            >   e# Slice away the first <number> elements,
             s  e# and join the remaining elements into a string.

1

J, 26 bytes

(]$~[,(<.@%~#));]{.~0-(|#)

Apart from elminating spaces and intermediate steps, this hasn't been golfed. I expect that I've taken the long way somehow, what with my parentheses and argument references ([ and ]).

See Jupyter notebook for test cases, such as the following:

   5 chunk test2
┌──┬───┐
│He│ld!│
│ll│   │
│o,│   │
│ w│   │
│or│   │
└──┴───┘

Thanks. Read too fast. Comment removed
Jonah

1

R, 79 63 bytes

-16 from Giuseppe fixing the indexing

function(s,n,k=nchar(s),l=k%/%n)substring(s,0:n*l+1,c(1:n*l,k))

Try it online!

Built around giving vector inputs to substring()


63 bytes -- simplified the indexing a bit.
Giuseppe

@Giuseppe Haha, I must have tried every variant of adding and multiplying on the index, but missed that one. Good catch.
CriminallyVulgar

0

PHP, 152 bytes

Thanks @JörgHülsermann (brackets tip!)

$c=$s=explode('|',readline());
while($s[1]--)$s[0]=preg_replace('/^'.($l[]=substr($s[0],0,strlen($c[0])/$c[1])).'/','',$s[0]);
$l[r]=$s[0];
print_r($l);

Try it online!


1
Your PHP Way doesn't work cause it replaces not only at the beginning. preg_replace is an alternative or you can use [,$s,$d]=$argv;print_r(array_slice(str_split($s,$l=strlen($s)/$d^0),0,$d)+[$d=>substr($s,$l*$d)]);
Jörg Hülsermann

Can you explain me with a example code why doesn't work my PHP code ?
kip

1
Try it online! It replaces all A in the first run
Jörg Hülsermann

1
You can drop the array_walk construct if you use brackets Try it online!
Jörg Hülsermann

Nice tip ! I totally forgot
kip


0

PowerShell v3+, 72, 80 bytes

Assumes $s contains the input string; $n contains the number of characters per "piece". This also assumes that "StrictMode" is off. Otherwise, an error would be returned because of indexing further into an array than actually exists (i.e. if array has 4 elements and i call the non-existent 5th element). With StrictMode off, PS doesn't care and it'll ignore the error.

for($i = 0;$i -le $s.Length;$i+=$n+1){-join($s|% ToCharA*)[$i..($i+$n)]}

Using notation ($s|% ToCharA*) i was able to save 1 character compared to $s.ToCharArray() : )

Update:

Updated code to actually satisfy challenges requirements. Again assumes $s contains the input string; however, this time $n contains the number of "pieces". The remainder is printed out last. And i used PowerShell's division operator

0..($n-1)|%{$p=[math]::Floor($s.length/$n)}{$s|% Su*($_*$p) $p}{$s|% Su*($n*$p)}

Try it online!


I believe you've misunderstood the question, the input is the number of pieces (excluding remainder).
Ørjan Johansen

Oh, you're right. I mis-read the question last night : ) I'll post my updated solution when i have a chance.
GAT
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.