This is an algorithm I made to alphabetically sort names and sort numbers. I tried searching in the internet for something like this to sort names alphabetically, but coulnt find it, or didnt look well. What I came up with, is that I knew there existed algorithms to sort numbers so I took the more efficient 2^n algorithm and adapted to sort letters. This is the shell algorithm! Becuase I used Visual C# is kind of easy when converting from string to int's and so on so I didnt have much problems. What I needed was to sort rows contained in a Datarow [ ] alphabetically, so the function takes the rows in Entrada, also takes which column of the row is going to read so that it is compared with the others(int posicion), also because I used Indexes in my tables, sometimes in my rows there were only indexes pointing to other tables which contained the names, so I put bool ligar which if true, means they are indexes and have to search in other tables, then also takes Relacion, which if ligar=true then relacion must contain the name of the relationship to the other table, so that it knows in which table the name is contained, and at last, I need to sort also by numerical order, so if it is true then it forgets all my adaptations and just uses the shell algorithm. It is quite simple, it looks quite messy but it just takes the word and each letter assignes it a numer, so name "a" will become (1)x27^5 if name "ab" will be (1)x27^5+(2)x27^4 and if name"abc" will be (1)x27^5+(2)x27^4+(3)x27^3 and so forth. The limitations of my algorithm is that it only compares the first 5 letters of the name. I think that is more than enough for my case, if you need more then just give bigger numbers to the exponent. Instead of 5 in my case, you could give 9 or 10, as you wish, the only problem would be you'll use numbers pretty big, bigger than a 32bit INT.
Hope it helps... enjoy...
Visual c# code:
DataRow[] regresaLugarAlfabetico(DataRow[] Entrada, int PosicionTexto,bool ligar, string relacion, bool numero)
{
//algoritmo shell
DataRow auxiliar;
int salto = Entrada.Length / 2;
int j, k;
int pasadas = 0;
while (salto > 0)
{
for (int i = salto; i < j =" i">= 0)
{
k = j + salto;
int exp = 1;
UInt32 uno = 0;
UInt32 dos = 0;
int charcomp = 6;
double Base = 27.0; //
if (numero == false)
{
string ej;
string ek;
if (ligar == false)
{
ej = Entrada[j][PosicionTexto].ToString();
ek = Entrada[k][PosicionTexto].ToString();
}
else
{
DataRow drj = Entrada[j];
DataRow drk = Entrada[k];
DataRow Papadrj = drj.GetParentRow(relacion);
DataRow Papadrk = drk.GetParentRow(relacion);
ej = Papadrj[PosicionTexto].ToString();// Entrada[j][PosicionTexto].ToString();
ek = Papadrk[PosicionTexto].ToString();// Entrada[k][PosicionTexto].ToString();
}
while (exp < charcomp)//hasta 5 caracteres comparaa y depende del int32 para aumentar a mas;
{
if (ej.Length >= exp && (int)ej[0] > 96 && (int)ej[0] < 123)//"a-z";
{
uint n = ((uint)ej[exp - 1]) - 96;
double p = System.Math.Pow(Base, (charcomp - exp));
uno = uno + (n) * Convert.ToUInt32(p);
}
else if (ej.Length >= exp && (int)ej[0] > 64 && (int)ej[0] < 91) //"A-Z";
{
uint n = ((uint)ej[exp - 1] - 64);
double p = System.Math.Pow(Base, (charcomp - exp));
uno = uno + (n) * Convert.ToUInt32(p);
}
if (ek.Length >= exp && (int)ek[0] > 96 && (int)ek[0] < 123)//"a-z"
{
uint n = ((uint)ek[exp - 1]) - 96;
double p = System.Math.Pow(Base, (charcomp - exp));
dos = dos + (n) * Convert.ToUInt32(p);
}
else if (ek.Length >= exp && (int)ek[0] > 64 && (int)ek[0] < 91)//"A-Z"
{
uint n = ((uint)ek[exp - 1] - 64);
double p = System.Math.Pow(Base, (charcomp - exp));
dos = dos + (n) * Convert.ToUInt32(p);
}
exp++;
if (ek.Length < exp && ej.Length < exp) { break; }
} }
else
{
uno = Convert.ToUInt32(Convert.ToDouble(Entrada[j][2])*1000);
dos = Convert.ToUInt32(Convert.ToDouble(Entrada[k][2])*1000);
}
pasadas++;
if (uno <= dos)
{
j = -1;
}
else
{
auxiliar = Entrada[j];
Entrada[j] = Entrada[k];
Entrada[k] = auxiliar;
j = j - salto;
}} }
salto = salto / 2;
//pasadas++;
}
return Entrada;
}
miércoles, 30 de enero de 2008
Suscribirse a:
Entradas (Atom)