在没有RegExps的情况下将字符串拆分为非数字的最短程序


16

编辑:如果您正在使用Lisp,我在计数字节的底部给出了一些准则。

目标:做最短的函数,将一个字符串拆分为非数字,并返回每个字符串中仅包含数字的数组,而无需使用任何正则表达式。每个字符串中应包含前导零。

当前排名(按类别划分):

  • C / C ++ / C#/ Java: 68(C)...。
  • GolfScript / APL / J: 13(APL)
  • 所有其他: 17(重击,使用tr),24(红宝石)

规则:

(冗长的道歉)

  1. 格式必须是带有单个字符串参数的函数。如果需要正确返回数组,最多可以添加两个附加参数(例如,sh / csh / DOS Batch需要一个额外的变量引用才能返回等)。
  2. 主要函数声明不计算在内,也不会导入其他标准库。“ #include”,“ import”和“ using”不计算在内。其他一切都做。这确实包括#define和辅助函数。对困惑感到抱歉。将此作为有用的指南,以了解哪些内容不算(用C样式语法编写)
    //不计入总数,除非可以省略
    //不明显,就像Java标准库的一半一样。
    #include <stdio.h>
    
    import some.builtin.Class //不算,见上文
    
    #define printf p //计入总数
    
    / *任何其他预处理指令等。* /
    
    int i = 0; //计数
    
    someFunction(); //计数
    
    char [] [] myMainSplitFunction(char [] [] array){//不计算在内
      //这里的一切都很重要
      return returnArray; //即使这很重要。
    } //不算在内
    
    / *此处的所有内容都很重要,包括声明* /
    char [] [] someHelperFunction(char [] string){
      // 东西
    } //即使如此
    
  3. 输出必须是字符串数组或类似的字符串(可接受Java和类似的数组列表)。接受的输出的示例:String[]char[][]ArrayList,和Array(对象)。
  4. 该数组必须仅包含可变长度的字符串基元或字符串对象。返回中不得包含空字符串,但以下情况除外。注意:字符串包含连续匹配的字符串,例如下面的示例输入和输出。
  5. 如果没有匹配项,则函数主体应返回null,空数组/列表或包含空字符串的数组/列表。
  6. 不允许外部库。
  7. DOS行尾计为一个字节,而不是两个字节(已经在meta中覆盖,但需要强调)
  8. 这是最大的规则:不允许使用正则表达式。

这是一个问题,因此以最小的大小为准。祝好运!

以下是一些示例输入和输出(带有C型转义符):

输入:“ abc123def456”
输出:[“ 123”,“ 456”]

输入:“ aitew034snk582:3c”
输出:[“ 034”,“ 582”,“ 3”]

输入:“ as5493tax54 \\ 430-52@g9.fc”
输出:[“ 5493”,“ 54”,“ 430”,“ 52”,“ 9”]

输入:“ sasprs] tore \“ re \\ forz”
输出:null,[],[“”]或类似内容

请输入答案使用的字节数,一如既往地快乐打高尔夫球!


Lisp准则

以下是Lisp方言中的计算和不计算的内容:

;;; 选项1

(defun extract-strings(ab);不算
  (东西) ;;; 这里的一切都很重要
); 不算

;;; 选项2

(defun extract-strings(字符串&aux(开始0)(结束0));不计算
  (东西) ;;; 这里的一切都很重要
); 不算在内。
所有其他lambda完全计入字节数。


这不是以前问过的吗?
Ismael Miguel 2014年

1
是的,但我在Meta上重新提出了要求,并对它进行了大量修改,然后再次在此处发布。因此,不应将其分类为重复项(如果尚未关闭,则其他相关的则应关闭)。
Isiah Meadows'2

2
不应该将您的“高尔夫”发布为答案吗?
MrWhite 2014年

4
抱歉,但-1表示不允许GolfScript。应该允许所有语言。
门把手

1
@Doorknob是的,但我也了解OP的感受。即使他们不会说GolfScript,J或APL,人们也应该有机会参加比赛(我对在这些比赛中仔细阅读APL感到内.。)您能在他所链接的主题中看看我的建议吗?
Tobia 2014年

Answers:


10

APL,13个字符

(或28/30字节,请阅读下文)

{⍵⊂⍨⍵∊∊⍕¨⍳10}

我们看到您已禁止GolfScript提出您的问题。我理解您的想法,但我希望这个社区最终不会禁止APL,因为它是源远流长的真正杰出的编程语言,更不用说编写代码了很多乐趣。如果有人说,它的得分可能会有所不同感到竞争不公平。我会将对此事的想法发布到您链接的那个线程上。

同样,我一直在APL帖子中添加脚注,声称APL可以得分为1个字符= 1个字节。我的主张基于这样一个事实,即少数(大多数为商业用途)APL实现仍支持其自己的旧式单字节编码,并且APL符号映射到高128字节的值。但这可能太麻烦了,在这种情况下,您可能希望将此条目的得分记为UTF-16中的28个字节或UTF-8中的30个字节。

说明

{        ⍳10}  make an array of naturals from 1 to 10
       ⍕¨      convert each number into a string
      ∊        concatenate the strings into one (it doesn't matter that there are two 1s)
    ⍵∊         test which chars from the argument are contained in the digit string
 ⍵⊂⍨           use it to perform a partitioned enclose, which splits the string as needed

例子

      {⍵⊂⍨⍵∊∊⍕¨⍳10} 'ab5c0x'
 5  0 
      {⍵⊂⍨⍵∊∊⍕¨⍳10}  'z526ks4f.;8]\p'
 526  4  8 

字符串数组的默认输出格式无法清楚说明该数组中有多少个字符串,也没有空白。但是快速添加引号的操作应该足够清楚:

      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10} 'ab5c0x'
 "5"  "0" 
      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10}  'z526ks4f.;8]\p'
 "526"  "4"  "8" 

关于您的评论,我认为对于其他语言而言,与“速记”语言进行公平竞争时,应将其他语言中的每个符号视为一个字符。例如,我在此处发布的Mathematica解决方案应计为7(或多或少)。我认为设计带有压缩令牌的语言根本不值得。
belisarius博士2014年

您能提供高尔夫球的十六进制转储吗?我看不懂某些字符。
伊赛亚·梅多斯

@impinball hexdump将如何帮助您?好像您不会看到正在执行的操作。
mniip 2014年

@impinball的APL代码为{omega,每个iota包围通勤omega epsilon epsilon格式}。如果您需要unicode值,就可以将其复制并粘贴到任何在线工具中,即使您看不到字符(这很奇怪,因为大多数现代Unicode字体都有APL符号)。无论如何,您得到的是{\ u2375 \ u2282 \ u2368 \ u2375 \ U220A \ U220A \ u2355 \ u00a8 \ u237310}(介意最后的“10”,这是不转义序列的一部分)
托比亚

1
相反∊⍕¨⍳10,您不能使用⎕D吗?那应该是常数'0123456789'。Dyalog APL至少支持它,NARS2000也支持。
marinus 2014年

5

Python 47

实作

f=lambda s:"".join([' ',e][e.isdigit()]for e in s).split()

演示版

>>> sample=["abc123def456","aitew034snk582:3c","as5493tax54\\430-52@g9.fc","sasprs]tore\"re\\forz"]
>>> [f(data) for data in sample]
[['123', '456'], ['034', '582', '3'], ['5493', '54', '430', '52', '9'], []]

算法

将每个非数字字符转换为空格,然后分割结果字符串。一种简单明了的方法。

使用itertools的有趣解决方案(71个字符)

f1=lambda s:[''.join(v)for k,v in __import__("itertools").groupby(s,key=str.isdigit)][::2]

4

Ruby,70岁

f=->(s){s.chars.chunk{|c|c.to_i.to_s==c}.select{|e|e[0]}.transpose[1]}

在线版本进行测试

由于将任何非数字字符转换为int会在Ruby中返回0(使用to_i),因此将每个char转换为int然后再转换回char是检查数字的非正则表达式方式...


您也可以成为('0'..'9')。member?每个字符,但是您所做的已经更短了
fgp 2014年

您绝对是对的-我应该说:“一种”方式;)
David Herrmann 2014年

4

bash,26(函数内容:22 +数组分配开销4)

这不会超越其他bash答案,但它很有趣,因为它可能使您倍加注意:

f()(echo ${1//+([!0-9])/ })

用法是:

$ a=(`f "ab5c0x"`); echo ${a[@]}
5 0
$ a=(`f "z526ks4f.;8]\p"`); echo ${a[@]}
526 4 8
$ 

乍一看,//+([!0-9])/看起来很像是regexp替代,但事实并非如此。这是一个bash参数扩展,它遵循模式匹配规则,而不是正则表达式规则。

从bash函数返回真正的bash数组类型很痛苦,因此我选择返回一个以空格分隔的列表,然后在函数调用之外的数组分配中转换为数组。因此,为了公平起见,我认为(` `)函数调用周围应包含在我的分数中。


3

Mathematica 32

StringCases[#,DigitCharacter..]&

用法

inps ={"abc123def456", "aitew034snk582:3c", "as5493tax54\\430-52@g9.fc", 
        "sasprs]tore\"re\\forz"}  
StringCases[#,DigitCharacter..]&/@inps

{{"123", "456"}, 
 {"034", "582", "3"}, 
 {"5493", "54", "430", "52", "9"}, 
 {}
}

使用正则表达式的等效时间更长!

StringCases[#, RegularExpression["[0-9]+"]] &

Mathematica很讨厌正则表达式。
CalculatorFeline

3

Bash,21字节 17/21字节(由DigitalTrauma改进)

使用空格建立以空格分隔的列表 tr

function split() {
tr -c 0-9 \ <<E
$1
E
}

用空格替换任何非数字

用法

$ for N in $(split 'abc123def456'); do echo $N; done
123
456

编辑

正如下面的注释所指出的那样,该代码可以精简为17个字节:

function split() (tr -c 0-9 \ <<<$1)

由于结果严格来说不是Bash数组,因此用法应为

a=(`split "abc123def456"`); echo ${a[@]}

多余的(``)应该算在内


1
加你击败我了!但是,为什么不使用here-string代替here-document?您也可以在使用的函数内容的末尾保存换行符,(blah)而不是{blah;}split()(tr -c 0-9 \ <<<$1)。这样,您的函数体只有17个字符。
Digital Trauma 2014年

1
您的函数返回一个“以空格分隔的列表”而不是数组。当然,返回true阵列从bash函数是尴尬,但你可以在你的函数的结果至少分配给您的使用数组: a=($(split "12 3a bc123")); echo ${a[@]}。可能会说您的分数中包含“(($())””
Digital Trauma 2014年

在探索该tr方法之前,我尝试使用参数扩展进行此操作tr绝对是打高尔夫球的更好方法。
Digital Trauma

您是否尝试过tr与扩展运算符一起使用?它将显示为($(tr...)),并且在不声明函数声明的情况下,外部括号不会对您不利。它只会是命令替换部分。
伊西亚·梅多斯

我不知道这应该如何工作,但是我对Bash数组并不熟练。无论如何,该(``)构造比($())一个构造好1个字符,因此是首选。
Coaumdio

2

Smalltalk(Smalltalk / X),81

f := [:s|s asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch|ch isDigit not]]

f值:'abc123def456'-> OrderedCollection('123''456')

f值:'aitew034snk582:3c'-> OrderedCollection('034''582''3')

f值:'as5493tax54 \ 430-52@g9.fc'-> OrderedCollection('5493''54''430''52''9')

f值:'sasprs] tore \“ re \ forz'-> OrderedCollection()

感叹-Smalltalk倾向于使用veeeery长函数名...


2
那是函数名称吗?O__O
托比亚

@tobia显然是……
Isiah Meadows

asCollectionOfSubCollectionsSeparatedByAnyForWhichಠ_ಠ这个名字太长了
TuxCrafting

1

R,81

f=function(x){
s=strsplit(x,"",T)[[1]]
i=s%in%0:9
split(s,c(0,cumsum(!!diff(i))))[c(i[1],!i[1])]
}

该函数接受一个字符串并返回一个字符串列表。

例子:

> f("abc123def456")
$`1`
[1] "1" "2" "3"

$`3`
[1] "4" "5" "6"

--

> f("aitew034snk582:3c")
$`1`
[1] "0" "3" "4"

$`3`
[1] "5" "8" "2"

$`5`
[1] "3"

--

> f("as5493tax54\\430-52@g9.fc")
$`1`
[1] "5" "4" "9" "3"

$`3`
[1] "5" "4"

$`5`
[1] "4" "3" "0"

$`7`
[1] "5" "2"

$`9`
[1] "9"

--

> f("sasprs]tore\"re\\forz")
$<NA>
NULL

注意:$x是列表元素的名称。


1

Perl,53岁

编辑:在没有匹配项的情况下,sub现在根据需要返回带有空字符串的列表(而不是空列表)。

它还避免了在单个空格字符上拆分,因为它会触发“在任何空格上拆分”行为,这可能违反了规则。我可以使用/ /定界符,该定界符将在单个空间上分割,但自相矛盾的是,它看起来像使用regexp模式。我可以用unpack一些额外的字符作为代价,因此split完全消除了争议,但是我认为,最后,拆分一个文字字符(而不是空格)是可以的。

sub f{shift if(@_=split a,pop=~y/0-9/a/csr)[0]eq''and$#_;@_}

而且,不,Perl的音译运算符不执行正则表达式。0123456789如果这是问题,我可以将0-9范围展开。


只要不使用正则表达式,它就是有效的。
伊西亚·梅多斯

我的Perl不太强大。如果我理解该代码,则将非数字替换为特定的非数字,然后拆分为所选的非数字,然后过滤出空字符串。这是正确的阅读吗?
Tim Seguine 2014年

1
@TimSeguine:不完全是。非数字将被替换并压缩为单个字符,如果该分隔符恰好位于开始位置,则将其拆分成一个空字符串。如果列表包含其他条目,则将其移开。
user2846289

清单可以。
Isiah Meadows 2014年

1

C,68个字节(仅函数体)

void split (char *s, char **a) {
int c=1;for(;*s;s++)if(isdigit(*s))c?*a++=s:0,c=0;else*s=0,c=1;*a=0;
}

第一个参数是输入字符串,第二个参数是输出数组,它是一个以NULL结尾的字符串数组。必须保留足够的内存用于a在调用该函数之前,(最坏的情况:)sizeof(char*)*((strlen(s)+1)/2)

输入字符串由函数修改(每个非数字字符均替换为 '\0'

使用范例

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

void split (char *s, char **a) {
int c=1;for(;*s;s++)if(isdigit(*s))c?*a++=s:0,c=0;else*s=0,c=1;*a=0;
}   

void dump(char **t) {
    printf("[ ");for(;*t;t++)printf("%s ", *t);printf("]\n");
}   

int main() {
    char **r = malloc(1024);
    char test1[] = "abc123def456";
    char test2[] = "aitew034snk582:3c";
    char test3[] = "as5493tax54\\430-52@g9.fc";
    char test4[] = "sasprs]tore\"re\\forz";
    split(test1,r); 
    dump(r);
    split(test2,r); 
    dump(r);
    split(test3,r); 
    dump(r);
    split(test4,r); 
    dump(r);
    return 0;
}

输出量

[ 123 456 ]
[ 034 582 3 ]
[ 5493 54 430 52 9 ]
[ ]

非高尔夫版本:

void split (char *s, char **a) {
    int c=1; // boolean: the latest examined character is not a digit
    for(;*s;s++) {
        if(isdigit(*s)) {
            if(c) *a++ = s; // stores the address of the beginning of a digit sequence
            c=0;
        } else {
            *s=0; // NULL-terminate the digit sequence
            c=1;
        }   
    }   
    *a = 0; // NULL-terminate the result array
} 

1

VBScript,190(164,不带函数声明)

Function f(i)
For x=1 To Len(i)
c=Mid(i,x,1)
If Not IsNumeric(c) Then
Mid(i,x,1)=" "
End If
Next
Do
l=Len(i)
i=Replace(i,"  "," ")
l=l-Len(i)
Loop Until l=0
f=Split(Trim(i)," ")
End Function

尽管完全没有竞争力,但令我惊讶的是,鉴于它的详细程度,VBScript如此简短(仅CR就有13个字节)。它循环遍历字符串,用空格替换所有非数字字符,然后将所有空格减少为单个空格,然后使用空格定界符对其进行分割。

测试用例

Input: "ab5c0x"
Output: 5,0

Input: "z526ks4f.;8]\p"
Output: 526,4,8

根据我在meta上阅读的内容,DOS行尾算作一个字符。
Isiah Meadows 2014年

我建议您进行修改。
Isiah Meadows 2014年

该计数已经假设Linux样式为1个字节的行结尾。根据我的计数,我得到190个字符(刚刚再次验证)。
Comintern

好。我一定算错了。
伊西亚·梅多斯

1

普通Lisp(根据字母1个;根据精神≈173)

这是可读的版本。由于诸如digit-char-pand position-if和的长名称,因此字节数相当高vector-push-extend

(defun extract-numeric-substrings (string &aux (start 0) (end 0) (result (make-array 0 :adjustable t :fill-pointer 0)))
  (loop 
     (unless (and end (setq start (position-if #'digit-char-p string :start end)))
       (return result))
     (setq end (position-if (complement #'digit-char-p) string :start (1+ start)))
     (vector-push-extend (subseq string start end) result)))
(extract-numeric-substrings "abc123def456")
#("123" "456")

(extract-numeric-substrings "aitew034snk582:3c")
#("034" "582" "3")

(extract-numeric-substrings "as5493tax54\\430-52@g9.fc")
#("5493" "54" "430" "52" "9")

(extract-numeric-substrings "sasprs]tore\"re\\forz")
#()

“函数声明”的概念有点模糊。这是一个只有一个字节(x函数主体中的字符)的版本;其他所有内容都捆绑在该函数的lamba列表(该函数的声明的一部分)的辅助变量中:

(defun extract-numeric-substrings (string 
                                   &aux (start 0) (end 0) 
                                   (result (make-array 0 :adjustable t :fill-pointer 0))
                                   (x (loop 
                                         (unless (and end (setq start (position-if #'digit-char-p string :start end)))
                                           (return result))
                                         (setq end (position-if (complement #'digit-char-p) string :start (1+ start)))
                                         (vector-push-extend (subseq string start end) result))))
  x)

实际的字节数将取决于必须将多少个辅助声明移入主体才能被接受。某些局部功能重命名也将有所帮助(例如,缩短position-if两次,因为它出现两次,使用单字母变量,等等)。

该程序的呈现具有220个字符:

(LOOP(UNLESS(AND END(SETQ START(POSITION-IF #'DIGIT-CHAR-P STRING :START END)))(RETURN RESULT))(SETQ END(POSITION-IF(COMPLEMENT #'DIGIT-CHAR-P)STRING :START(1+ START)))(VECTOR-PUSH-EXTEND(SUBSEQ STRING START END)RESULT))

如果没什么,这应该促进Common Lisp的&aux变量

loop当然,这可以用以下代码更简洁地编写:

(defun extract-numeric-substrings (s &aux (b 0) (e 0) (r (make-array 0 :fill-pointer 0)))
  (loop 
     with d = #'digit-char-p 
     while (and e (setq b (position-if d s :start e)))
     finally (return r)
     do 
       (setq e (position-if-not d s :start (1+ b)))
       (vector-push-extend (subseq s b e) r)))

loop形式,额外的空间删除,有173个字符:

(LOOP WITH D = #'DIGIT-CHAR-P WHILE(AND E(SETQ B(POSITION-IF D S :START E)))FINALLY(RETURN R)DO(SETQ E(POSITION-IF-NOT D S :START(1+ B)))(VECTOR-PUSH-EXTEND(SUBSEQ S B E)R))

我会指望从开始(result到最后的括号成为正文。定义名称和参数的部分是声明。
伊赛亚·梅多斯

请参考我修改后的规则中的规则2,以查看我在函数声明中的真正含义(基本上,声明函数名称,参数,以及在语法上的要求(这在解释语言中很少见,返回类型))。
伊西亚·梅多斯

@impinball是的,“ 1”计数有点像个玩笑,但是这里重要的是在这里result 声明为参数;它只有非常简单的初始化形式。原则上,这是具有可选值的可选参数,该可选参数具有由某些复杂表达式计算的默认值。(在较简单的情况下,很容易想象类似char* substring( char *str, int begin, int end(0) )某种语言的某种事物,使用类似C的语法来指定end可选的内容,如果未提供,则其值为0。我只是强调一个事实,其中某些术语是
Joshua Taylor

@impinball不太具体,语言不可知,无法防止某些笨拙的字节计数。:)
约书亚·泰勒

未指定参数的第一部分是我要统计计数的位置(例如(defun fn (string &aux (start 0) (end 0),不计数,但lambda中剩余的所有内容都会统计)。
Isiah Meadows 2014年

0

JavaScript,240个字节

对于那些好奇的人来说,这可能是我的超级高尔夫:

function split(a) { // begin function
function f(c){for(var a=-1,d=9;d--;){var e=c.indexOf(d+"");0
>e||e<a&&(a=e)}return 0<a?a:null}var c=f(a);if(null==c)retur
n null;var d=[];for(i=0;;){a=a.substring(c);d[i]||(d[i]="");
c=f(a);if(null==c)break;d[i]+=a.charAt(c);0<c&&i++}return d;
} // end function

上面漂亮的印刷品:

function split(a) {
    function f(c) {
        for (var a = -1, d = 9;d--;) {
            var e = c.indexOf(d + "");
            0 > e || e < a && (a = e);
        }
        return 0 < a ? a : null;
    }
    var c = f(a);
    if (null == c) return null;
    var d = [];
    for (i = 0;;) {
        a = a.substring(c);
        d[i] || (d[i] = "");
        c = f(a);
        if (null == c) break;
        d[i] += a.charAt(c);
        0 < c && i++;
    }
    return d;
}

上面的普通描述性代码

function split(a) {
    function findLoop(string) {
        var lowest = -1;
        var i = 9;
        while (i--) {
            var index = string.indexOf(i + '');
            if (index < 0) continue;
            if (index < lowest) lowest = index;
        }
        return (lowest > 0) ? lowest : null;
    }
    var index = findLoop(a);
    if (index == null) return null;
    var ret = [];
    i = 0;
    for ( ; ; ) {
        a = a.substring(index);
        if (!ret[i]) ret[i] = '';
        index = findLoop(a);
        if (index == null) break;
        ret[i] += a.charAt(index);
        if (index > 0) i++;
    }
    return ret;
}

0

PHP 134

function f($a){
$i=0;while($i<strlen($a)){!is_numeric($a[$i])&&$a[$i]='-';$i++;}return array_filter(explode('-',$a),function($v){return!empty($v);});
}

您可以通过省略回调来缩短它array_filter。这将自动删除所有false强制转换为布尔值的条目。
kelunik 2014年

@kelunik也将滤除0
Einacio

0

C,158

#define p printf
char s[100],c;int z,i;int main(){while(c=getchar())s[z++]=(c>47&&c<58)*c;p("[");for(;i<z;i++)if(s[i]){p("\"");while(s[i])p("%c",s[i++]);p("\",");}p("]");}

由于C没有内置的数组打印功能,因此我必须自己完成这项工作,因此我很抱歉每个输出中都有一个逗号结尾。从本质上讲,该代码的作用是读取字符串,如果不是数字,则将其替换为'\ 0',然后循环浏览代码并打印出所有数字链。(EOF = 0)

输入:ab5c0x
输出:[“ 5”,“ 0”,]

输入:z526ks4f。; 8] \ p
输出:[“ 526”,“ 4”,“ 8”,]


根据问题的规则(规则2),您只需要计算函数主体中的字符。因此,您的解决方案实际上将少于170个字节。不过,我不确定计数是否包括函数体外部的变量原型。
grovesNL 2014年

我将修改规则:#defines,变量声明等将起作用,而函数声明将不起作用。
伊赛亚·梅多斯

另外,上次我检查时,C中有一个类型被标记为char[][]合法。如果您以(或char**)的价格返回,则可以。
伊西亚·梅多斯

不必是文本输出吗?我虽然程序应该以字符串格式输出数组
ASKASK

0

C#,98

static string[] SplitAtNonDigits(string s)
{
    return new string(s.Select(c=>47<c&c<58?c:',').ToArray()).Split(new[]{','},(StringSplitOptions)1);
}

首先,这使用LINQ .Select()扩展方法将所有非数字转换为逗号。string.Replace()会更可取,因为它返回a string而不是a IEnumerable<char>,但是string.Replace()只能使用单个char或字符串,而不能使用诸如char.IsDigit() or47<c&c<58

如前所述,.Select()应用于字符串会返回一个IEnumerable<char>,因此我们需要将其转换为字符串,方法是将其转换为数组并将该数组传递给string构造函数。

最后,我们使用分割逗号string.Split()(StringSplitOptions)1是一种简短的说法StringSplitOptions.RemoveEmptyEntries,它将自动处理多个连续的逗号和字符串开头/结尾的逗号。


1
相反的char.IsDigit(c),你可以使用'/'<c&&c<':'
grovesNL

1
好点...甚至更好47<c&&c<58。(坦率地说,我很惊讶它可以与数字一起使用,但是显然它确实可以)。
BenM 2014年

1
而且我可以使用一个'&'而不是一个双'&&'来保存一个额外的有价值的字符。在C#中,当两个操作数均为布尔值时,此逻辑仍为逻辑“与”-仅当它们为整数时才进行按位“与”运算。
BenM 2014年

好一个。我不知道它能够做到这一点。
grovesNL 2014年

稍微短一点的变体是在空白处代替,,然后手动删除空项目return new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon 2014年

0

JS /节点:168 162 147 138个字符

function n(s){
var r=[];s.split('').reduce(function(p,c){if(!isNaN(parseInt(c))){if(p)r.push([]);r[r.length-1].push(c);return 0;}return 1;},1);return r;
}

美化版本:

function n(s) {
  var r = [];
  s.split('').reduce(function (p, c) {
    if (!isNaN(parseInt(c))) {
      if (p) {
        r.push([]);
      }
      r[r.length - 1].push(c);
      return 0;
    }
    return 1;
  }, 1);
  return r;
}

这个问题只希望返回数组,因此您可以删除console.log(r)其他内容
不是查尔斯(Charles)

函数声明不计入分数(原因是为了帮助公平竞争)
Isiah Meadows

好。根据@impinball的评论调整分数。(实际上,这里声明了两个函数。字符数包括匿名函数)
palanik

这应该。我更新了规则以更好地解释它。
伊西亚·梅多斯

同时,想出了更好的方法……
palanik 2014年


0

PHP 204

function s($x){$a=str_split($x);$c=-1;$o=array();
for($i= 0;$i<count($a);$i++){if(ord($a[$i])>=48&&ord($a[$i])<=57)
{$c++;$o[$c]=array();}while(ord($a[$i])>=48&&ord($a[$i])<=57)
{array_push($o[$c],$a[$i]);$i++;}}return $o;}

描述代码:

function splitdigits($input){

    $arr = str_split($input);
    $count = -1;
    $output = array();
    for($i = 0; $i < count($arr); $i++){


    if(ord($arr[$i]) >= 48 && ord($arr[$i]) <= 57){
        $count++;
        $output[$count] = array();
    }

    while(ord($arr[$i]) >= 48 && ord($arr[$i]) <= 57){
        array_push($output[$count], $arr[$i]);
        $i++;
    } 

}

return $output;
}

这是很长的代码,我相信此代码高尔夫将有一个更短的php版本。这是我可以在php中提出的。


也有一些改进:您可以替换array()使用[]array_push($output[$count], $arr[$i]);$output[$count][]=$arr[$i];ord()支票is_numeric()。而且您甚至不需要拆分字符串即可遍历其字符。同样,只有函数计算的内码,所以它是你的char数为204
Einacio

函数声明不计算在内。请参考规则2,以获取有关哪些内容重要和哪些内容不重要的指南。
伊西亚·梅多斯 Isiah Meadows)

0

蟒蛇

def find_digits(_input_):
    a,b = [], ""
    for i in list(_input_):
        if i.isdigit(): b += i
        else:
            if b != "": a.append(b)
            b = ""
    if b != "": a.append(b)
    return a

0

Python 104 83

def f(s, o=[], c=""):
    for i in s:
        try:int(i);c+=i
        except:o+=[c];c=""
    return [i for i in o+[c] if i]

@Abhijit的答案非常聪明,这只是我所想到的“最小化”版本。

assert f("abc123def456") == ["123", "456"]
assert f("aitew034snk582:3c") == ["034", "582", "3"]
assert f("as5493tax54\\430-52@g9.fc") == ["5493", "54", "430", "52", "9"]
assert f("sasprs]tore\"re\\forz") == []

这不会产生任何输出,因此,如果在声明中定义了一些变量,则代码如果一一运行就可以正常工作。


如果需要的话,您不必计算函数声明。正如抬起头来
伊塞亚草甸

0

PHP 98 89

就像DigitalTrauma的bash答案一样,它不使用正则表达式。

function f($x) {
// Only the following line counts:
for($h=$i=0;sscanf(substr("a$x",$h+=$i),"%[^0-9]%[0-9]%n",$j,$s,$i)>1;)$a[]=$s;return@$a;
}

测试用例:

php > echo json_encode(f("abc123def456")), "\n";
["123","456"]
php > echo json_encode(f("aitew034snk582:3c")), "\n";
["034","582","3"]
php > echo json_encode(f("as5493tax54\\430-52@g9.fc")), "\n";
["5493","54","430","52","9"]
php > echo json_encode(f("sasprs]tore\"re\\forz")), "\n";
null

0

哈斯克尔31

{-# LANGUAGE OverloadedStrings #-}
import Data.Char (isDigit)
import Data.Text (split)

f=filter(/="").split(not.isDigit)

它将字符串拆分为所有非数字字符,并删除由连续定界符生成的空字符串。


0

没有功能声明的VBA 210、181

Function t(s)
Dim o()
For Each c In Split(StrConv(s,64),Chr(0))
d=IsNumeric(c)
If b And d Then
n=n&c
ElseIf d Then:ReDim Preserve o(l):b=1:n=c
ElseIf b Then:b=0:o(l)=n:l=l+1:End If:Next:t=o
End Function

0

Rebol(66个字符)

remove-each n s: split s complement charset"0123456789"[empty? n]s

解开并包装在函数声明中:

f: func [s] [
    remove-each n s: split s complement charset "0123456789" [empty? n]
    s
]

Rebol控制台中的示例代码:

>> f "abc123def456"
== ["123" "456"]

>> f "aitew035snk582:3c"
== ["035" "582" "3"]

>> f "as5493tax54\\430-52@g9.fc"
== ["5493" "54" "430" "52" "9"]

>> f {sasprs]torer"re\\forz}
== []

0

JavaScript,104 97 89

打高尔夫球:

编辑:当循环走出数组的末尾时,cundefined,这是虚假的并终止循环。

2/27:使用?:可以节省的冗长性if/else

function nums(s) {
s+=l='length';r=[''];for(k=i=0;c=s[i];i++)r[k]+=+c+1?c:r[k+=!!r[k][l]]='';
r[l]--;return r
}

车厢内的回车是为了便于阅读,而不是解决方案的一部分。

取消高尔夫:

想法是将每个字符(如果是数字)追加到数组的最后一个条目,否则确保最后一个数组的条目是字符串。

function nums(s) {
    var i, e, r, c, k;
    k = 0;
    s+='x'; // ensure the input does not end with a digit
    r=[''];
    for (i=0;i<s.length;i++) {
        c=s[i];
        if (+c+1) { // if the current character is a digit, append it to the last entry
            r[k] += c;
        }
        else { // otherwise, add a new entry if the last entry is not blank
            k+=!!r[k].length;
            r[k] = '';
        }
    }
    r.length--; // strip the last entry, known to be blank
    return r;
}

0

Javascript,72

function f(a){
 a+=".",b="",c=[];for(i in a)b=+a[i]+1?b+a[i]:b?(c.push(b),""):b;return c
}

不打高尔夫球

a+=".",b="",c=[];        //add '.' to input so we dont have to check if it ends in a digit
for(i in a)
    b=+a[i]+1?           //check if digit, add to string if it is
        b+a[i]:         
    b?                   //if it wasnt a digit and b contains digits push it
        (c.push(b),""):  //into the array c and clear b
    b;                   //else give me b back
return c

样本输入/输出

console.log(f("abc123def456"));
console.log(f("aitew034snk582:3c"));
console.log(f("as5493tax54\\430-52@g9.fc"));
console.log(f("sasprs]tore\"re\\forz"));

["123", "456"]
["034", "582", "3"]
["5493", "54", "430", "52", "9"]
[] 

JSFiddle


1
我喜欢!比我自己简单得多。您可以通过更换再跌8个字符if(+a[i]+1)b+=a[i];else if(b)c.push(b),b=""b=+a[i]+1?b+a[i]:b?(c.push(b),""):b
DocMax 2014年

@DocMax thx,我进行了编辑以包括您的建议:)。那(c.push(b),"")似乎很聪明,从未见过。
Danny

我忘记了它,直到今天早些时候在codegolf.stackexchange.com/questions/22268#22279
DocMax(2014年

这是无效的,“”被误认为是0,这是一个难以管理的JavaScript怪癖。尝试'12 34 56'
edc65

0

R 52

此函数按字符类(不是regex!::)拆分字符串。类为N-数字字符,P {N}表示否定该类。o = T表示省略空子字符串。

x
## [1] "wNEKbS0q7hAXRVCF6I4S" "DpqW50YfaDMURB8micYd" "gwSuYstMGi8H7gDAoHJu"
require(stringi)
stri_split_charclass(x,"\\P{N}",o=T)
## [[1]]
## [1] "0" "7" "6" "4"

## [[2]]
## [1] "50" "8" 

## [[3]]
## [1] "8" "7"

0

PHP 99

<?php

$a = function($s) {
foreach(str_split($s)as$c)$b[]=is_numeric($c)?$c:".";return array_filter(explode('.',implode($b)));
};

var_dump($a("abc123def456"));
var_dump($a("aitew034snk582:3c"));
var_dump($a("as5493tax54\\430-52@g9.fc"));
var_dump($a("sasprs]tore\"re\\forz"));


输出量

array(2) {
  [3]=>
  string(3) "123"
  [6]=>
  string(3) "456"
}
array(3) {
  [5]=>
  string(3) "034"
  [8]=>
  string(3) "582"
  [9]=>
  string(1) "3"
}
array(5) {
  [2]=>
  string(4) "5493"
  [5]=>
  string(2) "54"
  [6]=>
  string(3) "430"
  [7]=>
  string(2) "52"
  [9]=>
  string(1) "9"
}
array(0) {
}

0

JavaScript的88

不计算函数n(x){}时为88个字符

function n(x){
y=[],i=0,z=t=''
while(z=x[i++])t=!isNaN(z)?t+z:t&&y.push(t)?'':t
if(t)y.push(t)
return y
}
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.