tienda - programa para calcular descuento c++
¿Cómo calcular la longitud de una cuerda en C de manera eficiente? (14)
Algunas de las respuestas anteriores son muy buenas, y esta es mi opinión. Hay una palabra clave conocida como "registro"
#include <stdio.h>
size_t strlenNew(char *s);
int main(int argc, char* argv[])
{
printf("Size of /"Hello World/" is ::/t%d",strlenNew("Hello World"));
return 0;
}
size_t strlenNew(char *s)
{
register int i=0;
while(s[i]!=''/0'') i++;
return i;
}
Lea aquí: http://gustedt.wordpress.com/2010/08/17/a-common-misconsception-the-register-keyword/ y http://msdn.microsoft.com/en-us/library/482s4fy9(v=vs.80).aspx
Desde el primer enlace:
Esto puede ser particularmente útil para las variables de matriz. Una variable de matriz se confunde fácilmente con una variable de puntero. A menos que sea seguido por un [expr] o con un tamaño de, se evalúa la dirección del primer elemento. Si declara el registro de matriz todos estos usos están prohibidos; Solo accedemos a elementos individuales o solicitamos el tamaño total. Una matriz de registro de este tipo puede entonces ser mucho más fácil de usar como si solo fuera un conjunto de variables por parte del optimizador. No se pueden producir alias (accediendo a la misma variable a través de diferentes punteros).
Por lo tanto, a veces, puede haber fluctuaciones de rendimiento. Personalmente, esta es una de mis implementaciones favoritas, pero Sudhanshu y Andomar también proporcionan una buena implementación :)
¿Cómo calcular la longitud de una cadena en C de manera eficiente (en el tiempo)?
Ahora mismo estoy haciendo:
int calculate_length(char *string) {
int length = 0;
while (string[length] != ''/0'') {
length++;
}
return length;
}
Pero es muy lento en comparación con strlen (), por ejemplo, ¿hay alguna otra forma de hacerlo?
Gracias.
EDITAR: Estoy trabajando en un entorno independiente, no puedo usar ninguna biblioteca externa, incluido "string.h".
Desde el código fuente de FreeBSD :
size_t
strlen(const char *str)
{
const char *s;
for (s = str; *s; ++s);
return(s - str);
}
En comparación con su código, esto probablemente se asigna muy bien a una instrucción de ensamblador, lo que puede explicar una gran diferencia de rendimiento.
Eche un vistazo a la fuente strlen()
la biblioteca GNU C.
Utiliza una serie de trucos no obvios para ganar velocidad sin caer al ensamblaje, incluyendo:
- llegar a un personaje que está correctamente alineado
- leyendo esas partes alineadas de la cadena en un int (o algún tipo de datos más grande) para leer varios caracteres a la vez
- usar trucos de bits para comprobar si uno de los caracteres incrustados en ese bloque de caracteres es cero
etc.
Eche un vistazo al código fuente de strlen en el libc estándar. Las funciones en las bibliotecas estándar son generalmente altamente optimizadas. Verifíquelo here (codificado en ensamblaje) - esto es de la biblioteca de GNU.
size_t
DEFUN(strlen, (str), CONST char *str)
{
int cnt;
asm("cld/n" /* Search forward. */
/* Some old versions of gas need `repne'' instead of `repnz''. */
"repnz/n" /* Look for a zero byte. */
"scasb" /* %0, %1, %3 */ :
"=c" (cnt) : "D" (str), "0" (-1), "a" (0));
return -2 - cnt;
}
En los procesadores i386, libc utiliza a menudo una versión ultra-optimizada de strlen
, a menudo escrita en lenguaje ensamblador. El documento " String Length " explica cómo funcionan.
Aquí hay una versión optimizada para OpenBSD . (También tienen una versión portátil ). Aquí está la versión para el libc de GNU .
La forma más fácil es llamar a strlen()
. Seriamente. Ya está optimizado por los proveedores de su compilador y / o biblioteca, para que sea lo más rápido posible para su arquitectura.
Una optimización común es eliminar la necesidad de aumentar un contador y calcular la longitud desde el puntero:
size_t my_strlen(const char *s)
{
const char *anchor = s;
while(*s)
s++;
return s - anchor;
}
Las cadenas C son intrínsecamente ineficientes , hay dos razones para usar la convención ASCIZ:
- La biblioteca estándar de C lo usa
- El compilador lo usa para constantes de cadena literal.
El primero de ellos es académico en este caso, ya que no está utilizando la biblioteca estándar, el segundo se supera fácilmente mediante la creación de funciones o macros que proporcionan conversiones de cadenas C a una convención más eficiente, como las cadenas Pascal. El punto es que no necesita ser un esclavo de la convención de C si no está utilizando la biblioteca de C.
No encontré mejor:
inline size_t mystrlen (char * _)
{ return ((_ == NULL) ? (_[0] != ''/0'')) ? 0 : (1 + mystrlen(_ + 1)); }
No estoy muy seguro de lo que quieres hacer.
Desea volver a escribir strlen
para que su código sea compatible con la biblioteca estándar de c, o para administrar cadenas.
En el primer caso, creo que es mejor usar directamente las bibliotecas estándar.
El otro caso es interesante: debe echar un vistazo a la clase de cadena c ++, que tiene una implementación de la estrategia de rasgos (que permite manipulaciones rápidas de cadenas muy grandes).
Otra forma de acelerar el recuento de caracteres es utilizar la vectorización.
Aquí hay un ejemplo de cómo hacer esto con respecto a las cadenas codificadas en UTF8:
Recuento de caracteres UTF-8 aún más rápido,
http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html
Tuve el mismo problema, y lo resolví. La clave es la segunda condición del bucle for:
int longitud(char cad[]){
int i, cont;
cont = 0;
for(i = 0; i < 30 && cad[i] != ''/0''; i++){
if(cad[i] != ''/0''){
if(cad[i] != '' ''){
cont++;
}
}
}
cont--;
return cont;
}
strlen()
. Lo más probable es que, si alguien hubiera encontrado un método genérico mejor y más rápido, strlen hubiera sido reemplazado por eso.
Programa básico de C para calcular la longitud de la cadena.
#include <stdio.h>
/**
* Method to calculate string length.
* Returns -1 in case of null pointer, else return string length.
**/
int length(char *str) {
int i = -1;
// Check for NULL pointer, then return i = -1;
if(str == NULL) return i;
// Iterate till the empty character.
while (str[++i] != ''/0'');
return i; // Return string length.
}
int main (int argc, char **argv) {
int len = 0;
char abc[] = "hello";
len = length(abc);
printf("%d", len);
return 0;
}
NOTA: Para una mejor manera, siempre debemos pasar el tamaño del arreglo para que funcione para evitar el caso de pérdida de memoria. Por ejemplo, el ** prototipo de método debería ser *: *
/**
* @desc calculate the length of str.
* @param1 *str pointer to base address of char array.
* @param2 size = capacity of str to hold characters.
* @return int -1 in case of NULL, else return string length.
**/
int length (char *str, int size);
int max;
max = sizeof(str);
return (--max);