C sharp - Problema de lógica en una Ordenación simple

   
Vista:

Problema de lógica en una Ordenación simple

Publicado por Manuel F. manuelf.borrego@gmail.com (17 intervenciones) el 29/07/2016 20:19:47
Muy Buenas Tardes a Todos !!!

Tengo un pequeño problema de lógica para ordenar unos datos (que están desordenados, por supuesto) dentro de un array...

{ 29, 8, 43, 4, 29, 83, 55, 62, 81, 5, 8, 77, 34, 29, 81, 18, 29, 8 } (originalmente)...

{ 4, 5, 8, 8, 8, 18, 29, 29, 29, 29, 34, 43, 55, 62, 77, 81, 81, 83 } (ordenados).

Esto lo logro mediante el usos del "método de la burbuja":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
int[] datos = { 29, 8, 43, 4, 29, 83, 55, 62, 81, 5, 8, 77, 34, 29, 81, 18, 29, 8 };
int datoTemporal;
int n = datos.Length;     // Número de datos.
int[] datosSinOrdenar = datos;
 
Console.Clear();
                        //
Console.WriteLine("");
Console.WriteLine("");
 
Console.WriteLine("     Datos sin ordenar...");
for (int srd = 0; srd < n; srd++)
{
       Console.Write("{0} ", datosSinOrdenar[srd]);     // Se muestran los datos en su orden original...
}
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("     Ordenando mediante el método de la burbuja...");
 
for (int i = 0; i < n - 1; i++)
{
       for (int j = i + 1; j < n; j++)
       {
               /*foreach (int dato in datos)
                          Console.Write("{0} ", dato);     // Se muestran los datos. mientras se van ordenando...
                 Console.WriteLine();*/
 
               if (datos[i] > datos[j])
               {
                       datoTemporal = datos[i];
                       datos[i] = datos[j];
                       datos[j] = datoTemporal;
               }
       }
}
 
Console.WriteLine();
Console.Write("     Ordenado: ");
 
foreach (int dato in datos)     // Se Muestran los datos ordenados de forma correcta...
       Console.Write("{0} ", dato);
 
Console.ReadKey();

Hasta ahí, todo bien...
Ahora lo que quiero es lograr separar los datos que no se repiten:
{ 4, 5, 18, 34, 43, 55, 62, 77, 83 }
y los que se repiten:
{ 8, 8, 8, 29, 29, 29, 29, 81, 81 } así: { 8, 29, 91}...

O sea, en 2 arreglos distintos, por supuesto conservando la información de los datos de se repiten, cuantas veces, etc.
Es para calcular la frecuencia absoluta, relativa, acumulada y relativa acumulada con fines estadísticos.
Estoy diseñando una calculadora, y entre otras funciones que le estoy agregando es el de algunos calculos de ese tipo.

Pido la ayuda de uds, porque he intentado de todo he "volteado" el método que utilicé, he probado de varias formas y no he logrado nada salvo "desastres" en los resultados !!!

Agradezco cualquier ayuda !!!


Manuel F. Borrego S.
Barcelona, Edo. Anzoátegui. Venezuela.
[Mientras nos permitan seguir comunicándonos...!!!]
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Problema de lógica en una Ordenación simple

Publicado por Flash (21 intervenciones) el 31/07/2016 14:19:46
Porque no haces dos arreglos y luego pones que el primer arreglo lo compare con la lista del segundo arreglo y que vaya cambiando de numero cuando llegue al limite?
ejemplo

[9][9]
if( [1]=[5])
null
Si es distinto que se mueva a un arreglo y se vaya actualizando
y cosas asi, ahora mismo no sabria ponertelo pero creo que se entiende

Aunque quizas lo entiendo mal
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de Aarón Castillo

Problema de lógica en una Ordenación simple

Publicado por Aarón Castillo acuarium_329@hotmail.com (3 intervenciones) el 31/07/2016 20:33:37
Primero que nada, te recomiendo ampliamente que construyas las estructuras de los números repetidos y no repetidos y posteriormente ordenes cada uno, ¿la razón? el algoritmo te saldrá mucho más fácil que si lo haces al revés.

Dado que ya hiciste un gran avance, te propongo esta solución.
Te recomiendo que uses una tabla hash (o no sé cuál sea su equivalente en C#, en Java al menos es una tabla hash). La tabla hash consiste en una estructura donde cada elemento es una asociación llave - valor, donde la llave debe ser irrepetible y el valor puede ser lo que sea, en este caso el valor será entero (el número de veces que aparece el número), la llave será el número.

Entonces, tienes tu arreglo de números original, sin ordenar ni nada.

1.- Recorre el arreglo y ve agregando los números al hash table, (hay métodos para averiguar si un elemento está en el hashtable).
Si el número ya está en el hash table, significa que había al menos un número repetido, entonces el valor asociado a la llave se incrementa en uno, si no existe el número en el hash table entonces el valor asociado a la llave será 1.

2.- Ya tienes tu hash table con los números y sus frecuencias (el número de veces que se repiten).
Ahora tomas todos los números del hash table y preguntas por su valor asociado, si es 1 significa que es un elemento que no tiene repetición y lo pones en la estructura pertinente, lo mismo para elementos cuyo valor asociado sea mayor a 1.

3.- Ahora sí ya tienes separados cada uno de los arreglos con elementos irrepetibles y repetibles. Simplemente ordena cada uno.

Ahora. ¿por qué usar una tabla hash?, fácil, porque cuando preguntas si está o no el elemento en la tabla hash, esto toma mucho menos tiempo que si preguntaras si un elemento está en una lista por ejemplo. (Para esto te recomiendo que leas un poco de complejidad computacional).

Ahora si lo hubieras hecho al revés (ordenar el arreglo principal y tomar los elementos repetidos y no repetidos), hubieras tenido que trabajar más.

Cualquier duda estoy a tus órdenes.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Problema de lógica en una Ordenación simple

Publicado por Manuel F. (17 intervenciones) el 02/08/2016 08:10:24
Saludos a todos !!!

Gracias Flash y Aarón por sus respuestas... Resulta que recién abro el post y veo sus respuestas !
Bueno tenía días dándole vueltas a la lógica de este problema, y de tanto andar y andar, conseguí una solución parcial, gracias a DIOS, y de allí partí...
Para comenzar, el código debía analizar todos y cada uno de los elementos de un conjunto de datos, en el caso que mencioné, un array.
Debía tomar en cuenta los elementos repetidos (sería la frecuencia absoluta de cada uno de ellos) y luego calcular el promedio y frecuencia relativa.

Lo que hice fue lo siguiente:
1) Se declara un array sin dimensionar.
2) Se pregunta al usuario de cuantos elementos va a contener el vector (array). Tomando ese valor, se dimensiona el array.
3) Se procede a cargar el vector a medida que el usuario ingresa los números para el mismo.
4) Una vez finalizada la carga del vector, este es ordenado de forma creciente usando el método de "la burbuja".
5) Se muestra el vector cargado y ordenado.
6) Se declara otro vector que contendrá cada uno de los elementos sin duplicados, usando la intrucción .Distinct().ToString()
7) Se obtiene el tamaño del nuevo vector.
8) Se muestra el nuevo vector ordenado y sin duplicados (opcional).
9) Se declara otro vector frecuenciaAbsoluta[].
10) En dos bucles for anidados, se compara cada uno de los elementos del vector sin duplicados con cada uno de los elementos del vector original, y se contabiliza las veces que se repite un elemento y el valor (frecuencia absoluta) se va guardando en el vector frecuenciaAbsoluta[].
11) Se calcula el promedio de todos los valores del vector original.
12) Se declara un nuevo vector frecuenciaRelativa[].
13) En un bucle for, se va tomando cada valor del vector frecuenciaAbsoluta[] y se divide entre n (total de elementos del arreglo original) para obtener la frecuencia relativa y almacenarla en el vector frecuenciaRelativa[].
14) Finalmente, en un bucle for que hará tantas iteraciones como elementos tenga el vector de elementos sin duplicados.
y se van mostrando cada elemento con su respectiva frecuencia absoluta y frecuencia relativa respectivamente.

Disculpen tanta explicación o "palabrería", pero quier que vean más o menos explicado, como llegué a la solución, que a lo mejor es muy poco ortodoxa, pero me funcionó para el propósito que quería...

Les dejo el código, esperando que lo puedan mejorar y lo suban por favor !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
static void Main(string[] args)
{
       int[] array;
       int cont = 0;
       int n = 0;
       int datoTemporal = 0;
 
       Console.Clear();
       /* Se ingresan los datos que seran guardados en un 
       * arreglo "int[] array;"... */
       Console.Write("Cuantos números desea ingresar? ");
       n = Convert.ToInt32(Console.ReadLine());
       array = new int[n];
       Console.WriteLine();
 
       for (int i = 0; i < n; i++)
       {
              Console.Write("Ingrese el número [{0}]: ", i + 1);
              // Cargando el array...
              array[i] = Convert.ToInt32(Console.ReadLine());
       }
 
       /* Se ordena el Vector de datos o Array mediante el
       * método de la burbuja... */
       Console.WriteLine();
       Console.WriteLine();
       Console.WriteLine("Array ordenado en forma creciente...");
       for (int i = 0; i < n; i++)
       {
               for (int j = 0; j < n; j++)
               {
                       // Se procede a ordenarlo...
                       if (array[i] < array[j])
                       {
                               datoTemporal = array[i];
                               array[i] = array[j];
                               array[j] = datoTemporal;
                       }
               }
       }
 
       // Se muestra el array ya ordenado...
       Console.Write("    ");
       for (int i = 0; i < n; i++)
       {
               Console.Write("{0} ", array[i]);
       }
 
       Console.WriteLine();
       Console.WriteLine();
       Console.WriteLine();
       Console.WriteLine();
 
       // Se depura el array, eliminando los elementos repetidos...
       int[] arraySR = array.Distinct().ToArray();
       int t = arraySR.Length;
 
       // Se muestra el array sin elementos duplicados... 
       Console.Write("    ");
       for (int i = 0; i < t; i++)
       {
               Console.Write("{0} ", arraySR[i]);
       }
 
       /* Array para guardar las veces que se repite un
       * elemento en el array original (frecuencia absoluta)... */
       int[] frecuenciaAbsoluta = new int[t];
 
       for (int i = 0; i < t; i++)
       {
               for (int j = 0; j < n; j++)
               {
                       if (arraySR[i] == array[j])
                       {
                               // Se cuenta el número de repeticiones...
                               cont++;
                       }
               }
               /* Se guarda el número de repeticiones por cada
               * elemento en el array "frecuenciaAbsoluta[]"... */
               frecuenciaAbsoluta[i] = cont;
               /* Se lleva el contador a cero nuevamente para
               * poder contabilizar otro elemento distinto... */
               cont = 0;
       }
 
       Console.WriteLine();
       Console.WriteLine();
       /* Se muestra el array con la frecuencia absoluta 
       * "frecuenciaAbsoluta[]"... */
       Console.Write("    ");
       for (int i = 0; i < t; i++)
       {
               Console.Write("{0} ", frecuenciaAbsoluta[i]);
       }
 
       /* Se calcula el promedio de todos los elementos del
       * array original... */
       float promedio = (float)array.Average();
       /* Se calcula la frecuecia relativa de cada elemento: 
       * el valor de la frecuencia absoluta de un elemento
       * dado entre el número total de los mismos y se guarda
       * en el array "float[] frecuanciaRelativa" */
       float[] frecuenciaRelativa = new float[t];
       float frecuenciaRelat = 0;
       float f1 = 0;
       float sinRep = 0;
 
       for (int f = 0; f < t; f++)
       {
               f1 = frecuenciaAbsoluta[f];
               sinRep = arraySR[f];
               // Se calcula la frecuencia relativa...
               frecuenciaRelat = f1 / n;
               // Se guarda en el array "frecuanciaRelativa[]"...
               frecuenciaRelativa[f] = frecuenciaRelat;
       }
 
       Console.WriteLine();
       Console.WriteLine();
       Console.Write("    ");
       // Se muestra el promedio de todos los datos...
       Console.Write("Promedio: {0}", promedio.ToString("f3"));
       Console.WriteLine();
       Console.WriteLine();
       Console.Write("    ");
       Console.Write("Frecuencias Absolutas y Frecuencias Relativas: ");
       Console.WriteLine();
       Console.WriteLine();
       /* Se muestran los elementos del array sin duplicados 
       * "arraySR[]" y las respectivas frecuencias absolutas 
       * y frecuencias relativas, guardadas en los arrays 
       * "frecuenciaAbsoluta[]" y "frecuenciaRelativa[]"... */
       for (int f = 0; f < t; f++)
       {
               Console.Write("    ");
               Console.Write("{0}   ", arraySR[f].ToString());
               Console.Write("{0}   ", frecuenciaAbsoluta[f].ToString());
               Console.WriteLine("{0}   ", frecuenciaRelativa[f].ToString("f3"));
       }
 
       Console.ReadKey();
}


Saludos !!!


Manuel F. Borrego S.
Barcelona, Edo. Anzoátegui. Venezuela.
[Mientras nos permitan seguir comunicándonos...]
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Aarón Castillo

Problema de lógica en una Ordenación simple

Publicado por Aarón Castillo (3 intervenciones) el 02/08/2016 23:50:44
Si tu programa hace lo que debe y no importan otros factores como la complejidad computacional, es una tarea lograda. Sin embargo si debes cumplir requisitos de complejidad computacional, tu algoritmo es O(n^2), que puede reducirse a O(n), es decir, se pueden reducir el número de operaciones para que tu algoritmo tarde menos.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar