递增字符串中的每个数字


11

给定一个包含十进制数字的字符串:

teststring134this 123test string54 100

将这个字符串中的每个数字加一以给出新的字符串

teststring135this 124test string55 101

字符串可以提供为:

  • 命令行参数
  • 标准输入
  • 硬编码的变量或函数参数

涵盖所有可能的职位:

  • 作为单词的前缀;123test124test
  • 作为一个词的后缀;test123test124
  • 一句话 te123stte124st
  • 一个人test 123 testtest 124 test

这是Python中的非解决方案:

NUMBERS = '0123456789'

def increment(s):
    out = ''

    number = ''
    for c in s:
        if c in NUMBERS:
            number += c
        else:
            if number != '':
                out += str(int(number) + 1)
                number = ''
            out += c

    if number != '':
        out += str(int(number) + 1)
        number = ''

    return out


print "\"%s\"" % (increment('teststring134this 123test string54 100'))

这是一个code-golf问题,最短的代码胜出。


5
有趣的事实:这可以通过3个纯正则表达式替换(没有回调)来完成stackoverflow.com/questions/12941362/…(虽然那不是最经典的方式)
Martin Ender

4
您指定了输入但未指定输出。根据您的输入规范,我假设STDOUT和返回值都很好。但是我们是否也可以将结果存储在硬编码变量中(就像我们可以从中获取输入一样)?
Martin Ender 2014年

1
那携带呢?999会怎样?
蓬松的


7
那负数呢?带小数点的数字呢?带小数点但前面没有小数的数字怎么办(也许除了负号)?
彼得·泰勒

Answers:




11

Vim-13次击键

0qqqqq^Al@qq@q

期望输入为当前行。

或对于8 + ceil(log(n))击键中的有限数目的数字(例如999):

0qq^Alq999@q

我似乎无法完成这项工作。...(我正在使用vim 7.0.237)
Jerry Jeremiah

10

JavaScript(ES6)-28

H=k=>k.replace(/\d+/g,k=>++k)

使用运行H("test 123 234t")


1
您可以取出H=并将其设为匿名函数。
Mama Fun

8

Perl,23岁

假设输入字符串已分配给 $_

s/\d+/@{[$&+1]}/g;print

8

Python 2-59

提供字符串作为变量 n

import re;print re.sub('\d+',lambda x:`int(x.group())+1`,n)

6

C99-86(GCC 4.9.0和Visual C ++ 2013)

编辑:GCC 4.9.0(带有-std = c99)和Visual C ++ 2013均成功构建(带有警告)没有包含的相同代码。我不知道你能做到!感谢您的提示。

编辑:我什至没有想到我应该将它即时写入屏幕,而不是创建字符串然后打印。那有很大的不同。谢谢丹尼斯!

这使用的是硬编码的字符串,但是字符串的内容不计入总数(计数为=“”)。

main(i){for(char*q,*s="test123test999test-1test";i=strtol(s,&q,0),*s;q>s?printf("%d",i+1,s=q):putchar(*s++));}

基本上,它一次遍历字符串一个字符,并检查每个字符是否为整数。如果是,它将递增整数并将其写入输出,否则将当前字符复制到输出。

这会泄漏硬编码的字符串,因为它会增加s。


1
我确定您可以摆脱某些includes,并且仍可以使用gcc进行编译。
Martin Ender 2014年

1
这是否可以与包含eg的字符串一起使用99
anatolyg 2014年

@MartinBüttner:是的,但是那将不是有效的C语言,只是某些在gcc上起作用的东西。
R .. GitHub停止帮助ICE 2014年

@R ..但是,PPCG通常允许使用。我经常看到(并随后完成)它,而没有任何人抱怨。
Martin Ender 2014年

是的,这是我的普遍看法。语言应该被列为“海湾合作委员会”或或类似的,而不是C,如果它不是真正有效C. :-)“关于C [特别弓/等的黑客碰巧工作。]”
R.,GitHub的STOP帮助ICE

5

J(20)

期望输入存储在变量中a

'\d+'>:&.".rxapply a

测试:

   a=:'teststring134this 123test string54 100'
   '\d+'>:&.".rxapply a
teststring135this 124test string55 101

5

(f?)lex(39)

档案inc.l

%%
[0-9]+ printf("%d",atoi(yytext)+1);

编译:

$ flex inc.l
$ gcc lex.yy.c -o inc -lfl

跑:

$ echo 'teststring134this 123test string54 100' | ./inc
teststring135this 124test string55 101

$ i='(-: 2 empty bottles of beer :-)'
$ tty=$(tty)
$ for n in {2..5} ; do i=$(./inc<<<$i|tee $tty) ; done
(-: 3 empty bottles of beer :-)
(-: 4 empty bottles of beer :-)
(-: 5 empty bottles of beer :-)
(-: 6 empty bottles of beer :-)

我没有用原件对此进行测试lex。欢迎发表评论。


1
您可以删除尾随,%%因为这不是用户代码:flex.sourceforge.net/manual/…–
Josh

嘿...是的!我尝试了但没有尾随换行符而失败了...然后我没有尝试添加最后的换行符... ;-) ...愚蠢的错误!

3

Emacs-20个字符

C-M-% [0-9]+ RET \,(1+ \#0) RET !

要求要处理的文本出现在当前缓冲区中。我将CM-%视为一个字符,因为在按住三个修饰符的情况下可以通过一次按键输入。


3

GNU sed,304(包括1个-r标志)

我投票否决了这个问题,可能是重复的问题,但这可能与之相反,因为不能轻易更改此答案以在此工作。到目前为止,答案最长。

sed文档中此示例的启发,尽管需要一些工作来处理字符串中的多个数字:

:d
s/9([^0-9]+|$)/_\1/g
td
s/8(_*)([^0-9]+|$)/9\1\2/g
s/7(_*)([^0-9]+|$)/8\1\2/g
s/6(_*)([^0-9]+|$)/7\1\2/g
s/5(_*)([^0-9]+|$)/6\1\2/g
s/4(_*)([^0-9]+|$)/5\1\2/g
s/3(_*)([^0-9]+|$)/4\1\2/g
s/2(_*)([^0-9]+|$)/3\1\2/g
s/1(_*)([^0-9]+|$)/2\1\2/g
s/0(_*)([^0-9]+|$)/1\1\2/g
s/(^|[^0-9_]+)(_+)/\11\2/g
y/_/0/

输出:

$ for s in "teststring134this 123test string54 100" "123test" "test123" "te123st" "test 123 test" ; do echo "$s" | sed -rf incr.sed ; done
teststring135this 124test string55 101
124test
test124
te124st
test 124 test
$ 

请注意,这会临时插入_字符,因此如果_输入流中有字符,可能会导致错误的结果。作为缓解措施,我们可以_用一些不可打印的字符(例如ASCII 0x07 BEL)替换sed脚本中的s,并假设输入流仅包含可打印的ASCII。当我对其进行测试时,这似乎工作正常。



2

Lua-68个字符

d='(%D-)'for k,i,j in s:gmatch(d..'(%d+)'..d)do io.write(k,i+1,j)end

期望输入存储在中。


2

CJam,67 58 53 48 31个字符

这个问题就像CJam的最糟糕的问题。没有正则表达式,没有模式匹配,没有异常捕获。但是我们开始(#YOLO)

Sl+_A,sNerN%\[_A,s-Ner~]:)]zs1>

这将字符串分成仅字母和数字的组。递增每个数字并缝回两个数组,每次取一个元素。


先前的解决方案:

L_l{:Ci57-zA<:RC*+:N\R!N*NNW?i):NL?+RLC?@R*}/NL?

在这里在线尝试

这个怎么运作:

基本思想是,如果字符是数字,则继续将其存储在字符串中,并在获得非数字字符后将递增的值转储到最终字符串中。

L_                                               "Push two empty strings to stack,"
                                                 "first representing the final string"
                                                 "and second, the current ongoing number";
  l{                                       }/    "Run this block for each character of input string";
    :Ci                                          "Store the character to C and convert to"
                                                 "its ASCII equivalent integer";
       57-zA<:R                                  "Subtract 57 from the integer and compare"
                                                 "its absolute value with 10. Numeric character"
                                                 "would result to true here. Store the result in R";
               C*+:N                             "Take either 0 or 1 characters from C based"
                                                 "on value of R, add it to the second string"
                                                 "from first step. Also store the value in N";
                    \                            "Switch the strings. Now the string containing"
                                                 "the final result string is at top of stack";
                     R!N*                        "If the character was not a digit and N contains a number in it";
                         NNW?i):NL?+             "Convert N to number and increment it."
                                                 "If N is blank, take 0 instead. Put the final"
                                                 "value back in N and add it to the final result string";
                                    RLC?         "If the character was not a digit, push it to stack";
                                        @R*      "Put the ongoing numeric string back to top of stack";
                                             NL? "This is to handle the case when the last number"
                                                 "is not followed by a string, so stack will"
                                                 "have a string at top. Push the value of N to stack in that case";

1

眼镜蛇-88

do(s='')=RegularExpressions.Regex.replace(s,'\d+',do(m as Match)='[int.parse("[m]")+1]')

1

C# - 178个 169 157字符

假设允许像999这样的数字溢出到000,并且-+ ,. E不是数字的一部分。

class T{static void Main(){var a="".ToCharArray();for(int b=1,c,i=a.Length;i-->0;b=48>c|c>57?7:b>0?c>56?a[i]='0':++a[i]*0:b)c=a[i];System.Console.Write(a);}}

可读性更好的形式:

class T
{
    static void Main()
    {
        var a="7teststring134this 123test string59 100".ToCharArray();

        for (int b=3, c, i=a.Length; i-->0;
            b=48>c|c>57
                ?7
                :b>2
                    ?c>56?a[i]='0':++a[i]*0
                    :b
        ) c=a[i];

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

我是新来的,以前从未尝试过编码高尔夫球,只是尝试一下:)

我想知道是否有人有想法让它变得更短...

如果我们可以省略所有围绕实际代码的必要框架,那么参与C#将会很不错-这样,它只有82个字符,并且无需调用任何强大的系统功能即可。


与指针相同(182个字符):

class T
{
    unsafe static void Main()
    {
        char[] a="7teststring134this 123test string59 100".ToCharArray();

        int b=3;
        fixed (char* s=&a[0])
            for (var p=s+a.Length; p-->s; )
                b=*p<48|*p>57
                    ?7
                    :b>2
                        ?*p>56?*p='0':++*p*0
                        :b;

        System.Console.Write(a);
        System.Console.ReadKey();
    }
}

现在,不会溢出,这可以正确处理999种情况(223个字符):

class T
{
    static void Main()
    {
        var s=new System.Text.StringBuilder("9999teststring134this 123test string99 100");

        for (int b=3, c, i=s.Length; i-->0; )
        {
            c=s[i];
            b=48>c|c>57
                ?b>8?8:7
                :b>2
                    ?c>56?c-(s[i]='0'):++s[i]*0
                    :b;
            if (b>8&i<1|b==8) s.Insert(i+9-b, '1');
        }

        System.Console.Write(s);
        System.Console.ReadKey();
    }
}

另一个不同的旧版本,它从标准输入中读取并使用递归:

namespace System {
    using C=Console;
    class T {
        class t {
            byte b=1;
            string s="";
            void R() {
                var c=C.Read();
                if (c>31) {
                    R();
                    if (48>c|c>57) b=1;
                    else if (b==1) c=c==57?48:++c*b--;
                    s=(char)c+s;
                }
            }
            public t() {
                R();
                C.Write(s);
            }
        }
        static void Main() {
            new t();
            C.ReadKey();
        }
    }
}

注意:Console.ReadKey();字符串本身不应该计算在内。

我已经对此进行了多次改进,请参见评论。我会说:仍然有更多改进的余地:)抱歉,不过,但是我认为不同版本足够有趣,可以保留它们。


不,不允许摆脱“环境”。我认为if(c==57)您可以编写c--;而不是来编写第二个代码c=48;,那么三元运算符也是如此。实际上有很多高尔夫技巧。也许您应该访问codegolf.stackexchange.com/questions/2203/tips-for-golfing-in-c
骄傲的haskeller 2014年

谢谢,我对高尔夫一无所知:)您在这里看到的一切都是我发明的;-) 57-1不是48。所以我不明白。
maf-soft 2014年

糟糕:-) :-) :-) :-)
骄傲的haskeller 2014年

我不太了解C#,但是我想您可以使用一些运算符将其粘在一起,例如... ? ... : c++*b--
自豪的haskeller 2014年

:发送你的C提示而不是C#技巧顺便说一句对不起codegolf.stackexchange.com/questions/173/...
傲haskeller

1

Groovy,38个字节

{it.replaceAll(/\d+/,{(it as int)+1})}

Uggghhh ...我绝对讨厌的话replaceall他们毁了所有的正则表达式了高尔夫对我来说。


1
(it as int)+1it.next()
manatwork '16

0

PHP-91字节

<?$i=fgets(STDIN);for($n=0;$n<strlen($i);$n++)if(is_numeric($i[$n]))$i[$n]=$i[$n]+1;echo$i;

我不想使用正则表达式。PHP无法直接递增字符串偏移量,因此,我需要在递增步骤中添加一些字节。这一行脚本让我想起了PHP脚本编写的一个非常黑暗的时代...


我刚刚观察到,这个问题要求您增加一系列算法的结果数。这个答案是不正确的。但是我真的觉得,操作员应该添加更多关于他想要的细节。
Alexandre Teles 2014年

0

K,56

{" "/:{,/$(`$a)^`$$1+"I"$a:_[;x]@&~~':x in .Q.n}'" "\:x}

0

sed和bash-40(包括调用和管道)

$ cat << EOF |sed 's/[0-9]\+/$((\0+1))/g;s/^/echo /'|bash
teststring134this 123test string54 100
123test
test123
te123st
test 123 test
EOF

输出:

teststring135this 124test string55 101
124test
test124
te124st
test 124 test

我尝试了以下测试字符串:42;rm -rf /第一次成功。
丹尼斯

2
您可以更改\0&(-1字符),$((…))$[…](-2个字符),s/^/echo /iecho \\(-2个字符),以缩短目前的代码。但是最好先解决@Dennis提到的错误。(他写道:“成功的第一时间”为乐趣,并为有关问题的暗示其实你的代码输入失败含有。;#`…`$(…)也许其他特殊字符了。)
manatwork

任意代码执行是一个功能:-)
mgjk 2014年

没有某种输入限制并保持代码很小,可能没有办法走这条路。解决方案的本质是转换输入并使用解释器进行数学运算,因为sed无法做到这一点。一旦用户输入命中了解释器,转义就很麻烦了。缺少前面的sed示例,sed不能进行数学运算。
mgjk 2014年

简短一些:eval echo `sed 's/[0-9]\+/$[&+1]/g'`-仍然有代码注入问题,根据我对另一个类似问题的回答codegolf.stackexchange.com/a/37145/11259
Digital Trauma

0

Java 7,119个字节

void c(String s){for(String x:s.split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}

如果要求是程序而不是功能,则为149字节:

class M{public static void main(String[]a){for(String x:a[0].split("(?=[^\\d]+)|(?<=[^\\d]+)"))System.out.print(x.matches("\\d+")?new Long(x)+1:x);}}

取消测试代码:

在这里尝试。

class M{
  static void c(String s){
    for(String x : s.split("(?=[^\\d]+)|(?<=[^\\d]+)")){
      System.out.print(x.matches("\\d+")
                        ? new Long(x) + 1
                        : x);
    }
  }

  public static void main(String[] a){
    c("123test");
    System.out.println();
    c("test123");
    System.out.println();
    c("te123st");
    System.out.println();
    c("test 123 test");
    System.out.println();
    c("7teststring134this 123test string59 100");
  }
}

输出:

124test
test124
te124st
test 124 test
8teststring135this 124test string60 101

0

Gema,14个字符

<D>=@add{$1;1}

样品运行:

bash-4.3$ gema '<D>=@add{$1;1}' <<< 'teststring134this 123test string54 100'
teststring135this 124test string55 101

0

DASH,16字节(非竞争)

rstr[R"\d+""g"+1

这将返回功能/部分应用程序。

用法:

rstr[R"\d+""g"+1]"test 123 234t"

说明

rstr[          #. replace any parts of the input
  R "\d+" "g"  #. matching /\d+/g
  +1           #. with its incremented form
]

这个答案是非竞争性的吗?
丹尼斯

哦裂口:(我总觉得这是一个目录的问题。
妈妈乐辊

0

CJam,18个字节

q_A,s-_:(:`ers~]:)

在这里尝试。

说明

q         e# Read input.
_A,s-     e# Duplicate and remove digits.
_         e# Duplicate.
:(:`      e# Decrement and get the string representation of each character.
er        e# Map the characters to the decremented string representation.
s~        e# Flatten to string and evaluate.
]:)       e# Wrap in an array and increment each element.

0

R,83个字节

晚会。假设输入存储在variable中x。可能不需要使用它regmatches来解决此问题,但是如果没有任何外部程序包,我将无法找出向量化的替换方法。

paste0(el(r(x,m<-gregexpr("\\d+",x),T)),c(as.numeric(el(r(x,m)))+1,""),collapse="")

脱节和解释

r=regmatches                                        # Alias for regmatch
y=r(x<-scan(,""),m<-gregexpr("\\d+",x))             # return match digits
i=r(x,m,T)                                          # return inverted match (non-digits)
paste0(el(i),c(as.numeric(el(y))+1,""),collapse="") # join digits+1 and non-digits, element-wise

输出示例

input: 
"teststring135this 124test string55 101"

output:
[1] "teststring136this 125test string56 102"

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.