» »

[JavaScript] Sortiranje šumnikov

[JavaScript] Sortiranje šumnikov

MarkookraM ::

Kako ga prepričati, da sortira tudi šumnike? Encoding sem probal nastaviti tako na ISO-8859-2, kot tudi na UTF-8, nobeno ne deluje.

Za test uporabljam tole preprosto funkcijo:
var prvi = "Č";
var drugi = "V";
if (prvi < drugi)
{
alert('true');
}
else
{
alert('false');
}

V bistvu se vpraša ali naj postavim č pred v. Odgovor dobim false, kar je seveda narobe.

Kakšna ideja kako to porihtati?

arjan_t ::

tako ne bo šlo, primerja se charcode

lahko si nardiš array črk in potem primerjaš pozicijo

MarkookraM ::

In naj vsako črko posebej primerjam, o ne hvala. Že tako dela prepočasi hehe. Bom raje klical Java Servlet pa bo on zrihtal sort in vrnil novo tabelo.

MarkookraM ::

Saj tudi v Javi imam probleme s temi šumniki grrr!

Ideja z arrayjom črk bi potrebovala primerjanje vsake črke posebej? A nebi to bila zelo požrešna zadeva in tudi relativno težka za sprogramirat?

Sedaj imam takšno napol rešitev, še vedno ima težave z velikimi/malimi šumniki. Sortira jih takole: č, čaj, Č. Hočem pa, da je tako: č, Č, čaj. Ampak ne s to rešitvijo saj davam noter nek dolg niz za katerega upam, da je unikaten in se nebo nikjer pojavil.

record_delo[i][3] = record_delo[i][3].replace("č", "c0000000000000000000000001");
record_delo[i][3] = record_delo[i][3].replace("Č", "c0000000000000000000000002");

record_delo[i][3] = record_delo[i][3].replace("ć", "c0000000000000000000000003");
record_delo[i][3] = record_delo[i][3].replace("Ć", "c0000000000000000000000004");

// sortiram array in zamenjam nazaj v šumnike

jernejl ::

Če želiš sortirati case-insensitive, pretvori nize vse v lowercase (ali uppercase). Sicer ti jih bo uredilo tako, da boš najprej imel velike črke, potem pa male.

Če že zamenjuješ šumnike, potem jih lahko zamenjaš z bolj varnimi nizi. Npr tako:

test = test.replace(/Č/g, "C" + String.fromCharCode(254)); //šumnik se zamenja z C, ki mu sledi znak z visoko ASCII vrednostjo. Taki znaki se v originalnih nizih običajno ne uporabljajo, razen če gre za kak specifičen primer.

Tako pa napraviš zamenjavo nazaj:

test = test.replace(new RegExp( "C" + String.fromCharCode(254), "g" ),"Č");

Razmisli o tem, da originalno polje prepišeš v neko drugo, nad katerim izvedeš zamenjave šumnikov in pretvorbo v lowercase ter urejanje. Tako ti originalno polje z originalnimi nizi ostane.
Recimo, da je staro polje spremenljivka "staro", potem narediš novo polje "novo", kjer je vsak element objekt, ki vsebuje originalni niz, pretvorjen niz za urejanje.

Torej, z zanko:

novo[i] = Object();
novo[i].orig=staro[i];
novo[i].sort=staro[i].replace(/Č/g,"C" + String.fromCharCode(254)); //podoben replace se naredi za vse šumnike
novo[i].sort=String.toLowerCase(novo[i].sort);
novo[i].toString= function () {return this.orig}; //po želji za izpis

Funkcija za urejanje:

function sortby(a, b) {
return(a.sort==b.sort)?0:(a.sort>b.sort)?1:-1;
}

Uredimo:

novo=novo.sort(sortby);

Pa imamo urejeno polje.

Zgodovina sprememb…

  • spremenil: jernejl ()

MarkookraM ::

Ampak mislim, da tvoj način še vedno nebo znal pravilno postaviti velikih in majhnih nizov s velimi črkami. Recimo "C" bo verjetno postavil pred "cc". No, vem samo, da koliko sem jaz probaval te metode z zamenjavo šumnikov z nekimi posebnimi nizi, vse falirajo, samo pravi primer jim moraš dat sortirat. In seveda strah, da so bo po nekem naključju nekje našel ta poseben niz in se bo konvertiral v šumnik, uporabniku pa nič jasno. Razen če si zapomniš vse zamenjave in...ah...

Iz nule sem napisal svoj sortirni algoritem. Groza, teror in ogromno kave, da mi je uspelo hehe. Gleda črko za črko in mu lahko sam definiraš abecedo. Tako lahko imaš notri več abeced, zelo lahko je izključiti prioriteto lowercase.


int primerjava = 0;
String[][] tempek = new String[1][1];
String[][] abeceda = {{"1", "a"},
{"2", "A"},
{"3", "b"},
{"4", "B"},
{"5", "c"},
{"6", "C"},
{"7", "č"},
{"8", "Č"},
{"9", "ć"},
{"10", "Ć"},
{"11", "d"},
{"12", "D"},
{"13", "đ"},
{"14", "Đ"},
{"15", "e"},
{"16", "E"},
{"17", "f"},
{"18", "F"},
{"19", "g"},
{"20", "G"},
{"21", "h"},
{"22", "H"},
{"23", "i"},
{"24", "I"},
{"25", "j"},
{"26", "J"},
{"27", "k"},
{"28", "K"},
{"29", "l"},
{"30", "L"},
{"31", "m"},
{"32", "M"},
{"33", "n"},
{"34", "N"},
{"35", "o"},
{"36", "O"},
{"37", "p"},
{"38", "P"},
{"39", "q"},
{"40", "Q"},
{"41", "r"},
{"42", "R"},
{"43", "s"},
{"44", "S"},
{"45", "š"},
{"46", "Š"},
{"47", "t"},
{"48", "T"},
{"49", "u"},
{"50", "U"},
{"51", "v"},
{"52", "V"},
{"53", "w"},
{"54", "w"},
{"55", "x"},
{"56", "X"},
{"57", "y"},
{"58", "Y"},
{"59", "z"},
{"60", "Z"},
{"61", "ž"},
{"62", "Ž"}};


int i = 0;
int j = 0;
int k = 0;
int l = 0;
int i_jek = 0;
int j_jek = 0;
int kateriJeManjsi = 0;
int kdoImaPrejUpperCase = 0;
for (i = 0 ; i < steviloDelIzBaze-1 ; i++) // bubble sort zunanja zanka
{
for (j = i+1 ; j < steviloDelIzBaze ; j++) // bubble sort notranja zanka
{
if (record_delo[i][3].length() > record_delo[j][3].length()) // kateri niz je manjsi?
{ kateriJeManjsi = record_delo[j][3].length(); }
else
{ kateriJeManjsi = record_delo[i][3].length(); }

if (kateriJeManjsi > 0) // oba niza sta bila null?
{
k = 0;
do // vzemi trenutna niza ki se bosta primerjala in ju preleti crko za crko
{
// ce bosta ostala na 0 pomeni, da smo naleteli na poseben znak,
// ki ga nismo definirali v nasi abecedi in ta bo dobil prioriteto
i_jek = 0;
j_jek = 0;

l = 0;
do
{
if (record_delo[i][3].substring(k, k+1).equals(abeceda[l][1])) // trenutno crko prvega niza najdi v abecedi
{ i_jek = Integer.parseInt(abeceda[l][0]); break; }
l++;
}
while(l < abeceda.length);

l = 0;
do
{
if (record_delo[j][3].substring(k, k+1).equals(abeceda[l][1])) // trenutno crko drugega niza najdi v abecedi
{ j_jek = Integer.parseInt(abeceda[l][0]); break; }
l++;
}
while(l < abeceda.length);

// razlika v teh dveh crkah je samo uppercase, samo -1 v arrayju abecede
// ce bosta niza enaka bo zmagal tisti, ki je prej imel uppercase
if ((i_jek - 1 == j_jek) && (kdoImaPrejUpperCase != 0))
{ kdoImaPrejUpperCase = 1; }
if ((j_jek - 1 == j_jek) && (kdoImaPrejUpperCase != 0))
{ kdoImaPrejUpperCase = 2; }

k++;
}


Joj kak zna forum formatirati kodo. :-(
while((i_jek == j_jek) && (k != kateriJeManjsi)); // dokler sta trentni crki enaki in nismo prisli do konca najmanjsega niza
}//end if


// odlocitev, ce je potrebna zamenjava
if ((i_jek == j_jek) && (record_delo[i][3].length() > record_delo[j][3].length()))
{ primerjava = 1; }
else
{
if ((i_jek == j_jek) && (record_delo[i][3].length() == record_delo[j][3].length()))
{
if (kdoImaPrejUpperCase == 2) { System.out.println("pravilo 2"); primerjava = 1; }
}
else
{
if ((j_jek < i_jek))
{ primerjava = 1; }
}
}

if (primerjava == 1) // naredi zamenjavo
{
tempek[0] = record_delo[i];
record_delo[i] = record_delo[j];
record_delo[j] = tempek[0];
}

// resetiraj primerjalne spremenljivke
primerjava = 0;
kdoImaPrejUpperCase = 0;

}
}

Zgodovina sprememb…

MarkookraM ::

ups jaz nič kriv

Zgodovina sprememb…

jernejl ::

Recimo "C" bo verjetno postavil pred "cc".

Ali nisi tega želel? Kako bi pa moralo biti?

Tvoj bubble-sort (preletel sem ga v dveh sekundah) pa je verjetno zelo počasna zadeva, sploh če primerjaš črko s črko in pri tem sproti pregleduješ še array s črkami. Je vgrajena "sort" metoda gotovo hitrejša.

MarkookraM ::

Eh pardon, misil sem ravno obratno.

Moj algoritem le še ne deluje kot bi moral, je še potrebno malo popraviti. :-(

Verjetno pa ni kaj preveč pošasnejši od vgrajenih sortov. Kako pa oni delujejo če ne črko za črko?

MarkookraM ::

Sedaj pa res deluje pravilno, upam vsaj. :-)

int primerjava = 0;
String[][] tempek = new String[1][1];
String[][] abeceda = {{"1", "a"},
{"2", "A"},
{"3", "b"},
{"4", "B"},
{"5", "c"},
{"6", "C"},
{"7", "č"},
{"8", "Č"},
{"9", "ć"},
{"10", "Ć"},
{"11", "d"},
{"12", "D"},
{"13", "đ"},
{"14", "Đ"},
{"15", "e"},
{"16", "E"},
{"17", "f"},
{"18", "F"},
{"19", "g"},
{"20", "G"},
{"21", "h"},
{"22", "H"},
{"23", "i"},
{"24", "I"},
{"25", "j"},
{"26", "J"},
{"27", "k"},
{"28", "K"},
{"29", "l"},
{"30", "L"},
{"31", "m"},
{"32", "M"},
{"33", "n"},
{"34", "N"},
{"35", "o"},
{"36", "O"},
{"37", "p"},
{"38", "P"},
{"39", "q"},
{"40", "Q"},
{"41", "r"},
{"42", "R"},
{"43", "s"},
{"44", "S"},
{"45", "š"},
{"46", "Š"},
{"47", "t"},
{"48", "T"},
{"49", "u"},
{"50", "U"},
{"51", "v"},
{"52", "V"},
{"53", "w"},
{"54", "w"},
{"55", "x"},
{"56", "X"},
{"57", "y"},
{"58", "Y"},
{"59", "z"},
{"60", "Z"},
{"61", "ž"},
{"62", "Ž"}};


int i = 0;
int j = 0;
int k = 0;
int l = 0;
int i_jek = 0;
int j_jek = 0;
int kateriJeManjsi = 0;
int kdoImaPrejUpperCase = 0;
for (i = 0 ; i < steviloDelIzBaze-1 ; i++) // bubble sort zunanja zanka
{
for (j = i+1 ; j < steviloDelIzBaze ; j++) // bubble sort notranja zanka
{
if (record_delo[i][3].length() > record_delo[j][3].length()) // kateri niz je manjsi?
{ kateriJeManjsi = record_delo[j][3].length(); }
else
{ kateriJeManjsi = record_delo[i][3].length(); }

if (kateriJeManjsi > 0) // oba niza sta bila null?
{
k = 0;
do // vzemi trenutna niza ki se bosta primerjala in ju preleti crko za crko
{
// ce bosta ostala na 0 pomeni, da smo naleteli na poseben znak,
// ki ga nismo definirali v nasi abecedi in ta bo dobil prioriteto
i_jek = 0;
j_jek = 0;

l = 0;
do
{
if (record_delo[i][3].substring(k, k+1).equals(abeceda[l][1])) // trenutno crko prvega niza najdi v abecedi
{ i_jek = Integer.parseInt(abeceda[l][0]); break; }
l++;
}
while(l < abeceda.length);

l = 0;
do
{
if (record_delo[j][3].substring(k, k+1).equals(abeceda[l][1])) // trenutno crko drugega niza najdi v abecedi
{ j_jek = Integer.parseInt(abeceda[l][0]); break; }
l++;
}
while(l < abeceda.length);

// razlika v teh dveh crkah je samo uppercase, samo -1 v arrayju abecede
// ce bosta niza enaka bo zmagal tisti, ki je prej imel uppercase
if ((i_jek - 1 == j_jek) && (kdoImaPrejUpperCase == 0))
{ kdoImaPrejUpperCase = 1; i_jek = j_jek; } // i_jek in j_jek izenacimo da nebomo padli ven iz while zanke
if ((j_jek - 1 == i_jek) && (kdoImaPrejUpperCase == 0))
{ kdoImaPrejUpperCase = 2; i_jek = j_jek; } // i_jek in j_jek izenacimo da nebomo padli ven iz while zanke

k++;
}
while((i_jek == j_jek) && (k != kateriJeManjsi)); // dokler sta trentni crki enaki in nismo prisli do konca najmanjsega niza
}//end if


// odlocitev, ce je potrebna zamenjava
if ((i_jek == j_jek) && (record_delo[i][3].length() > record_delo[j][3].length()))
{ primerjava = 1; }
else
{
if ((i_jek == j_jek) && (record_delo[i][3].length() == record_delo[j][3].length()))
{
if (kdoImaPrejUpperCase == 1) { primerjava = 1; }
}
else
{
if ((j_jek < i_jek))
{ primerjava = 1; }
}
}

if (primerjava == 1) // naredi zamenjavo
{
tempek[0] = record_delo[i];
record_delo[i] = record_delo[j];
record_delo[j] = tempek[0];
}

// resetiraj primerjalne spremenljivke
primerjava = 0;
kdoImaPrejUpperCase = 0;

}
}

snow ::

Am... daj ko kopiraš kodo, jo prilepi v [ st.koda] [ /st.koda] oznake (brez presledkv pred [).
Pa koda v slovenščini se meni ful čudna zdi ;)
Random mutation plus nonrandom cumulative natural selection - Richard Dawkins

Mavrik ::

Zakaj maš tam številke v stringih in jih potem naknadno parsaš v integer pri _vsakem_ obhodu zanke? To je brezveze in samo brez potrebe kuriš procesorske cikle (kar pri jeziku kot je JS ni tak trivialno).

Pa morda bi lahko uporabil kakšen bolj optimalen sortirni algoritem... npr. QuickSort.
The truth is rarely pure and never simple.

MarkookraM ::

Tema je malce zašla, to ni JS, to je Java. :-)

Nova koda, ki pa deluje perfektno (upam vsaj hehe).

Primer kako sortira tabelo, v predogledu posta je slika ogromna, upam da bo boljse po postu.
 primer sortirane tabele

primer sortirane tabele



/********************************************************************** 
		 ** sortiraj record_delo kot je bilo zahtevano s parametri 		     **
		 **														   		     **
		 ** poCemNajSortiram = 0: DATUM							   		     **
		 **					 = 1: PODROCJE						   		     **
		 **					 = 2: STORITEV						   		     **
		 **					 = 3: OPIS							   		     **
		 **					 = 4: URE							   		     **
		 **					 = 5: KONTAKT						   		     **
		 **					 = 6: NAROCNIK						   		     **
		 **					 = 7: TIP							   		     **
		 **														   		     **
		 ** kakoNajSortiram = "AZ" - od najmanjsega do najvecjega  		     **
		 ** 				= "ZA" - od najvecjega do najmanjsega  		     **
		 **																     **
		 **																     **
		 **	- Sortirni algoritem uporablja prej definirano abecedo.			 **
		 **   Pri dodajanju novih crk ali znakov se morajo dodajati v parih. **
		 **   Na prosto neparno stevilo se da lowercase znaka, na naslednjo  **
		 **   pa njegov uppercase, ce znak nima uppercase ga vseeno dodamo   **
		 **   v paru na neparno in naslednje parno stevilo				     **
		 ** - Ce se najde znak, ki ni definiran v abecedi dobi 				 **
		 **   prioriteto pred vsemi definiranimi							 **
		 ** - Uppercase prioriteta se bo upostevala samo pri prvi besedi	 **
		 **   oz. dokler ne naletimo na prvi presledek						 **
		 **********************************************************************/
		int primerjava = 0;
		String[][] tempek = new String[1][1];
		String[][] abeceda = {{"1",  "a"},
							  {"2",  "A"},
							  {"3",  "b"},
							  {"4",  "B"},
							  {"5",  "c"},
							  {"6",  "C"},
							  {"7",  "č"},
							  {"8",  "Č"},
							  {"9",  "ć"},
							  {"10", "Ć"},
							  {"11", "d"},
							  {"12", "D"},
							  {"13", "đ"},
							  {"14", "Đ"},
							  {"15", "e"},
							  {"16", "E"},
							  {"17", "f"},
							  {"18", "F"},
							  {"19", "g"},
							  {"20", "G"},
							  {"21", "h"},
							  {"22", "H"},
							  {"23", "i"},
							  {"24", "I"},
							  {"25", "j"},
							  {"26", "J"},
							  {"27", "k"},
							  {"28", "K"},
							  {"29", "l"},
							  {"30", "L"},
							  {"31", "m"},
							  {"32", "M"},
							  {"33", "n"},
							  {"34", "N"},
							  {"35", "o"},
							  {"36", "O"},
							  {"37", "p"},
							  {"38", "P"},
							  {"39", "q"},
							  {"40", "Q"},
							  {"41", "r"},
							  {"42", "R"},
							  {"43", "s"},
							  {"44", "S"},
							  {"45", "š"},
							  {"46", "Š"},
							  {"47", "t"},
							  {"48", "T"},
							  {"49", "u"},
							  {"50", "U"},
							  {"51", "v"},
							  {"52", "V"},
							  {"53", "w"},
							  {"54", "w"},
							  {"55", "x"},
							  {"56", "X"},
							  {"57", "y"},
							  {"58", "Y"},
							  {"59", "z"},
							  {"60", "Z"},
							  {"61", "ž"},
							  {"62", "Ž"},
							  {"63", " "},
							  {"64", " "}};
				
		
		int i = 0;
		int j = 0;
		int k = 0;
		int l = 0;
		int i_jek = 0;
		int j_jek = 0;
		int kateriJeManjsi = 0;
		int kjeIma_i_prviUpperCase = -1;
		int kjeIma_j_prviUpperCase = -1;
		int nehajGledatiUpperCase_i = 0;
		int nehajGledatiUpperCase_j = 0;
		for (i = 0 ; i < steviloDelIzBaze-1 ; i++) // bubble sort zunanja zanka
		{
			for (j = i+1 ; j < steviloDelIzBaze ; j++) // bubble sort notranja zanka
			{
				// kateri niz je manjsi? zanka ki gleda crke se bo obrnila samo do najmanjsega
				if (record_delo[i][3].length() > record_delo[j][3].length()) 
				{ kateriJeManjsi = record_delo[j][3].length(); }
				else
				{ kateriJeManjsi = record_delo[i][3].length(); }
				
				if (kateriJeManjsi > 0) // oba niza sta bila null?
				{
					k = 0;
					do // vzemi trenutna niza ki se bosta primerjala in ju preleti crko za crko
					{
						// ce bosta ostala na 0 pomeni, da smo naleteli na poseben znak, 
						// ki ga nismo definirali v nasi abecedi in ta bo dobil prioriteto
						i_jek = 0; 
						j_jek = 0;
						
						l = 0;
						do // trenutno crko prvega niza najdi v abecedi
						{
							if (record_delo[i][3].substring(k, k+1).equals(abeceda[l][1])) 
							{ i_jek = Integer.parseInt(abeceda[l][0]); break; }
							l++;
						}
						while(l < abeceda.length);
					
						l = 0;
						do // trenutno crko drugega niza najdi v abecedi
						{
							if (record_delo[j][3].substring(k, k+1).equals(abeceda[l][1])) 
							{ j_jek = Integer.parseInt(abeceda[l][0]); break; }
							l++;
						}
						while(l < abeceda.length);
						
						
						// poglej, ce je razlika v teh dveh crkah samo uppercase, torej samo -1 v arrayju abecede
						// ce bosta niza enaka bo zmagal tisti, ki je prej imel uppercase
						if ((i_jek - 1 == j_jek) && (nehajGledatiUpperCase_i == 0))
						{ 
							i_jek = j_jek; // i_jek in j_jek izenacimo da nebomo padli ven iz while zanke
							if (kjeIma_i_prviUpperCase == -1) // samo ce ga se nismo nasli
							{ kjeIma_i_prviUpperCase = k; }
						} 
						if ((j_jek - 1 == i_jek) && (nehajGledatiUpperCase_j == 0))
						{ 
							i_jek = j_jek; // i_jek in j_jek izenacimo da nebomo padli ven iz while zanke 
							if (kjeIma_j_prviUpperCase == -1) // samo ce ga se nismo nasli
							{ kjeIma_j_prviUpperCase = k; }
						}
						
						if ((i_jek == 63) || (i_jek == 64)) // nasli smo presledek v prvi besedi
						{ nehajGledatiUpperCase_i = 1; }
						
						if ((j_jek == 63) || (j_jek == 64)) // nasli smo presledek v drugi besedi
						{ nehajGledatiUpperCase_j = 1; }
						
						k++;
					}
					while(((i_jek == j_jek) && (k != kateriJeManjsi))); // dokler sta trentni crki enaki in nismo prisli do konca najmanjsega niza
				}//end if
				
								
				// odlocitev, ali je potrebna zamenjava
				// prisli smo do konca manjsega niza, niza sta enaka in prvi je samo daljsi
				if ((i_jek == j_jek) && (record_delo[i][3].length() > record_delo[j][3].length()))
				{ primerjava = 1; }
				else
				{
					// niza se razlikujeta samo po uppercase
					if (((i_jek == j_jek) || (j_jek - 1 == i_jek) || (i_jek - 1 == j_jek)) && (record_delo[i][3].length() == record_delo[j][3].length()))
					{
						if ((kjeIma_i_prviUpperCase > kjeIma_j_prviUpperCase)) // zmaga tisti, ki ima prej uppercase
						{ primerjava = 1; }
					}
					else
					{
						// drugi niz se je koncal na crko z vecjo prioriteto in ta ni samo lowercase prve
						if ((j_jek < i_jek) && (i_jek - 1 != j_jek))
						{ primerjava = 1; }
					}
				}
				
				if (primerjava == 1) // naredi zamenjavo
				{
					tempek[0]      = record_delo[i];
					record_delo[i] = record_delo[j];
					record_delo[j] = tempek[0];
				}
				
				// resetiraj primerjalne spremenljivke za naslednji par nizov
				primerjava = 0;
				kjeIma_i_prviUpperCase = -1;
				kjeIma_j_prviUpperCase = -1;
				nehajGledatiUpperCase_i = 0;
				nehajGledatiUpperCase_j = 0;
			}
		}

Mavrik ::

Uspel si skomplicirati in sproducirati neverjetno dolgo kodo, namesto da bi pogooglal in imel rešitev v parih minutah:

Collator siCollator = Collator.getInstance(new Locale("sl_si"));
Collections.sort(stringi, siCollator);
The truth is rarely pure and never simple.

Zgodovina sprememb…

  • spremenil: Mavrik ()

BigWhale ::

FTWPWND!
;>

MarkookraM ::

Ampak to nebi bilo tako zabavno. ;-)


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C#] sortiranje priimkov po slovenski abecedi

Oddelek: Programiranje
61455 (1266) mihies
»

Pomoč pri programiranju z javo

Oddelek: Programiranje
203322 (2249) milc
»

osnove v Javi - zvezdice

Oddelek: Programiranje
403379 (2601) Tutankhamun
»

[c++] problem: pretvorba iz malih v velike crke

Oddelek: Programiranje
142000 (1647) Makina
»

Pomoč pri Flash MX 2004

Oddelek: Programska oprema
9907 (799) Vesoljc

Več podobnih tem