2009-06-18 476 views
26

¿Hay un barato forma para concatenar enteros en csharp?Concatenar enteros en C#

Ejemplo: 1039 & 7056 = 10397056

+7

Sólo una nota - muchos de ellos (análisis de cadenas) soluciones pueden tener un OverflowException si la cadena combinada es mayor que el valor entero máximo (o menor que el min). –

+0

¿Por qué me votaron a la baja? – CountCet

+0

Porque no diste ninguna motivación ¿POR QUÉ QUISE concatenar números? –

Respuesta

49

Si se puede encontrar una situación en la que esto es bastante caro para causar ninguna preocupación, voy a estar muy impresionado:

int a = 1039; 
int b = 7056; 

int newNumber = int.Parse(a.ToString() + b.ToString()) 

O, si se quiere que sea un poco más "NET-ish":

int newNumber = Convert.ToInt32(string.Format("{0}{1}", a, b)); 

int.Parse es no una operación costosa. Dedique su tiempo a preocuparse por las E/S de red y las expresiones regulares O^N.

Otras notas: la sobrecarga de crear instancias de StringBuilder significa que no tiene sentido si solo hace algunas concatenaciones. Y muy importante: si es pensando en volver a convertirlo en un número entero, tenga en cuenta que está limitado a ~ 2,000,000,000. Los números de concatenación se hacen muy grandes muy rápidamente, y posiblemente mucho más allá de la capacidad de un int de 32 bits. (firmado por supuesto).

+2

Solo necesita llamar a .ToString() en uno de los enteros. – Brandon

+0

Estoy de acuerdo. Esto debería funcionar. Si el rendimiento es realmente importante en esa parte de tu código, trataría de perfilar diferentes soluciones a este problema. –

+4

@Brandon es técnicamente cierto, pero el compilador realiza la misma conversión de cadena de cualquier manera, por lo que solo guarda unas pocas teclas en el mejor de los casos. –

8
  1. string ConcatInt(int x,int y){return String.Format("{0}{1}",x,y);} 
    
  2. int ConcatInt(int x,int y){ 
        return (x * Math.Pow(10, y.length)) + y; 
    } 
    

Editar Nota: corrige algunos mistypes. Quedan más problemas de tipo. Sólo estoy dando un resumen de la respuesta

El segundo método debería ser en realidad:

static int ConcatInt2(int x, int y) { 
    return (int)(x * Math.Pow(10, y.ToString().Length)) + y; 
} 
+0

# 2 parece que sería más rápido que un análisis de cadenas – tooleb

+0

No estoy seguro de cuánto más rápido es realmente este segundo método, ya que ya está analizando una cadena int de todos modos (solo para obtener su longitud). Creo que para que esto sea realmente más rápido que simplemente concatenar dos cadenas, debe usar el enfoque de "vieja moda" para determinar la longitud de los números. –

3

Si queremos resultado entero a continuación:

int result = int.Parse(input1.ToString() + input2.ToString()); 

Para un resultado cadena de ello:

string result = input1.ToString() + input2.ToString(); 
2

El "Mathy" y "No String" método de la siguiente manera:

int a = 1039; 
    int b = 7056; 

    int bLen = (int)Math.Ceiling(Math.Log10(b)); 
    int ab = (a * ((int)Math.Pow(10, bLen))) + b; 

Tenga en cuenta que aún puede ser lento debido a la llamada Log10.

+1

+1 aunque no estoy 100% convencido de que esto sea más rápido en la práctica que la concatenación de cadenas –

+0

Honestamente, tampoco estoy seguro de que sea así. Pero funciona y probablemente valga la pena intentarlo. –

8

¿barato? La concatenación de cadenas o cadenas formateadas probablemente sea considerablemente más rápida.

lo contrario, puede hacer algo como:

Math.Pow(10,Math.Ceiling(Math.Log10(second)))*first+second 

siempre primero y segundo son números enteros. Esta es la única forma en que lo hará sin involucrar la conversión a una cadena y viceversa, , pero estoy extremadamente dudoso de que sea más rápido.

+0

+1 Buena llamada en el techo. –

+0

Estoy de acuerdo, gran atrapada en el techo, y esta es casi la única cosa que podría creer que es más rápido que analizar valores int para cadenas y concatenarlas. –

6

Si desea concatenar muchos enteros a una cadena

StringBuilder sb = new StringBuilder(1039); 
sb.Append(7056); 
sb.Append(1234); 
sb.Append(1235); 
.... 
sb.Append(9999); 
sb.ToString(); 
1

En realidad, no inpexpensive, pero:

string con = string.Format("{0}{1}",int1,int2); 

o

string con = int1.ToString() + int2.ToString(); 

si se utiliza esta en un bucle , Creo que usaría la Opción 1, que utiliza un StringBuilder internamente.

1
public int ConcatInts(int int1, int int2) 
{ 
    return (int)(int1 * Math.Pow(10, int2.ToString().Length)) + int2; 
} 

Edit: Supongo que no fui el primero con esta solución.

7

No creo que se puede conseguir más simple que esto:

static uint Concat (uint a, uint b) 
{ 
    uint 
    pow = 1; 

    while (pow < b) 
    { 
    pow = ((pow << 2) + pow) << 1; 
    a = ((a << 2) + a) << 1; 
    } 

    return a + b; 
} 

que no tiene asignaciones de memoria, la conversión de series o se multiplica; o tal vez:

static uint Concat (uint a, uint b) 
{ 
    uint 
    pow = 1; 

    while (pow < b) 
    { 
    pow = ((pow << 2) + pow) << 1; 
    } 

    return a * pow + b; 
} 

Si desea concatenar dos números binarios:

static uint Concat (uint a, uint b) 
{ 
    uint 
    mask = uint.MaxValue; 

    while ((mask & b) != 0) 
    { 
    mask <<= 1; 
    a <<= 1; 
    } 

    return a | b; 
} 
+7

¿No se puede obtener _simpler_? Podría creer que este es el enfoque más rápido, y el cambio es inteligente, pero no estoy seguro de que merezca la etiqueta de "simple". ;) –

+0

Además, para un circuito muy ajustado, querrá hacer un perfil (o al menos desmontarlo) para ver si la constante reduce la fuerza de JIT se multiplica por 10 según el patrón de cambio que tiene aquí. Es posible que "pow * = 10" produzca resultados muy similares a "pow = ((pow << 2) + pow) << 1" o incluso que la multiplicación sea más rápida por alguna razón arcana. –

+0

Usando la versión "* 10" en IA32, el compilador/JIT podría usar las instrucciones: lea eax, [eax * 4 + eax]; añadir eax, eax. Sin embargo, es una posibilidad remota. – Skizz

2

¿qué tal esto?

int c = b; 
while(c > 0) { 
    a *= 10; 
    c /= 10; 
} 
a += b; 
10

estoy un poco tarde a la fiesta, pero recientemente he tenido que concatenar números enteros. Con 0 < a, b < 10^9 se puede hacer bastante rápido.

static ulong concat(uint a, uint b) 
{ 
    if (b < 10U) return 10UL * a + b; 
    if (b < 100U) return 100UL * a + b; 
    if (b < 1000U) return 1000UL * a + b; 
    if (b < 10000U) return 10000UL * a + b; 
    if (b < 100000U) return 100000UL * a + b; 
    if (b < 1000000U) return 1000000UL * a + b; 
    if (b < 10000000U) return 10000000UL * a + b; 
    if (b < 100000000U) return 100000000UL * a + b; 
    return 1000000000UL * a + b; 
} 

Editar: la versión más adelante podría ser interesante (plataforma de destino: 64).

static ulong concat(ulong a, uint b) 
{ 
    const uint c0 = 10, c1 = 100, c2 = 1000, c3 = 10000, c4 = 100000, 
     c5 = 1000000, c6 = 10000000, c7 = 100000000, c8 = 1000000000; 
    a *= b < c0 ? c0 : b < c1 ? c1 : b < c2 ? c2 : b < c3 ? c3 : 
     b < c4 ? c4 : b < c5 ? c5 : b < c6 ? c6 : b < c7 ? c7 : c8; 
    return a + b; 
} 
+6

Esta debería ser la respuesta (si se pregunta por una forma económica), he comparado algunas de las respuestas aquí y esta salió en la parte superior con 36ms (frente a 546ms de la respuesta aceptada, y 718ms para la forma .NET-ish) Los probé generando un millón de enteros aleatorios hasta 20000 (sin desbordamientos) y concatené cada uno con el anterior. – user886079

0

// La concatenación de dos números de programa //

 Console.WriteLine("Enter a number for a"); 
     int a = int.Parse(Console.ReadLine()); 

     Console.WriteLine("Enter a number for b"); 
     int b = int.Parse(Console.ReadLine()); 

     int Concatenating = Convert.ToInt32(string.Format("{0}{1}", a, b)); 
     Console.WriteLine(Concatenating); 
     Console.ReadKey();