Diskuze: problém Seřazení objektů podle jména
V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.


Pokud resit databazi, tak se k tomu pouzivaji programy na spravu databaze a
tabulek v ni. Sql prikazem obvykle ziskavas uz tabulku pro vypis.
Pro cpp ti moc neporadim, ale urcite bys nasel priklady googlem na sortovani. V
JS to funguje tak, ze sortovaci funkci muzes predat funkci pro porovnani.
Ukazka:
list = array();
list.sort(); // seradi
list = array();
list[0] = array();
list[0][0] = 5;
// a ted bys byl se sortem uplne v haji, ale...
function cmp(a,b) {return a[0]<=b[0] ? 0 : 1;} // if (radek_a[sloupec_0]<=radek_b[sloupec_0]
list.sort(cmp);
list = array();
list[0] = 'Jenda';
// a ted bys byl se sortem uplne v haji, opet, protoze stringy neporovnava jako stringy, ale jako cisla ...
function cmp(a,b) {return a.length<=b.length ? 0 : (a<=b ? 0 : 1);} // porovna delky stringu a pak porovnava stringy
list.sort(cmp);
list = array();
list[0] = 'Jeníček';
// a dalsi problem, diakritika, to bys musel upravit porovnavaci funkci i o ni, to se mi resit ted nechce
list = array();
list[0] = object();
list[0]['name'] = 'Jenik';
function cmp(a,b) {return a['name']<=b['name'] ? 0 : 1;} // if (radek_a[sloupec_0]<=radek_b[sloupec_0]
list.sort();
Takze, pokud to jde, pouzil bych nativni sort funkci.
Pokud to nejde, tak bych pouzil list-merge sort. Nebo quick sort.
A pokud mas do 100 polozek, tak by byla pouzitelna insert to middle. Ten funguje
tak, ze serazene pole rohledavas od stredu, stred pulky, stred ctvrtky...
1.
Kdyz porovnavas jmena, stringy, musis porovnavat delky retezcu, pak hodnoty.
xxx < AAAAAA = lidsky, chces obvykle kratke nahore
AAAAAA < xxx = ale u normalniho sortu rozhodne prvni porovnani znaku a to je
x > A
A u hodnot nastava krize v pripade diakritiky. Hodnoty se porovnavaji znak po
znaku. Ascii kody znaku jsou v poradi cisla (48), velka pismena (65), mala
pismena (97), diakritika (128). Takze pro stringy musis pouzit vlastni tabulku
poradi znaku.
Cili, tvuj sort bych predelal nejak takto. (ale pac cecko neumim, tak to musis dotahnout sam)
void sortCompare(*a, *b)
{
return a<=b ? false : true;
}
void sortSwap(*a, *b)
{
tmp = a;
a = b;
b = tmp;
}
void bubbleSort(*array, *cmp, start, end) {
// cili, abys mohl zadavat, kterou cast chces seradit, start, end
// abys to mohl pouzit i pro jinou array
// a abys tam mohl zadavat porovnavaci funkci
for (int i = start; i < (end - 1); i++) {
for (int j = (i+1); j < end; j++) {
if (cmp(array[i], array[j]) {
sortSwap(array[i], array[j]);
}
}
}
}
2. Data musis drzet dal od funkci, jinak se v tom brzo ztratis a tez zbytecne zatezujes pamet duplikovanim funkci.
class classUcitel :
public a, b, c;
public function x() {}
public function y() {}
};
osoby = array();
osoby[0] = new classUcitel() // ted ti to zabere v pameti nejen a,b,c, ale i x a y
class struUcitel :
public a, b, c;
};
osoby = array();
osoby[0] = new struUcitel()
// ty funkce preci muzes volat tak, ze jim predas ucitele
class fceUcitel :
{
function SetKatedra(ucitel, katedra);
function Vypis(ucitel);
function Zadej(ucitel, data);
function VypisUcitele(osoby_list)
{
str = '';
for ( i=0; i<count(osoby_list); i++)
{str+= "\n" + VypisData(osoby_list[i]);}
print str;
}
};
// a jinak bych to vytvarel nejakym takovym zpusobem
list = array();
list.add(new struUcitel ('jmeno', 'prijmeni'));
list.add(new struUcitel ('jmeno', 'prijmeni'));
list.add(new struUcitel ('jmeno', 'prijmeni'));
+20 Zkušeností
+2,50 Kč

DarkCoder:10.6.2020 14:59
V C máš implementovanou funkci strcmp() pro lexikografické porovnání dvou řetězců, hlavičkový soubor string.h. Dále máš zde implementovanou funkci qsort() pro třídění pole pomocí algoritmu QuickSort, hlavičkový soubor stdlib.h.
Vytvoř si dynamicky alokované pole celých čísel o velikosti počtu položek databáze naplněné hodnotami představující pozici daného záznamu databáze. Porovnávej klíče databáze a třiď dynamicky alokované pole. Po setřídění dynamicky alokované pole obsahuje hodnoty indexů databáze v pořadí jakém by se nacházely abecedně setříděné řetězce. Pro výpis setříděné databáze procházej postupně dynamicky alokované pole a vypisuj záznam na indexu databáze odpovídající hodnotě v dynamicky alokovaném poli.
Luboš Horký:10.6.2020 16:23
Díky za objasnění sort funkce. Máš pravdu, že při porovnání stringů převádí string na čísla, to není v mém případě úplně vhodné. Takže jsem si vytvořil vlastní funkci na seřazení sice jsem vynechal tvoji "sortCompare" funkci ale přetypoval jsem si funkci pro operator < , kde teď už místo sortu jsem použil porovnání délky jmen a následně jejich písmen zvlášť, jak jsi radil.
Zdá se že podle toho vše funguje.
Občas se porovnání ještě sekne, ale myslím že to bude nějakou
maličkostí v kódu.
Jinak díky za poukázání na "insert to middle", o tom jsem zatím neslyšel a rozhodně to zní využitelně!
Jinak, kdyby někdo řešil stejný problém co já dám sem výsledný kód
pro to uspořádání objektů
Zde byl kámen úrazu, porovnával jsem špatně řetězce, takhle by to mělo
být správně:
bool COsoba::operator<(const COsoba& osoba) const
{
int delka;
if (strlen(m_Jmeno) <= strlen(osoba.m_Jmeno))
delka = strlen(m_Jmeno);
else
{
delka = strlen(osoba.m_Jmeno);
}
//urceni kratsiho retezce
if(m_Jmeno[0] < osoba.m_Jmeno[0]){ return true; }
if (m_Jmeno[0] > osoba.m_Jmeno[0])
{
return false;
}
else
{
if(m_Jmeno[0]==osoba.m_Jmeno[0])
for (int k = 0; k < delka; k++)
if (m_Jmeno[k] < osoba.m_Jmeno[k])
{
return true;
}
}
}
a v mainu se použije pouze obyčejný bubble:
for (int i = 0; i < x; i++)
{
for (int k = 0; k <x ; k++)
{
if (*osoby[i]<*osoby[k])
{
//prohod(i, k); --> funkce prohod nefunguje spravne !
COsoba* temp;
temp = osoby[i];
osoby[i] = osoby[k];
osoby[k] = temp;
}
}
}
Ještě jednou díky !
Luboš Horký:10.6.2020 16:36
Díky, funkci strcmp() je dobré znát, alespoň si pro příště nemusím
tuhle funkci sám tvořit
A qsort() taky ulehčí mnoho práce
Jen nevím jestli není zbytečné tolik knihoven, ale samozřejmě na to se
asi nehraje
DarkCoder:10.6.2020 17:00
Jo, obojí celkem ulehčí dost práce. Ale tak aspoň sis trochu procvičil
algoritmizaci, to se vždy hodí. Obě funkce jsou součástí standartních knihoven jazyka C, tak
proč toho nevyužít. Jinak překladače jsou optimalizované tak, že
vkládají do kódu pouze funkce použité v programu. Nejsem příznivcem toho
aby mé programy obsahovaly seznamy includovaných hlavičkových souborů, ale
zde to má smysl. Ještě by se Ti mohla hodit funkce bsearch() která provádí
binární vyhledávání v setříděném poli, nachází se podobně jako
funkce qsort() v hlavičkovém souboru stdlib.h.
Zobrazeno 6 zpráv z 6.