Složka algoritmus vyhledávání

hlasů
0

Není si jistý, jestli se jedná o obvyklý druh otázky, který se ptal tady, nebo jestli budu mít nějaké odpovědi na tento jeden, ale jsem hledal přístupu pseudo-kódu pro generování DB propojující záznamy z struktura složek, který obsahuje obrázek soubory.

Mám sadu složek, strukturované jako folllows:

+-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
  ...  ... ...  

V podstatě lze říci, že představuje možné fotografie pro vozidla tím, že rok, který začíná v roce 1999.

Značek a modelů (např Značka: Alfa Romeo, Model: 145) přicházejí v různých sklonů nebo verze. Každé čalounění, nebo verze lze nalézt v celé řadě vozidel, která bude vypadat stejně, ale mají říci rozdíly v druhu paliva a objemu motoru.

Chcete-li ušetřit zdvojování, struktura složek výše využívá výchozí složky ... A se zobrazuje na výchozí verzi z roku 2000. Musím vyrobit tabulky odkazy pro každou verzi - založený na tom, zda mají své vlastní naléhavé obrazy, nebo zda využít výchozí verzi ...

Tak například VERSION_1 nemá žádné obrazové soubory, takže jsem třeba, aby se odkazy na na výchozí obrazů, počínaje rokem 2000, a pokračující až do roku 2009.

Version 2 na druhé straně začíná s použitím výchozích obrazů v roce 2000, ale pak se používá dvě nové sady nejprve pro období 2001-2002, a poté 2003-2009. Seznam odkazů potřebných proto ...

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
...

(Výchozí hodnota je právě to - držitel místo a žádné odkazy jsou potřebné pro to.)

V tuto chvíli Běžím procházet složky, stavební pole, a pak ořezávání tuku na konci. Jen by mě zajímalo, jestli tam byl krátký střih, s použitím nějaké textové zpracování přístupu? Tam je asi 45,000 složky, z nichž většina jsou prázdné :-)

Položena 05/07/2009 v 21:43
zdroj uživatelem
V jiných jazycích...                            


1 odpovědí

hlasů
1

Zde je několik Python pseudocode, dost blízko na spustitelný soubor (potřebuje vhodné dovoz a DEF pro funkci writerow, který bude dělat skutečné psaní - ať už k přechodnému souboru, DB, CSV, cokoliv):

# 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)

Jeden nejednoznačnost v spec a například je, zda je možné, aby default_version změnit sadu souborů v některých letech - tady, já jsem za předpokladu, že se tak nestane (pouze určité verze změnit tímto způsobem, je výchozí verze vždy nese jednu sadu souborů).

Pokud toto není ten případ, co se stane v případě, že výchozí verze změny let (řekněme) 1999 a 2003, a změny version1 v letech 2001 a 2005 - jaké soubory by varianta 1 použít pro 03 a 04 novými ve výchozí verzi nebo těch, kterým je uvedeno v 01?

V nejsložitější verzi spec (kde oba default_version a konkrétní člověk může změnit, s nejnovější změny budou mít přednost, a je-li specifické i výchozí změna ve stejném roce pak specifický, který má přednost) je třeba, aby všechny „další změny rok“ sekvence, pro každou konkrétní verzi, opatrným „prioritní sloučení“ sekvencí změny let u třídy a konkrétní verzi, namísto pouhého použití years(sled změn v konkrétní verzi) jako já zde - a každá změna rok umístí v pořadí musí být spojena s příslušnou sadu souborů samozřejmě.

Takže v případě, že přesná specifikace může být vyjádřeno, prosím, až na případy kout, mohu ukázat, jak provést potřebné sloučení úpravou tohoto pseudocode - Raději bych dělat práci, dokud přesné specifikace jsou objasněny, protože v případě, že specifikace jsou skutečně jednodušší, práce by nepotřebné -!)

Edit : jako nový komentář vyjasnit přesné specifikace je skutečně velmi složitá, takže musíme dělat dělat sloučení odpovídajícím způsobem. Tak smyčky na konci zjednodušujícího odpovědi nad změnami:

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)

Klíčovou změnou je merged = dict(...podtrženo: v Pythonu, to znamená umožnit spojil nový dict (a dict je obecný mapování, bude typicky volal HashMap v jiných jazycích), což je částka, nebo sloučit, z default_versiona years_dict, ale když klíčem k úspěchu je přítomna v obou z nich, hodnota od years_dictpřednost - který splňuje klíčovou podmínku pro rok, který je k dispozici (tj je to rok se změnou souborů) v obojí.

Poté, že hračka: anydict.pop (somekey) vrátí hodnotu odpovídající klíče (a zároveň jej od anydict); min (anydict) vrátí minimální klíč slovníku. Všimněte si „sentinel“ idiom na merged[max_year + 1] = None: to říká, že rok „jeden po max jednom“ je vždy považována za změnu let (s fiktivní hodnotou zástupný nevznikla), takže poslední sada řádků je vždy správně napsaný (s maximální rok max_year + 1 - 1, který je přesně max_year, jak je požadováno).

Tento algoritmus není maximálně efektivní, jen nejjednodušší! Děláme min(merged)pořád dokola, takže je O (N SQUARED) - Myslím, že můžeme dovolit, protože každý mergedby měl mít několik desítek změnou roky na většinu, ale puristické by WinCE. Můžeme samozřejmě prezentovat (N logn) řešení je O - stačí roztřídit roky jednou provždy a chodit tuto sekvenci, aby si po sobě jdoucích hodnot next_change. Jen pro úplnost ...:

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

Zde sortedje uveden seznam s klávesami mergedv seřazeném pořadí, a já jsem přešel na forpříkazu k procházce tento seznam od začátku do konce (a jestli příkazy k výstupnímu nic poprvé projít). Hlídač je nyní dát do default_version (takže je mimo smyčku, na další mírné optimalizaci). Je to legrační vidět, že toto optimalizované verzi (v podstatě proto, že pracuje na mírně vyšší úrovni abstrakce) se ukáže být menší a jednodušší než předchozí ty ;-).

Odpovězeno 05/07/2009 v 22:57
zdroj uživatelem

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