Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Random_Suffle en C++Builder??? (https://www.clubdelphi.com/foros/showthread.php?t=86666)

aguml 13-09-2014 21:08:19

Random_Suffle en C++Builder???
 
hola amigos, hace tiempo haciendo pruebas con rand y Random para barajar una matriz de enteros alguien me mostro un codigo que usaba una funcion llamada Random_Suffle que simplificaba mucho el trabajo. Juraria que era una funcion de c++builder pero no encuentro informacion ni ejemplos sobre esa funcion de builder. ¿Alguien puede pasarme info al respecto?

ecfisa 13-09-2014 23:42:45

Hola aguml.
Cita:

Empezado por aguml (Mensaje 481395)
... Juraria que era una funcion de c++builder pero no encuentro informacion ni ejemplos sobre esa funcion de builder. ¿Alguien puede pasarme info al respecto?

En realidad random_shuffle es una función de de la librería <algorithm> de C++ y por supuesto, C++ Builder la soporta.

Ejemplo:
Código PHP:

#include <iostream>
#include <algorithm>

using namespace std;

int main(){

  
int v[3][3] = {1,2,3,
                 
4,5,6,
                 
7,8,9};

  
cout << "Matriz original" << endl;
  for(
int f 03f++) {
    for(
int c 03c++)
      
cout << v[f][c] << ",";
    
cout << endl;
  }

  
random_shuffle(&v[0][0], &v[3][3]);

  
cout << endl << "Matriz modificada" << endl;
   for(
int f 03f++) {
    for(
int c 03c++)
      
cout << v[f][c] << ",";
    
cout << endl;
  }

  
cin.get();
  return 
0;


Saludos :)

aguml 14-09-2014 10:16:59

¿y si quisiera barajar una cadena? Por ejemplo "Hola mundo" para que hiciera algo como "lo mHaudon", veo que en tu ejemplo lo hace con enteros y no se especifica el tamaño del dato a barajar (con tamaño me refiero a char, int, double, int64...).

ecfisa 14-09-2014 20:43:37

Hola aguml.
Cita:

Empezado por aguml (Mensaje 481416)
¿y si quisiera barajar una cadena? Por ejemplo "Hola mundo" para que hiciera algo como "lo mHaudon"...

Código PHP:

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int main() {
  
string str;
  
cout << "Ingrese una frase: ";
  
getline(cinstr);

  
random_shuffle(str.begin(), str.end());

  
cout << str << endl;

  
cin.get();
  return 
0;


Saludos :)

aguml 15-09-2014 09:35:39

O_o ¿Entonces la funcion random_suffle detecta el tipo de array? Porque he visto que en este caso le pasas la direccion al primer caracter y del ultimo del string ¿Como puede saber el programa que se trata de barajar chars, ints, dwords, int64 u otros si no lo indicamos en ninguna parte de la funcion? Por ejemplo, si yo creara un array de estructuras y le paso la direccion a la primera y a la ultima ¿Como va a saber el tamaño de la estructura?

ecfisa 15-09-2014 09:59:27

Hola aguml.
Cita:

Empezado por aguml (Mensaje 481478)
O_o ¿Entonces la funcion random_suffle detecta el tipo de array? Porque he visto que en este caso le pasas la direccion al primer caracter y del ultimo del string ¿Como puede saber el programa que se trata de barajar chars, ints, dwords, int64 u otros si no lo indicamos en ninguna parte de la funcion? Por ejemplo, si yo creara un array de estructuras y le paso la direccion a la primera y a la ultima ¿Como va a saber el tamaño de la estructura?

La respuesta a esa pregunta la vas a encontra leyendo sobre Templates.

Un ejemplo típico:
Código PHP:

#include <iostream>
#include <string>

using namespace std;

template <typename Type>
Type max(Type xType y) {
  return (
y) ? x;
}

int main() {
  
int i1=5i2=2;
  
bool b1=trueb2=false;
  
string s1="Ana"s2="Juan";

  
cout << max(i1i2) << endl;
  
cout << boolalpha << max(b1b2) << endl;
  
cout << max(s1s2) << endl;

  
cin.get();


Saludos :)

aguml 15-09-2014 15:51:51

Guauuu eso escapa a mis conocimientos, aun no vi las templates y la verdad es que me pierdo en algo tan simple como lo que pones. Ya cuando lo vea seguro me enteraré mejor. Una cosa ¿que es eso de boolalpha? no lo habia visto jamas.

ecfisa 15-09-2014 21:38:54

Hola aguml
Cita:

Empezado por aguml (Mensaje 481496)
¿que es eso de boolalpha? no lo habia visto jamas.

Es simplemente un especificador de formato. En lugar de mostrar 0 ó 1, muestra false o true.

Saludos :)

aguml 18-09-2014 10:27:49

Cita:

Empezado por ecfisa (Mensaje 481400)
Hola aguml.

En realidad random_shuffle es una función de de la librería <algorithm> de C++ y por supuesto, C++ Builder la soporta.

Ejemplo:
Código PHP:

#include <iostream>
#include <algorithm>

using namespace std;

int main(){

  
int v[3][3] = {1,2,3,
                 
4,5,6,
                 
7,8,9};

  
cout << "Matriz original" << endl;
  for(
int f 03f++) {
    for(
int c 03c++)
      
cout << v[f][c] << ",";
    
cout << endl;
  }

  
random_shuffle(&v[0][0], &v[3][3]);

  
cout << endl << "Matriz modificada" << endl;
   for(
int f 03f++) {
    for(
int c 03c++)
      
cout << v[f][c] << ",";
    
cout << endl;
  }

  
cin.get();
  return 
0;


Saludos :)

amigo he estado probando tus codigos y en este tengo problemas, me corrompe los datos del array y creo que desborda el buffer del array y coge datos que no le pertenecen. ¿lo has probado?

ecfisa 18-09-2014 12:20:28

Hola aguml.
Cita:

Empezado por aguml (Mensaje 481691)
amigo he estado probando tus codigos y en este tengo problemas, me corrompe los datos del array y creo que desborda el buffer del array y coge datos que no le pertenecen. ...

A traves de los mensajes he notado que tu Builder te trae muchos problemas de compabilidad con los códigos publicados, ¿ Has probado de reinstalarlo ?
Cita:

Empezado por aguml (Mensaje 481691)
...¿lo has probado?

Y si, siempre que no sea una trivialidad (una o dos líneas) pruebo el código que publico, así como también lo guardo en una carpeta "ClubDelphi\nombre_usuario" por si alguién llegara a necesitarlo mas tarde. Precisamente lo acabo de buscar y te adjunto los fuentes comprimidos.

Saludos :)

aguml 18-09-2014 19:00:37

A mi tu codigo tal cual me funciona, el problema es cuando intento pasarlo a la vcl. Hice esto:
Código PHP:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
        
int array[3][3]={1,2,3,
                         
4,5,6,
                         
7,8,9};

        
AnsiString aux="";

        for(
int f 03f++) {
                for(
int c 03c++)
                        
aux += AnsiString(array[f][c]) + ",";
                
aux += '\n';
        }

        
ShowMessage(aux);

        
random_shuffle(&array[0][0], &array[3][3]);

        
aux="";

        for(
int f 03f++) {
                for(
int c 03c++)
                        
aux += AnsiString(array[f][c]) + ",";
                
aux += '\n';
        }
        
ShowMessage(aux);


Solo cambio la manera de mostrar el resultado y con eso ya no funciona correctamente.

ecfisa 18-09-2014 20:02:58

Hola aguml.

Pero, no habías comentado que estabas implementando la función en un proyecto con interfaz gráfica ...

Usala de este modo:
Código PHP:

void __fastcall TForm1::FormCreate(TObject *Sender)
{
 
srand (time(0));
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  
int v[3][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
  
String s;

  
Memo1->Lines->Clear();
  
Memo1->Lines->Add("Matriz original");
  for(
int f 03f++) {
    
"";
    for(
int c 03c++)
      
String(v[f][c]) +",";
    
Memo1->Lines->Add(s);
  }
  
Memo1->Lines->Add("");
  
Memo1->Lines->Add("Matriz modificada");

  
random_shuffle(&*v[0], &*v[3]);

  for(
int f 03f++) {
    
"";
    for(
int c 03c++)
      
IntToStr(v[f][c]) +",";
    
Memo1->Lines->Add(s);
  }


Saludos :)

aguml 18-09-2014 23:02:06

ya mañana lo probaré pero de momento hay algo que me ha llamado la atencion. Si la matriz es la misma ¿Por que ha cambiado la forma en que usas random_shuffle? Me refiero a los parametros ¿Porque lo haces de forma diferente siendo la misma matriz?

aguml 21-09-2014 20:51:53

1 Archivos Adjunto(s)
Hola amigo, he probado tu codigo y funciona muy bien pero he intentado complicar la cosa algo mas y para ello he creado dos formularios mas.
Ahora cuando le doy al boton me muestra un form donde me pide el numero de columnas y filas y le indico y doy al boton del nuevo form y me muestra un tercer form desde el que relleno el array.
El problema es que por lo visto random_shuffle se sale del rango y supongo que es por el tema de la gestion de la memoria porque no lo haga bien.
Te mando el proyecto con esa parte comentada todo lo que he podido a ver si puedes ayudarme a descubrir que hago mal. Supongo que muchas cosas pero bueno :o

ecfisa 22-09-2014 06:59:03

Hola aguml.


Te adjunto los fuentes de un ejemplo que creo te va a servir para comprobar el funcionamiento de random_shuffle, muestra:



Como la idea es mostrarte el uso de la función random_shuffle, no compliqué el ejemplo con algunas verificaciones que hubieran sido necesarias pero no hacen a la questión.

Saludos :)

aguml 22-09-2014 08:34:31

no veo el adjunto. Me parece mejor que lo que yo hice ya que no usas otros forms. ¿Viste lo que hice para insertar los valores? ¿Que te parecio? Me costó mucho jejeje.

ecfisa 22-09-2014 09:45:26

Hola aguml.
Cita:

Empezado por aguml (Mensaje 481837)
no veo el adjunto. Me parece mejor que lo que yo hice ya que no usas otros forms. ¿Viste lo que hice para insertar los valores? ¿Que te parecio? Me costó mucho jejeje.

Me parecio que lo había subido, pero indudablemente debo haber cerrado la ventana antes. :o

Si, lo estuve mirando , ví el trabajo de delimitación de las comas y está muy bién. Pero apuntando a que veas el manejo que hago de de random_shuffle me resultó mas simple hacerlo en el mismo form y no tan elaborado.

Saludos :)

aguml 22-09-2014 11:10:19

veo que tu usas strings y no usas memoria dinamica como es mi caso y no veo en que fallo yo.
Con respecto a lo que me indicas por privado, si indico solo el numero de filas me da error en ejecucion y si le pongo el & delante de cada parametro solo baraja las filas, osea, {1,2,3}{4,5,6}{7,8,9} lo que hace es barajar los tres grupos y podemos obtener:
{1,2,3}{4,5,6}{7,8,9}
{1,2,3}{7,8,9}{4,5,6}
{4,5,6}{7,8,9}{1,2,3}
{4,5,6}{1,2,3}{7,8,9}
{7,8,9}{1,2,3}{4,5,6}
{7,8,9}{4,5,6}{1,2,3}

Pero no baraja todos los elementos. Si todo fuese parte de un mismo array si que lo haria, o sea:
{1,2,3,4,5,6,7,8,9}
Ahi si que nos barajaria todo pero en el caso anterior lo que me baraja son los punteros a cada fila.

aguml 22-09-2014 12:07:23

Lo que se me ocurrió fue esto:

Código PHP:

void __fastcall TFormPrincipal::ButtonBarajarMatrizClick(TObject *Sender)
{
        
//En este form pedimos el numero de columnas y filas
        
FormDimension->ShowModal();

        
//Obtenemos memoria para nuestro array
        
= new int*[filas];
        for(
int i 0filas; ++i)
                
v[i] = new int[columnas];

        
//En este form rellenamos el array
        
FormRellenado->ShowModal();

        
String s;

        
Memo1->Lines->Clear();
        
Memo1->Lines->Add("Matriz original");

        
//Mostramos el array original
        
for(int f 0filasf++) {
                
"";
                for(
int c 0columnasc++)
                        
String(v[f][c]) +",";
                
Memo1->Lines->Add(s);
        }
        
Memo1->Lines->Add("");
        
Memo1->Lines->Add("Matriz modificada");

        
//Obtengo memoria auxiliar para meter todo el array bidimensional en uno unidimensional
        
int *array_aux = new int[filas columnas];

        
//Relleno el array auxiliar con los datos del array bidimensional
        
int pos 0;
        for(
int f 0filasf++) {
                for(
int c 0columnasc++)
                {
                        
array_aux[pos] = v[f][c];
                        
pos++;
                }
        }

        
//Barajamos los valores del array
        
random_shuffle(&array_aux[0], &array_aux[filas columnas]);

        
//Actualizo el contenido del array bidimensional ya barajado
        
pos 0;
        for(
int f 0filasf++) {
                for(
int c 0columnasc++)
                {
                        
v[f][c] = array_aux[pos];
                        
pos++;
                }
        }

        
//Libero la memoria del array auxiliar
        
delete [] array_aux;

        
//Mostramos el array barajado
        
for(int f 0filasf++) {
                
"";
                for(
int c 0columnasc++)
                        
IntToStr(v[f][c]) +",";
                
Memo1->Lines->Add(s);
        }

        
//Liberamos la memoria del array
        
for(int i 0filas; ++i) {
                
delete [] v[i];
        }
        
delete [] v;


Pero lo ideal sería conseguirlo sin usar un array auxiliar aunque esto funciona correctamente. ¿se te ocurre algo?

aguml 22-09-2014 17:11:11

Si te fijas, en tu codigo que me mandaste lo que haces es barajar las filas pero no el contenido.
Segun he averiguado, usando la memoria dinámica no se consigue que quede la memoria consecutivamente como ocurriría cuando creo el array de forma estática. Ya lo pude ver en un depurador y me lo han confirmado. De ahí viene el problema con random_shuffle asi que la unica solucion que veo es crear un array unidimensional del tamaño filas*columnas y pasar el contenido a este, luego barajar, y por último volcar el resultado al array multidimensional.


La franja horaria es GMT +2. Ahora son las 21:35:15.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi