|
31
|
Programación / Programación C/C++ / Re: Orden de letras de manera alfabetica en C
|
en: 9 Octubre 2019, 11:20 am
|
Intente realizar como el mencionado pero no pude me puedes orientar un poco mas porfavor
Copia el programa, estúdialo y dale curso en tu computador... Te sale ? Que parte te confunde? Sobre todo, distingue lo esencial (el algoritmo) de lo accesorio (la entrada/salida de datos).
|
|
|
32
|
Programación / Programación C/C++ / Re: Orden de letras de manera alfabetica en C
|
en: 8 Octubre 2019, 18:41 pm
|
si son char, en el scanf no capturas con %d capturas con %c
te recomiendo buscar el algoritmo de ordenamiento de burbuja, es el mas simple de los algoritmos de organizacion
A ver, según entiendo yo, si dice "según se lee la letra se acomoda", no se trata de ordenar, sino de insertar en un vector ordenado una letra. Pero el mayor problema, veo yo, tiene que ver con el hecho de capturar caracteres de la entrada estandard. Eso es otro problema, porque la entrada buferada exige que le des al intro, y a la vez el intro es un caracter (que a t'i no te vale para tu proposito). Propuesta: /* P : N>0 and sorted(A,0,N-1) and V=A Q : perm(V,A) and sorted(V,0,N) I : perm(V,A) and sorted(V,0,n) and sorted(V,n, N) and (0<n<N-1 - > V[n-1]<V[n+1]) and 0 <= n <= N-1 !B : n==0 || V[n]>=V[n-1] B : n > 0 && V[n]<V[n-1] |- I and !B -> Q Quote: C(n) = n >= 0 |- I -> C(n) >= 0 Invariant snapshot: ------------------- 0 n N +-----+-----+-----+-----+-----+ | 0 | 1 | 3 | 2 | 4 | +-----+-----+-----+-----+-----+ Init: ----- n = N- 1 |- P -> I[n/N-1] Step: ---- n= n- 1 |- I and B and n=T -> (n<T)[n/n-1] Restore: -------- V[n],V[n-1]=V[n-1],V[n] Pseudocode: ----------- n=N-1 while n>0 and V[n]<V[n-1] do V[n],V[n-1]=V[n-1],V[n] n=n-1 done */ void *insertChar(char V[], int N) { for(int n=N-1 ; (n && V[n]<V[n-1]);n--) { const int An=V[n]; /* To do swapping */ V[n]=V[n-1]; V[n-1]=An; } return V; } #include <stdio.h> #include <string.h> #define MAX 100000 int main(int argc, char* args[]) { int N; char V[MAX]; for(N =0 ; (scanf("%c",&c )==1) && c !='\n' ; ) { V[N++]=c; } return 0; }
Ejemplp: gcc char.cc -o char && ./char enunlugardelamancha 1 e e 2 n en 3 u enu 4 n ennu 5 l elnnu 6 u elnnuu 7 g eglnnuu 8 a aeglnnuu 9 r aeglnnruu 10 d adeglnnruu 11 e adeeglnnruu 12 l adeegllnnruu 13 a aadeegllnnruu 14 m aadeegllmnnruu 15 a aaadeegllmnnruu 16 n aaadeegllmnnnruu 17 c aaacdeegllmnnnruu 18 h aaacdeeghllmnnnruu 19 a aaaacdeeghllmnnnruu
|
|
|
33
|
Programación / Programación C/C++ / Re: estructuras de datos
|
en: 8 Octubre 2019, 09:34 am
|
Pero es que nadie va a responder a nuestra programadora argentina? hoal quiero apsar este algoritmos a recursivo e ayudan? solo tengo esto int vertir-un-numero(int n) { tpila pila; init_stack(pila); while(n>0){ push_stack(pila,n%10); n/=10; } for(int i=0;empty_stack(pila)==false;i++) n+=pop_stack(pila)*pow(10.0,i); return n; }
Antes de dar la solución, aprecio un fallo de eficiencia... No es necesario en el segundo bucle expresar pow(10.0,i)... puedes poner for(int i=0,power=1;empty_stack(pila)==false;i++) { n+=pop_stack(pila)*power; power *=10 ; }
Y te ahorras la función pow que trabaja con floats, algo que es "peligroso" en computación. Lo normal es que te den el iterativo y tengas que hacer el recursivo. Si la función recursiva es lineal (con una sola llmada) entonces hay truco fácil. (Un poco largo para explicar aquí) Lo que yo hago en estas lineas es dar el programa al que se aplica el truco. Es una función lineal no final, es decir, después de la llamada hay quqe hacer algo más, que en la veris'on iterativa realiza el segundo bucle... Allá va: int invertir_un_numeroG(const int N,int &power); /* P : A[0..log(N)) and N = \sum i : 0 <= i < log(N) : A[i]*10^i Q : M = \sum i : 0 <= i < log(N) : A[i]*10^(log(N)-i) */ int invertir_un_numero(const int N) { int power; return invertir_un_numeroG(N,power); } /* P' : P Q' : Q and power=10^log(N) */ int invertir_un_numeroG(const int N,int &power) { if (N==0) { power = 1 ; return 0 ; } int result; result = invertir_un_numeroG(N/10,power); result += N%10 * power ; power *= 10; return result; } #include <iostream> using namespace std; int main(int argc, char* args[]) { int N; for( ; cin >> N ; ) cout << invertir_un_numero(N) << endl; return 0; }
Y algunos casos de prueba bash-2.04$ ./main 45 54 4678 8764 12345678 87654321
|
|
|
34
|
Programación / Programación C/C++ / Re: Comunicacion entre hilos. Consumidor-Productor
|
en: 4 Octubre 2019, 17:53 pm
|
Sí, siempre se debe usar un while...[...]
La respuesta de RayR es muy acertada. Como norma general, hay que poner while. Sólo analizando un caso particular puedes poner if con seguridad, pero tampoco se gana tanto en eficiencia... Si te lia tu "intuición operacional", (ya que, si es difícil la programación secuencial, la concurrente es inabordable por la explosión de estados) de te recomiendo el siguiente esquema en pseudo lenguaje (one thread) <await B(var) -> S>
(other thread) <var = e>
Se traduce en C a lo que refleja el código : (one thread) pthread_Mutex_lock(l) while !b do pthread_cond_wait(l, c) ; S pthread_Mutex_unlock(l)
(other thread) pthread_Mutex_lock(l) var=e pthread_cond_signal(c) pthread_Mutex_unlock(l) Por último, antes de manejar variables de condición en C, estudia teoría de monitores en papel y pseudo código! Las variables de condición y mutex asociados no se pueden comprender sin ellos. Fueron creados para implementar esa idea, aunque el lenguaje C no los implementa directamente. java, por ejemplo, si, pero se una forma muy limitada). la gente las utiliza sin saber su razón de ser (Perdón por la imprecision, pero estoy escribiendo dese un móvil)
|
|
|
35
|
Programación / Programación C/C++ / Re: Problema k-paired (k-emparejados) en O(N)
|
en: 25 Septiembre 2019, 17:13 pm
|
Asi sólo con datos de tiempos, y no en una gráfica es dificil de ver.... Haz una ultima prueba, con distros aleatorias y k = 1. Si interpolaramos en una gráfica las mediciones, deberíamos ver que las medidas de cada una se acercan a 3 rectas... (por eso es linear. Desde la teoría de la complejidad, da igual que una vaya el doble, el triple, o k-veces más rápido, los factores constantes dan igual...) Pero si se interpolan las curvas y vemos que alguna da una parabola, algo no va bien, pues en los tres casos, n_paired, k_paired, y zoz?paired son lineales... Si, en el doble bucle interior tambien se comporta lineal, ya que al ser la instrucción critica se ejecuta un máximo de N veces... La que no debería ser una recta es la del lower_bound... Un buen trabajo ! Enhorabuena Los elementos del vector sí están ordenados (y no se repiten), sólo que son generados al azar. Pongo el algoritmo acá abajo:
Se invoca con el vector ya del tamaño apropiado; se carga con valores al azar, se ordena y se eliminan los duplicados:
|
|
|
36
|
Programación / Programación C/C++ / Re: Problema k-paired (k-emparejados) en O(N)
|
en: 24 Septiembre 2019, 10:45 am
|
Sí sí, es que quería mantener una atmósfera de misterio... Y ejecutando la misma prueba para cada una de las tres funciones, en Visual Studio, ha resultado:
Curioso, al menos a mí me lo parece. Jé, nuevo desafío... ¿quién me lo explica?
Un momento, amigo... Elementos al azar (uniform distribution) desde 1 hasta 2147483647 Las pruebas quedan invalidadas... Si pones elementos al azar, entonces ya no estarán ordenados estrictamente creciente, y los algoritmos no funcionarán en absoluto... Es conforme a esa precondición que programamamos el algoritmo... De nada sirve ir muy rápido si no computa las cosas que se espera. Si los elementos están al azar, no ordenados, entonces, el algoritmo solo puede ser O(N^2). Por supuesto, este no vale, hay que cambiarlo.
|
|
|
37
|
Programación / Programación C/C++ / Re: Problema k-paired (k-emparejados) en O(N)
|
en: 20 Septiembre 2019, 10:14 am
|
Tu mensaje esta lleno de cosas interesantes.... ... Si te fijas en esta línea: it = std::lower_bound(it, j, s); it queda posicionado en la posición buscada o en una más allá del límite s, esperando en el mejor lugar para la próxima iteración. Y lower_bound es un binary search, logarítmico, que es mejor que avanzar secuencialmente, o mejor dicho, creí que debería serlo. La clave está en que estamos juzgando el caso peor, y tu distribución std::iota (junto con el valor k) puede entrar en ese caso. Como tu dices, binSearch es logaritmico, pero fijate, debido a la distrbución std::iota (junto con el valor k) trabajas mucho para avanzar solamente 1 posición, cosa que se consigue en el mío en O(1) m=m+1. Imaginate k=2 1 5 6........................................................... 1000000000 (Arbitrariamente grande,N)
trabajas mucho (del orden de O(log(N)) para pasar del 1 al 5, del 5 al 6 Yo también probé con una solución (aparentemente) muy inferior a la versión con lower_bound, donde lo reemplazo por un estúpido find, haciendo ahora sí una solución (prácticamente) O(N2), pero no, curiosamente: size_t n_pares(const std::vector<int>& v, int k) { assert(std::is_sorted(v.begin(), v.end()) && "v debe estar ordenado."); assert(v.size() && "v no puede venir vacio."); auto n{ 0u }; auto it = v.begin(); for (auto i = v.begin(), j = v.end(); i != j; ++i) { it = std::find(it, j, *i + k); if (it != j) { ++n; ++it; } else { it = i + 1; } } return n; }
Ahora los resultados son hasta ligeramente mejores que los de los de k_paired. Joder. UN mundo muy ingrato. Je,je,je... Tiene toda la explicacion... En este caso, la naturaleza de iota, k, y el problema, constituyen el caso mejor para find... No tienen que moverse casi nada, estan preguntando por el elmeento siguiente y los datos de entrada están al principio, no da "saltos" como el binsearch. con k=4 1 5 6........................................................... 1000000000 (Arbitrariamente grande,N)
Del 1 al 5, la busqueda se detiene en el primero. Idem para 5 a 6... A nadie engañamos diciendo que es en O(N^2) en el caso peor... Pero este, era el mejor caso posible...
|
|
|
38
|
Programación / Programación C/C++ / Re: Problema k-paired (k-emparejados) en O(N)
|
en: 19 Septiembre 2019, 09:12 am
|
Estupendo intento, Loretz, buena exhibición de recursos... No obstante creo que el punto flaco reside en la llamada que haces a lower_bound, lo que eleva la complejidad de tu algoritmo a O(Nlog(N)). Mejor que cuadrático O(N^2), al menos... ... for (auto i = v.begin(), j = v.end(); i != j && it != j; ++i) { auto s = *i + k; it = std::lower_bound(it, j, s);
if (it != j && *it == s) { ++n; ++it; } } ...
A ver que te parece ésta, en O(N): Brevemente, para evitar llamadas a lower_bound, controlas con una variable extra m, que parte del vector recorrido YA sabes que no va a emparejar con el actual en curso V[n], por lo que no hace falta volver a recorrer... Ah!, y lo mismo vale para vectores vacíos /* P : strict(V) fun k_paired(V[0..N) of int, int k) dev r Q : r =#i,j : 0 <= i , j<N : V[j]-V[i]=k I : Q[N/n] and 0 <= m <= n <= N and n<N -> \forall i : 0<=i < m : V[n]-V[i] > k ** ** m for efficiency reasons, discarding subtrahends V[i] far from V[n]. !B : n==N B: n<N C(N,n,m)= 2N - (m+n) >= 0 Invariant snapshot: ------------------- k = 20 , r = 0 0 m n N +-----+-----+-----+-----+-...-+-----+-----+-----+-----+-...-+ | 1 | 3 | 5 | 40 | | | 49 | 50 | 60 | | +-----+-----+-----+-----+-...-+-----+-----+-----+-----+-...-+ */ #include <iostream> using namespace std; int k_paired(const int V[], const int N, const int k) { int n,m,r; for(n=m=r=0;n<N;) if (V[n]-V[m] <= k) r+=(V[n++]-V[m] == k); else m++; return r; } #define MAX 100000 int main(int argc, char **args) { int N,k; int V[MAX]; for(cin >> N ; N!=-1 ; cin>>N) { cin >> k; for(int n=0;n<N;n++) cin >> V[n]; cout << k_paired(V,N,k) << endl; } return 0; }
A ver si pudieras medir tiempos con tus clases C++...
|
|
|
40
|
Programación / Programación C/C++ / Problema k-paired (k-emparejados) en O(N)
|
en: 17 Septiembre 2019, 14:44 pm
|
Dado un vector de enteros V[0..N) , con todos sus componentes siguiendo un orden stricto creciente, (1,5,17,20) y un numero k >=0 , diseñar un algoritmo de complejidad lineal que resuelva el número de pares de componentes <i,j> , con 0<=i,j<N, tales que Vi-Vj=k. En la siguientee lineas se da unos ejemplos como ilustracion 5 3 (Numero de componentes del vector y k) 1 4 5 6 8 (Componentes del vector) 2 (Resultado)
4 2 (Numero de componentes del vector y k) 1 4 5 6 (Componentes del vector) 1 (Resultado)
3 0 (Numero de componentes del vector y k) 1 2 3 (Componentes del vector) 3 Resultado)
Yo dispongo de la solución. La pongo en dos días. Pero ahí esta el reto. Cuanto más simple mejor!
|
|
|
|
|
|
|