在C#中实现“追加”整数的好方法是什么?

7

我有两个整数,例如15和6,我想得到156。

我的做法:

int i = 15;
int j = 6;
Convert.ToInt32(i.ToString() + j.ToString());

有更好的方法吗?

更新: 感谢所有美好的回答。我进行了一个快速的秒表测试,以查看性能影响: 这是在我的机器上测试的代码:

static void Main()
    {
        const int LOOP = 10000000;
        int a = 16;
        int b = 5;
        int result = 0;
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < LOOP; i++)
        {
            result = AppendIntegers3(a, b);
        }
        sw.Stop();
        Console.WriteLine("{0}ms, LastResult({1})", sw.ElapsedMilliseconds,result);
    }

以下是时间安排:

My original attempt: ~3700ms 
Guffa 1st answer: ~105ms 
Guffa 2nd answer: ~110ms 
Pent Ploompuu answer: ~990ms 
shenhengbin answer: ~3830ms 
dasblinkenlight answer: ~3800ms
Chris Gessler answer: ~105ms

Guffa提供了一个非常好的、聪明的解决方案,而Chris Gessler则为该解决方案提供了一个非常好的扩展方法。


如果那种方式已经能够工作并且速度很快,为什么还需要更好的方式呢? - matthewr
不需要使用 toString(),因为可以直接连接字符串。 - Shyju
2
@Shyju,如果我不添加.ToString(),那么我的结果是21而不是156。 - user194076
7
伙计们,谁在投反对票?虽然他的愿望有些奇怪,但这是个合理的问题。他提出了一种解决方案,并想知道是否存在更好的方案。不要因为这个而投反对票。请理性看待。 - Kyeotic
1
@user194076:是的,您可以进行移位操作,但由于您需要十进制数,因此您需要通过乘以10来进行移位。 - Guffa
显示剩余2条评论
5个回答

16

你可以通过数值计算来实现。不需要进行字符串转换:

int i=15;
int j=6;

int c = 1;
while (c <= j) {
  i *= 10;
  c *= 10;
}
int result = i + j;

或:

int c = 1;
while (c <= j) c *= 10;
int result = i * c + j;

1
除非有特殊原因需要更快的速度,否则我会只使用字符串连接的变体..但是对于不同的方法加1。 - user166390
+1 我想知道它是否比 @dasblinkenlight 的 string 方法更快?有人愿意发布测试结果吗?为了好玩儿... - Alex
3
@Xander 这段代码避免了在 .NET 基础类库中执行转换所需的大量数学计算(和额外的开销和中间字符串);我预计它能够在微基准测试中取得胜利。当然,微基准只是微基准.. 我只会在一个合适命名的函数(或特定基准测试性能情况下)之后接受这段代码。 - user166390
此外,需要注意的是,这段代码可能会悄悄地溢出。可能重要,也可能不重要。 - user166390
1
@pst:好点子。你可以使用第二个版本并检查 i > Int32.MaxValue/c 来捕获溢出。 - Guffa
我已经添加了一些性能测试,如果有人感兴趣的话。还要感谢guffa给出的很棒的答案! - user194076

3

这是一个扩展方法:

public static class Extensions
{
    public static int Append(this int n, int i)
    {
        int c = 1;
        while (c <= i) c *= 10;
        return n * c + i; 
    }
}

并且要使用它:

    int x = 123;
    int y = x.Append(4).Append(5).Append(6).Append(789);
    Console.WriteLine(y);

如果您使用更多基于数字的方法,那么使用(int)Math.Log10(i) + 1而不是i.ToString().Length(如Pent Ploompuu的答案中所示)会更快(也更纯)。 - Simon MᶜKenzie
哇,当我看到将乘以十编码为 ((p << 2) + p) << 1 时,我可以告诉作者在汇编语言编程方面有相当丰富的经验 :) 大约二十年前,我停止使用这个技巧,因为我看到了一个针对8位CPU进行优化的C编译器将常数乘法编译成一系列移位和加法。 - Sergey Kalinichenko
我尝试使用移位和加法代替乘法进行测试。在64位模式下,性能没有差异。但在32位模式下,实际上比乘法更慢... - Guffa
@Guffa - 感谢您的性能审查,但我解决方案的重点是将任何解决方案转换为扩展以实现方法链接。我再次更新了我的答案,但实际上,在这里几个纳秒不会有太大的区别。如果我需要添加100亿个整数,那就是另一回事了。 - Chris Gessler
@ChrisGessler:我之所以指出这一点,是因为显然这段代码是为了尝试更快地运行而编写的。 :) - Guffa

2
int res = j == 0 ? i : i * (int)Math.Pow(10, (int)Math.Log10(j) + 1) + j;

0

我想使用 string.Concat(i,j)


-2
int i=15
int j=6
int result=i*10+6;

3
此答案假设变量j小于10。 - Andrew Barber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接