Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Xandrete

#21
¡Vaya, comentarios en catalán! Quina sorpresa més agradable!

A ver, me gustaría comentarte unas cosillas primero. Si estás programando en C++, has de tener en cuenta que has de incluir la librería cstdio, no stdio.h.

Por otro lado, no es necesario incluir la biblioteca iostream ya que no utilizas nada de ella.

¿Qué quieres decir con borrar exactamente? Permíteme copiarte el case 3 del bloque switch:

Código (cpp) [Seleccionar]
                      afegir = afegir -1;
                      printf("Guardando cambios....");
                      fp=fopen("telefons.txt","a");
                      fprintf(fp,"%s %d\n" ,contacte,numero);         
                      printf("\nTots els canvis han sigut guardats");
                      fclose(fp);
                      for (int i=0;i<10;i++){ contacte[i]=0; numero[i]=0; }
                      break;


Lo que haces es:

- Decrementar el indicador de posición afegir.
- Guardar en el documento el nombre del contacto seguido de... un puntero Si pones "numero" a secas, ¡estás imprimiendo un puntero en el documento! De hecho, estás imprimiendo el puntero a la primera posición del array numero.
- Poner todas las posiciones de los arrays contacte y numero a 0. Mi pregunta es: ¿por qué guardas 10 números en un array si sólo vas a coger el último y el resto los borras?

Además, si borras todos los números, ¡deberías darle el valor 0 a afegir!

También es curioso el tratamiento que haces del array de caracteres contacte. A veces lo tratar como una cadena de texto (como en la sección de código anterior) y otras lo tratas como un vector de cadenas de texto, como en el siguiente fragmento:

Código (cpp) [Seleccionar]
                      printf("Introduce el numero : ");
                      scanf("%d", &numero[afegir]);
                     
                      printf("Introduce el nombre del contacto : ");
                      scanf("%s", &contacte[afegir]);
                      afegir++;
                     
                      break;


A no ser que los nombres tengan siempre longitud máxima de un carácter, deberías revisar esto.

¡Saludos!
#22
Aquí tienes un par de sitios más que pueden interesarte

http://acm.timus.ru/
http://www.jutge.org
http://www.spoj.pl
http://cm.baylor.edu/welcome.icpc

Si miras los enlaces externos al final de este artículo de la Wikipedia, encontrarás cosas aún más interesantes.

http://en.wikipedia.org/wiki/ACM_International_Collegiate_Programming_Contest
#23
Ahá. ¿Has oído hablar de los jueces online (tengo la impresión de haberlos mencionado cientos de veces en este foro)? Aquí tienes uno: http://uva.onlinejudge.org/

El funcionamiento es este. Tienes una lista (inmensa) de enunciados de problemas (donde te explican qué programa quieren que hagas y un ejemplo de entrada/salida). Puedes leer los problemas que te interesen, hacer una solución en C++ y subirla. El juez la compilara y le aplicará varios juegos de prueba. Comparará la salida de tu programa con la salida que tiene él y, si son iguales, te da el visto bueno. También tienes el projecteuler.net. Son problemas de matemáticas que puedes resolver mediante un programa (muchos están orientados a este tipo de soluciones). Aquí no subes tu programa, sino directamente la solución al problema que te plantean. Por ejemplo, el primer problema de projecteuler es: haya el número de múltiplos de 3 y 5 menores que 1000. Lo único que tendrías que subir es un valor numérico. Como lo obtengas es cosa tuya (este problema de hecho se puede resolver a mano).

Si te va el rollo de la competición y tal, también tienes topcoder.com. Es en plan juez online pero además ofrece una plataforma para competir contra otros usuarios (también se puede acceder sin competir, para practicar, por ejemplo).

Saludos
#24
Cita de: $Edu$ en 27 Marzo 2012, 14:23 PM
Alguien que sepa C++ y nos venga a retar de que hablamos sin saber y nos explique esto?

No es difícil de entender. La declaración de la función en la que no se especifica el cuerpo de la misma (hablando en plan rudo, la que acaba en punto y coma) se llama prototipo. Se utilizan mucho cuando se quiere separar la implementación de la especificación. Por ejemplo, imagínate que tienes una función foo(). En C/C++ puedes tener la definición de la función en un archivo, junto a una descripción exhaustiva de su comportamiento (precondiciones, postcondiciones, invariantes, análisis de eficiencia, justificación, etc) y en otro fichero puedes tener el código de la función, que puedes ir cambiando para mejorar (o empeorar, según lo que hagas) cosas. La función hace siempre lo mismo, lo que cambia es la manera en que lo hace. Otra utilidad de la declaración de prototipos es cuando tienes dos funciones que se llaman la una a la otra. Por ejemplo:

Código (cpp) [Seleccionar]
int spam(int n) {
return n+foo(n-2);
}

int foo(int n) {
return n+spam(n-1);
}


Si intentaras compilar un programa con estas funciones, obtendrías un error. Cuando  foo llama a spam, este ya está definido. Sin embargo, no sucede lo mismo cuando spam llama a foo (la declaración de la función está más abajo). Esto se soluciona añadiendo el prototipo de la función foo antes de spam:

Código (cpp) [Seleccionar]
int foo(int n);

int spam(int n) {
return n+foo(n-2);
}

int foo(int n) {
return n+spam(n-1);
}


Como ves, en la mayoría de las situaciones, no hace falta declarar los prototipos antes de definir el cuerpo de la función. La única tesitura en que es necesario es en la que te he descrito anteriormente. Por lo demás, puedes hacerlo o no (depende del procedimiento y el estilo que estilo sigas a la hora de programar, y de si documentas o no tus programas).

Saludos
#25
Cita de: nirvguy en 22 Marzo 2012, 19:01 PM
Usa Bison y Lex se hace más rápido.

Por otro lado, si nos apartamos de C/C++, también hay lenguajes de programación como el de Matlab que te permiten hacer un eval sobre una cadena de carácteres y entonces pasan el contenido de esa cadena al intérprete. Diría que con Python tienes algo parecido. Si puedes usar alguno de estos lenguajes, podrías hacer esto en un periquete.

Cita de: durasno en 22 Marzo 2012, 18:08 PM
Hola firius2010! Es verdad como dicen todos el problema q planteas es bastante complicado pero como todo nada es imposible.

¡Claro que no es imposible! De hecho, es lo que hace el intérprete del Python, por ejemplo (que se puede usar como una simple calculadora). Sin embargo, para que el usuario que ha iniciado este post se haga una idea de lo que se puede complicar este programa, le sugiero realizar el siguiente problema, que es una versión mucho más suave de éste que nos plantea: https://www.jutge.org/problems/P45102_en

Saludos

P.S. Ah, y otra cosa que se me olvidó comentar e el anterior post. También sugiero usar títulos más descriptivos para sus temas en el foro. "ayuda porfavor es urgente" está muy manido y no ofrece ninguna información de antemano que motive a leerlo. Además es antiestético ver un puñado de temas con nombres de este estilo.
#26
Cita de: firius2010 en 22 Marzo 2012, 02:25 AM
ok vale
entonces el usuario debera de ingresar alguna funcion que el desee evaluar ej
(x^2+3 x-2)/x^3
e ingresa el valor de x q quiere evaluar entocnes mi programa de be de tabular ese punto es decir si ingreso 1 por ej como valor de x mi progrma debera de hacer
(1^2+3(1)-2)/1^3=2
espero haberme echo entender

¿Cómo dice usted? Si lo he entendido bien, se ha de ingresar nada más y nada menos que una expresión con literales (ocurrencias de x). sustituir el literal por un valor que ingresa el usuario posteriormente y efectuar la operación.

Creo que, o no has entendido bien el problema, o se pasan en tu universidad (sobre todo teniendo en cuenta que haces el 3er semestre de una ingeniería electrónica), o te has expresado con ambigüedad. ¿Te das cuenta de la envergadura de lo que dices?

El programa tendría que ser una especie de intérprete. Debería reconocer varias funciones básicas y variantes(exponenciación, funciones trigonométricas, cociente, logaritmos, composición, multiplicación por constantes, suma de constantes, suma de funciones, producto de funciones...). Además tendrías que decidir qué hace tu programa si el usuario ingresa una expresión con errores de sintaxis si no te garantizan que la entrada va a ser válida siempre. Es decir, poco más o menos te están pidiendo una calculadora científica. Comprueba bien qué es lo que te piden, porque dudo mucho que sea eso. Otra cosa es que te pidan evaluar siempre la misma función, o que simplemente tengas que sustituir las x de la cadena de entrada por el valor numérico ingresado por el usuario, y retornar la cadena con los valores sustituidos (sin efectuar ninguna operación). Estaría bien que pusieras un ejemplo de entrada/salida tal y como dice $EdU$, pero en el siguiente formato:

Entrada

x^2+2x+1
-1

1/(x-1)
0

Salida

0

1

Este ejemplo de entrada/salida correspondería al de una calculadora científica.

Otro ejemplo es:

x^2+2x+1
-1

1/(x-1)
0

Salida

(-1)^2+2(-1)+1

1/((0)-1)

Este ejemplo se correspondería a un programa que únicamente cambiara las x por el número que te da el usuario.

Saludos
#27
Claro, es bastante código. Pero ten en cuenta que es la implementación completa de una lista circular. Cuando usas los vectores o las listas de la STL es verdad que tu programa queda muy bonito y tal, pero detrás está la implementación de esas clases que es mucho más grande y compleja que ésta (que, en comparación, es bastante simplona).

Suerte con el proyecto  ;D

¡Saludos, jefe!
#28
Bien. Aquí la implementación:

Código (cpp) [Seleccionar]
#include <cstdlib>
#include <ctime>
using namespace std;

template <class T>
clist<T>::clist() {
srand(time(NULL));
act = NULL;
s = 0;
}

template <class T>
clist<T>::~clist() {
while (act != NULL) erase();
}

template <class T>
T clist<T>::elem() const {
return act->info;
}

template <class T>
int clist<T>::size() const {
return s;
}

template <class T>
bool clist<T>::empty() const {
return s == 0;
}

template <class T>
clist<T> &clist<T>::operator=(const clist& cl) {
while (act != NULL) erase();
if (cl.act != NULL) {
insert(cl.act->info);
Node* aux = cl.act->next;
while (aux != cl.act) {
insert(aux->info);
aux = aux->next;
}
s = cl.s;
}
return *this;
}

template <class T>
void clist<T>::insert(const T& inf) {
Node* n = new Node;
n->info = inf;
if (act != NULL) {
n->next = act;
n->prev = act->prev;
act->prev->next = n;
act->prev = n;
}
else {
n->next = n;
n->prev = n;
act = n;
}
++s;
}

template <class T>
void clist<T>::erase() {
if (act != NULL) {
if (act == act->next) {
delete act;
act = NULL;
}
else {
act->next->prev = act->prev;
act->prev->next = act->next;
Node* aux = act->prev;
delete act;
act = aux;
}
--s;
}
}

template <class T>
void clist<T>::operator++() {
if (act != NULL) act = act->next;
}

template <class T>
void clist<T>::operator--() {
if (act != NULL) act = act->prev;
}

template <class T>
void clist<T>::rand_sel() {
if (s > 0) {
int r = rand()%s;
while (r--) act = act->next;
}
}


Quiero aclarar que esta clase no la he hecho sólo para esto.

¡Saludos!
#29
¡Hola!

Tu manera de hacerlo es correcta (y eso es lo más importante). Otra manera sería mantener un vector de booleanos en el que marques los elementos que ya has cogido (así no tienes que hacer una búsqueda entre los elementos que ya han salido).

Propongo también esto otro, con listas circulares (y aprovechando que generas elementos entre 0 y 9 únicamente). Me he hecho una clase llamada clist que básicamente es eso, una lista circular. Aquí como resuelvo el problema usando esa clase:

Código (cpp) [Seleccionar]
#include <iostream>
#include "circlist/clist.hpp"

int main() {
clist<int> cl;
for (int i = 0; i < 10; ++i) {
cl.insert(i);
cl.rand_sel();
}
for (int i = 0; i < 10; ++i) {
cout << cl.elem() << endl;
++cl;
}
}


Y aquí el fichero de cabecera de la clase:

Código (cpp) [Seleccionar]

#ifndef NULL
#define NULL 0
#endif

template <class T>
class clist {

private:

struct Node {
T info;
Node* next;
Node* prev;
};
T hola;
Node* act;
int s;

public:

clist();

~clist();

// Returns the element pointed by act
T elem() const;

// Returns the number of elements of the circular list
int size() const;

// Returns true if there isn't any element in the list. False otherwise
bool empty() const;

// Overloaded = operator
clist& operator=(const clist& cl);

// Insert element inf before the element pointed by act
void insert(const T& inf);

// Erases the element pointed by act from the list
void erase();

// Makes act := act->next
void operator++();

// Makes act := act->prev
void operator--();

// Makes act point to a random element of the list
void rand_sel();

};

#include "clist.cpp"


Si alguien quiere la implementación de las funciones (clist.cpp), ya me lo hará saber. No lo pongo aquí para no hacer el post demasiado largo.

De hecho, he utilizado este mismo método para hacer un pequeño buscaminas y decidir en que casillas estarán las minas ^^. Aunque, de todas formas, lo más eficiente en tiempo es lo del vector de booleanos.

Saludos.

PS: por cierto, un detalle. No hace falta que cambies la semilla en cada iteración. No ganas casi nada y pierdes tiempo. Es mejor hacer el srand al principio del programa y ya está.
#30
Programación C/C++ / Re: Contar caracters
11 Marzo 2012, 14:37 PM
Cita de: rir3760 en 11 Marzo 2012, 01:55 AM
Advierto: para variar me voy a pasar de "pesadito" (mas bien [CENSORED]).
No exactamente. Es mas complicado.

Para empezar el tipo "char" es equivalente a "signed char" (lo usual, al menos en PCs de escritorio) o "unsigned char" y, aquí el problema, eso es "implementation defined". Por ello el rango valido del tipo "char" es CHAR_MIN  .. CHAR_MAX (ambas macros cortesía del encabezado <limits.h>).

En el caso del tipo "signed char" y considerando que el mínimo numero de bits que lo componen es ocho su rango mínimo garantizado es -127 .. 127. Ello porque el estándar de C no especifica como serán representados los números negativos. De nuevo lo usual es complemento a dos pero bien puede utilizarse complemento a uno o magnitud con signo y en ese caso se debe considerar al (inútil) cero negativo.
Cuando las macros resultan en expresiones la convención es colocarlas delimitadas por paréntesis, de no hacerlo se pueden presentar casos donde la expresión termina con resultados no deseados, por ejemplo si declaramos un array con el doble de elementos:
int array[NUMOFLETTERS * 2];
Se presenta un error lógico.

Un saludo

No, tampoco [CENSORED]  :D. Es bueno que te corrijan.

Saludos.