Folder kereső algoritmus

szavazat
0

Nem biztos, hogy ez a szokásos fajta kérdés, amelyet a kért errefelé, vagy ha hozok semmilyen választ, hogy ez egy, de keresem a pszeudo-kód megközelítést generáló DB nyilvántartások összekapcsolásával egy mappa struktúra tartalmazó kép fájlokat.

Van egy mappakészletük felépítésű osztandók:

+-make_1/
  | +--model_1/
  |    +-default_version/
  |    |   +--1999
  |    |   +--2000
  |    |   |   +--image_01.jpg
  |    |   |   +--image_02.jpg
  |    |   |   +--image_03.jpg
  |    |   |   ...
  |    |   +--2001
  |    |   +--2002
  |    |   +--2003
  |    |   ...
  |    |   +--2009
  |    +--version_1/
  |    |   +--1999
  |    |   ...
  |    |   +--2009
  |    +--version_2/
  |    |   +--1999
  |    |   +--2000
  |    |   +--2001
  |    |   |   +--image_04.jpg
  |    |   |   +--image_05.jpg
  |    |   |   +--image_06.jpg
  |    |   |   ...
  |    |   +--2002
  |    |   +--2003
  |    |   |   +--image_07.jpg
  |    |   |   +--image_08.jpg
  |    |   |   +--image_09.jpg
  |    |   ...
  |    |   +--2009
  ...  ... ...  

Lényegében azt jelenti lehet képeket a járművek számára, az év 1999-től kezdve.

Teszi és modellek (pl Gyártmány: Alfa Romeo, Típus: 145) jönnek a különböző kárpitok vagy változatok. Minden berendezés, vagy verzió megtalálható a járművek száma, amely ugyanúgy néz ki, de van mondjuk a gázolaj típusú vagy a motor lökettérfogata.

Ha menteni párhuzamos, a mappa szerkezet felett él egy alapértelmezett mappa ... És a képek jelennek meg az alapértelmezett verzió 2000-től. Azt kell termelni a linkeket táblázatot minden egyes verzió - attól függően, hogy a saját nyomós képeket, vagy akár kihasználják az alapértelmezett verzió ...

Így például, VERSION_1 nincs kép fájlokat, így azt kell, hogy linkeket az alapértelmezett kép, 2000-től kezdve 2009-ig folytatódik.

2. verzió másrészt indul ki az alapértelmezett kép 2000-ben, de aztán használja a két új sorozat első 2001-2002, majd 2003-2009. A linkek listáját szükséges, ezért ...

version    start     end   file_name
=======    =====   =====   =========
version_1   2000    2009   image_01.jpg
version_1   2000    2009   image_02.jpg
version_1   2000    2009   image_03.jpg
...
version_2   2000    2001   image_01.jpg
version_2   2000    2001   image_02.jpg
version_2   2000    2001   image_03.jpg
version_2   2001    2003   image_04.jpg
version_2   2001    2003   image_05.jpg
version_2   2001    2003   image_06.jpg
version_2   2003    2009   image_07.jpg
version_2   2003    2009   image_08.jpg
version_2   2003    2009   image_09.jpg
...

(Alapértelmezett csak, hogy - egy hely, és nem kapcsolatra van szükség rá.)

Abban a pillanatban én fut át ​​a mappát, az épület tömbök, majd levágja a zsír a végén. Én csak gondoltam, ha van egy rövidebb utat, használ valamilyen szövegfeldolgozó megközelítés? Jelenleg mintegy 45.000 mappák, amelyek többsége üres :-)

A kérdést 05/07/2009 21:43
a forrás felhasználó
Más nyelveken...                            


1 válasz

szavazat
1

Itt van néhány Python pszeudokódokra, elég közel végrehajtható (szükségleteinek megfelelő import és a def egy writerow funkció, amely nem a tényleges írás - legyen szó akár egy köztes fájlt, DB, CSV, bármi):

# first, collect all the data in a dict of dicts of lists
# first key is version, second key is year (only for non-empty years)

tree = dict()
for root, dirs, files in os.walk('make_1/model_1'):
    head, tail = os.path.split(root)
    if dirs:
       # here, tail is a version
       tree[tail] = dict
    elif files:
       # here, tail is a year
       tree[os.path.basename(head)][tail] = files

# now specialcase default_version
default_version = tree.pop('default_version')
# determine range of years; rule is quite asymmetrical:
#   for min, only years with files in them count
min_year = min(d for d in default_version if default_version[d])
#   for max, all years count, even if empty
max_year = max(default_version)

for version, years in tree.iteritems():
    current_files = default_version[min_year]
    years.append(max_year + 1)
    y = min_year
    while years:
        next_change = min(years)
        if y < next_change:
            for f in current_files:
                writerow(version, y, next_change-1, f)
        y = next_change
        current_files = years.pop(y)

Egy kétértelműséget a spec, és például az, hogy ez lehetséges, a default_version változtatni a sor fájlokat néhány évben - itt felteszem, hogy nem történik meg (csak a konkrét változat változtatni, hogy így, az alapértelmezett verzió mindig magában hordozza egy készlet fájlok).

Ha ez nem így van, mi történik, ha az alapértelmezett verzió változások éve (mondjuk) 1999-ben és 2003-ban és 2001-ben kivitelnél1 változások és 2005 - milyen fájlokat kell változat 1 felhasználás 03 és 04, az újakat az alapértelmezett verzió vagy az általa meghatározott 01?

A legbonyolultabb változatát spec (ahol mindkét default_version és specifikus lehet változtatni, a legutóbbi változás elsőbbségadás, és ha mind a specifikus és az alapértelmezett változás ebben az évben, akkor az adott szedési részesítendő) az egyik kell, hogy az összes „következő változás éve” sorozat, minden egyes változat, óvatos „prioritási összevonása” szekvenciák változás év alapértelmezett és egyedi változata, ahelyett, hogy csak a years(szekvencia változások a specifikus változat), mint én itt - és minden változást évente helyezni a sorrendben kell társítani a megfelelő sor fájlokat természetesen.

Tehát, ha a pontos specifikációt is kérem kifejezhető, egészen a sarokba esetekben tudom mutatni, hogyan kell csinálni a szükséges egyesülő módosításával ezt pszeudokódokra - Inkább nem azt a munkát, amíg a pontos specifikációk tisztázni, mert ha a szemüveg valóban egyszerűbb a munka lenne felesleges! -)

Szerkesztés : mint egy új hozzászólást tisztázni, hogy pontosan szemüveg valóban a legbonyolultabb, ezért meg kell tennünk ezt az egyesülő megfelelően. Tehát a ciklus végén a leegyszerűsített válasz fenti módosítások:

for version, years_dict in tree.iteritems():
    # have years_dict override default_version when coincident
    merged = dict(default_version, **years_dict)
    current_files = merged.pop(min_year)
    merged[max_year + 1] = None
    y = min_year
    while merged:
        next_change = min(merged)
        for f in current_files:
            writerow(version, y, next_change-1, f)
        y = next_change
        current_files = merged.pop(y)

A legfontosabb változás a merged = dict(...sort: Python, ez azt jelenti, hogy győződjön egyesült új dict (a dict generikus feltérképezése, ami jellemzően úgynevezett HashMap más nyelveken), amely az összeg, vagy összeolvad, az default_versionés years_dict, de ha egy kulcs egyaránt jelen van az említett, az értéket years_dictelőnyben -, amely megfelel a legfontosabb feltétele egy évre, ami jelen (azaz egy év a változás a fájlok) mindkettő.

Ezután ez sima vitorlázás: anydict.pop (somekey) visszaadja a megfelelő értéket a legfontosabb (és eltávolítja azt a anydict); min (anydict) visszatér a minimális kulcsot a szótárban. Megjegyzés: A „sentinel” idióma meg merged[max_year + 1] = None: ez azt mondja, hogy az év „egymás után max egy” mindig kell tekinteni a változás éve (dummy helykitöltő értéke None), úgy, hogy az utolsó sor a sorok mindig írva helyesen (maximum év max_year + 1 - 1, azaz pontosan max_year, ahogy szükséges).

Ez az algoritmus nem maximálisan hatékony, csak a legegyszerűbb! Csinálunk min(merged)újra és újra, ami O (N négyzeten) - Azt hiszem, magának, mert minden mergedkell egy pár tucat change-éves időszakra, de purista lenne összerezzen. Tudjuk persze bemutatni egy O (N logN) megoldás - csak rendezni az évek, egyszer és mindenkorra, és gyalog, hogy a sorozatot, hogy az egymást követő értékei next_change. Csak a teljesség kedvéért ...:

default_version[max_year + 1] = None

for version, years_dict in tree.iteritems():
    merged = dict(default_version, **years_dict)
    for next_change in sorted(merged):
        if next_change > min_year:
            for f in merged[y]:
                writerow(version, y, next_change-1, f)
        y = next_change

Itt sortedad egy listát a kulcsokat a mergedrendezett sorrendben, és én váltottunk, hogy a fornyilatkozat járni, hogy a listát az elejétől a végéig (és ha nyilatkozatok kiadási semmi először át). A sentinel most hozott default_version (így kívül a hurok, egy másik kis optimalizálás). Vicces látni, hogy ez optimalizált változatát (lényegében, mert működik egy kicsit magasabb absztrakciós szinten) kiderül, hogy kisebb és egyszerűbb, mint a korábbiak ;-).

Válaszolt 05/07/2009 22:57
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more