» »

[c++]iskalnik po bazi podatkov

[c++]iskalnik po bazi podatkov

'FireSTORM' ::

torej mam ustvarjeno svojo bazo podatkov
vsak podatek(Item) ma pa še 6 "podpodatek"(ItemText) oz. podrobnosti o tem podatku
torej vseka skupaj je 7
sedaj pa delam iskalnik po teh podatkih
pišem delne parametre in zaženem išči nakar mi pomeče ven vse kateri tem parametrom ustrezajo

sedaj pa mi nastaja problem, ker če mam dva enaka podatka(Item) in je razlika samo v "podpodatku"(ItemText)
in če iščem po imenu podatka in vnesem še tudi tisti različen "podpodatek" mi izpiše opa neglede na to da imata različen podpodatek, kar pa...ni vredu
torej moram spremeniti iskalni algoritem
saj lepo in kul, ampak 7 iskalnih parametrov če tu naredim kombinacije katere so vse možne je to kar lepa številka za napisat kodo potem

je mogoče kak hitrejša varianta?
domišljujem se je že x dnevov in ne morem prit gor kako bi šlo hitreje
Those penguins.... They sure aint normal....

Gundolf ::

> saj lepo in kul, ampak 7 iskalnih parametrov če tu naredim kombinacije katere so vse možne je to kar lepa številka za napisat kodo potem
Zakaj bi pa vse možne kombinacije napisal?

Pa naredi nekako takole (upam da sem prav razumel tvoj tekst)
class Item;
class ItemText;

struct SearchStruct {
   Item item;
   ItemText itemText[6];
   int searchMask;
}

searchFunc(SearchStruct& s);

Zdej maš eno samo funkcijo za iskanje. Preden jo zaženeš nastaviš vse kar iščeš v en SearchStruct in v searchMask zapišeš kaj vse naj ti tvoja funkcija primerja. Recimo če daš v searchMask 1+2+4, ti bo searchFunc primerjala item in prva dva itemText. Še lažje bi bilo, če bi imel vsak tvoj podatek neko neveljavno vrednost, in bi enostavno to zapisal v tiste podatke, ki jih ne želiš primerjat. Tako bi ti tudi maska odpadla.

Je približno jasno?

'FireSTORM' ::

malo je jasno ja...
lej, pozabil sem omenit da to delam v MFC z okni, list control itd...

torej do sedaj sem mel narejeno tako
da primerja čisto vse parametre
ime podatka pa vseh 6 parametrov oz. ItemTextov iz podatka
ampak kdo bo iskal nek podatek z iskalnikom če pa itak vse ve o njem...
ok potem sem začel razmišljat naprej
naredim iskalnik tak
če je iskano samo po imenu podatka
če je iskano samo po prvem parametru podatka
če je samo po drugem itd itd.
ampak to bi pisal in pisal v nedogled in še časa bi zabil še pa još
torej to bi raje izključil
mam pa vse podatek shranjene v eni datoteki
7 vrstic je en podatek z vsemi parametri
in jih prebiram v program, prvih sedem, primerjam po iskanih besedah ali številkah
če ni grem k naslednjemu podatku, torej spet naslednjih 7 vrstic
to delam dokler ne pridem do konc file-a
če pa vmes ker podatek ustreza iskanemu, pa ga vrže v listcontrol...in seveda spet nadaljuje normalno dokler ne pride do konca seznama...
bom kar pastal ta odsek iskanja sem
	while (!fajl.eof())
	{
		fajl.getline(ime,200);
		fajl.getline(opis,50);
		fajl.getline(tip,20);
		fajl.getline(stevilo,20);
		fajl.getline(kater,20);
		fajl.getline(ip_las,50);
		fajl.getline(ip_pos,50);
		// kopiranje zaradi spremembe vseh znakov v lower case
		ime1.Format("%s",ime);
		opis1.Format("%s",opis);
		tip1.Format("%s",tip);
		stevilo1.Format("%s",stevilo);
		kater1.Format("%s",kater);
		ip_las1.Format("%s",ip_las);
		ip_pos1.Format("%s",ip_pos);
		//lower case, podatek iz datoteke
		ime1.MakeLower();
		opis1.MakeLower();
		tip1.MakeLower();
		stevilo1.MakeLower();
		kater1.MakeLower();
		ip_las1.MakeLower();
		ip_pos1.MakeLower();
		//lower case, podatek iskan
		m_ime_iskan.MakeLower();
		m_opis_iskan.MakeLower();
		m_tip_isk.MakeLower();
		m_stevilo_isk.MakeLower();
		m_last_iskan.MakeLower();
		m_ipizp_iskan.MakeLower();
		m_ippos_isk.MakeLower();
		if(m_ime_iskan!="")
			ime_find=ime1.Find(m_ime_iskan);
		if(m_opis_iskan!="")
			opis_find=opis1.Find(m_opis_iskan);
		if(m_tip_isk!="")
			tip_find=tip1.Find(m_tip_isk);
		if(m_stevilo_isk!="")
			stevilo_find=stevilo1.Find(m_stevilo_isk);
		if(m_last_iskan!="")
			kater_find=kater1.Find(m_last_iskan);
		if(m_ipizp_iskan!="")
			ipizp_find=ip_las1.Find(m_ipizp_iskan);
		if(m_ippos_isk!="")
			ippos_find=ip_pos1.Find(m_ippos_isk);
		//search
		/*if((m_ime_iskan==ime1)||(m_opis_iskan==opis1)||(m_tip_isk==tip1)||(m_stevilo_isk==stevilo1)||
                     (m_last_iskan==kater1)||(m_ipizp_iskan==ip_las1)||(m_ippos_isk==ip_pos1))
		{
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
			goto SIGNXT;
		}*/
		if((ime_find!=-1)&&(opis_find!=-1)&&(tip_find!=-1)&&(stevilo_find!=-1)&&
                   (kater_find!=-1)&&(ipizp_find!=-1)&&(ippos_find!=-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find!=-1)&&(opis_find==-1)&&(tip_find==-1)&&(stevilo_find==-1)&&
                   (kater_find==-1)&&(ipizp_find==-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find!=-1)&&(tip_find==-1)&&(stevilo_find==-1)&&
                   (kater_find==-1)&&(ipizp_find==-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find==-1)&&(tip_find!=-1)&&(stevilo_find==-1)&&
                   (kater_find==-1)&&(ipizp_find==-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find==-1)&&(tip_find==-1)&&(stevilo_find!=-1)&&
                   (kater_find==-1)&&(ipizp_find==-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find==-1)&&(tip_find==-1)&&(stevilo_find==-1)&&
                   (kater_find!=-1)&&(ipizp_find==-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find==-1)&&(tip_find==-1)&&(stevilo_find==-1)&&
                   (kater_find==-1)&&(ipizp_find!=-1)&&(ippos_find==-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
		if((ime_find==-1)&&(opis_find==-1)&&(tip_find==-1)&&(stevilo_find==-1)&&
                   (kater_find==-1)&&(ipizp_find==-1)&&(ippos_find!=-1))
			CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
	}
	fajl.close();

če ti je kaj jasno iz tega, mam nekaj komentarjev, upam da pomaga kaj...

edit: pozabil omenit, zdaj mam narejeno tak kot nočem met...
Gundolf edit: sem dodal tag [st.koda c++]
Gundolf edit: sovražim predolge vrstice...
Those penguins.... They sure aint normal....

Zgodovina sprememb…

  • spremenil: Gundolf ()

Gundolf ::

Uf, vse kar mi je jasno iz te kode je, da je prekomplicirana.

'FireSTORM' ::

ko sem to postal in prebral še enkrat tvoj post za tem mi je že bolj postalo jasno kaj misliš
da bi dal tam kjer po katerem naj se ne išče nek poseben znak, npr. /
in potem samo iskal po tistih parametrih po katerih uporabnik hoče iskat
mam prav?

v bistvu ni tako zakomplicirana, najprej ves podatek preberem v program
spremin vse v lower case za lažje iskanje
poiščem še morebitne substringe
in če ni najdenega substringa vrne funkcija -1, če pa je pa vrne 0,1,2,3,4...kaj koli
v glavnem ne sme bit -1, če ni potem je iskani parameter v podatku ali pa iskani parameter je podatek ali "podpodatek"
Those penguins.... They sure aint normal....

Gundolf ::

Upam da razne ime_find, opis_find, ... imaš initializirane, tako da če uporabnik ne išče po teh poljih, bodo te spremenljivke kazale da so polja v redu (recimo, če uporabnik ne išče po opisu mora opis_find ne sme biti -1, kar bi nakazovalo da se opis ne ujema z iskanim)

In na koncu če so vis find_xxx ok, dodaš iteme v tvoj listbox. To ti tisti zadnji if dela, ne vem pa zakaj si ga tollikokrat namnožil...

'FireSTORM' ::

saj če nič ne vnese uporabnik je polje prazno, CString = ""
in nič ne more bit na nekem mestu...
torej vrne v tem primeru opis_find = -1
in potem mam v if stavkih ki so tukaj na dolgo in širiko napisani
if (opis_find==-1) in zraven še 6 drugih in že če je opis_find različen od -1 se ta if preskoči ker mam pogoje na AND oz. &&

ne lej, prvi if je če je popolnoma vse kar je iskano prav potem ga izpiše oz. vrže na lsitbox
drugi je če je samo ime pravo
potem če je samo opis
itd itd.
ampak to sem samo sprobaval in ko sem prišel tako daleč sem se malo popraskal in ugotovil da bom to pisal 5 let če bom tako nardil
Those penguins.... They sure aint normal....

Zgodovina sprememb…

Gundolf ::

Ja tako sem v prvem postu mislil, ampak podobno temu že imaš. Pač pogledaš če je nek tvoj m_XXX_iskan enak "" in če je, potem ga ne greš primerjat. Samo verjetno ti manjka to, da ko ga ne greš preverjat, moraš vseeno označit kot da je to polje v redu, oz. ga označiš kot da si ga šel iskat in našel vedno ujemanje. Zato tista initializacija, ki sem jo prejle omenil.

Za vsako polje bi imel v psevdokodi nakako takole:
if (!iscem_to_polje || (vsebina == iskanemu_nizu))
   to_polje = ok
else
   to_polje = !ok;

//potem pa v iskanju:
if (polje1 == ok && polje2 == ok && ...)
  dodaj_v_list(polje1, polje2, ...)


Ka je pa v tvoji kodi preveč komplicirano je pa to, da imaš vsa polja praktično enaka (stringi) in na vsakem izvedeš en kup enakih operacij in je zato en kup copy-pastane kode. Manj komplicirano bi bilo če bi recimo napisal nekako takole:
//funkcija ki na enem fieldu naredi vse operacije
bool getAndCompareField(ifstream& fajl, char* fieldOrg, CString& fieldLow, int size, Cstring& compareTo) {
   fajl.getline(fieldOrg, size);
   field.Format("%s", fieldOrg);
   field.MakeLower();
   compareTo.MakeLower();
   // vrne true če je iskan niz enak "" (briga te njegova vrednost) ali pa je enak prebranemu nizu
   return ((m_ipizp_iskan == "") || (field.Find(compareTo) != -1));
}

...

while(!fajl.eof()) {
  // za vse fielde naredi iste operacije
   bool fieldsOk = getAndCompareField(fajl, ime, ime1, 200, m_ime_iskan);
   fieldsOk |= getAndCompareField(fajl, opis1, 200, m_opis_iskan);
   ...
   // skupen ok pove ali je match ali ni
   if (fieldsOk)
      CSearchDlg::IskVnos(ime, opis, tip, stevilo, kater, ip_las, ip_pos);
}

Zgodovina sprememb…

  • spremenil: Gundolf ()

Gundolf ::

BTW, upam da sem vsaj približno zadel tipe spremenljivk :)

'FireSTORM' ::

ma saj ni važno, saj sem dojel bistvo kaj mi hočeš povedat, hvala za razlago
ko bom uredil sporočim da boš lahko ponosen da si me naučil nekaj:D
danes ziher ne ker počasi krenem, ju3 pa čist mogoče ;)
Those penguins.... They sure aint normal....

kopernik ::

Ja, preverjanje vnosov (raznorazni filtri) mora biti tako, kot je napisal gundolf, sicer se tiste if klobase razširijo v nekaj nerazpoznavnega že pri manj kot desetih poljih.

'FireSTORM' ::

malo se moram popravit

dokončal sem ta search danes :)
zdaj bom lahko mirno spal ;)
hvala za pomoč
Those penguins.... They sure aint normal....

Gundolf ::

Me veseli :)


Vredno ogleda ...

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

[bash] Sortiranje fotografij po datumu

Oddelek: Programiranje
101381 (942) Mike0
»

Python separiranje besed v stavkih

Oddelek: Programiranje
91049 (863) Meizu
»

ukazno programiranje

Oddelek: Programiranje
131553 (948) Greek
»

Nujna Pomoč ! C++

Oddelek: Programiranje
121161 (960) BigWhale
»

Bash izpis datotek

Oddelek: Programiranje
111394 (1216) BigWhale

Več podobnih tem