Diskuze: Formátovanie veľmi dlhého textu

Python Python Formátovanie veľmi dlhého textu

Avatar
MLN
Člen
Avatar
MLN:

na tejto stránke je zadanie k domácej úlohe: http://python.input.sk/…mace/03.html

mám za úlohu naprogramovať funkciu ktorá sformátuje text podľa zadanej šírky, napr.:

string = '\nLorem ipsum dolor\n\n  sit      amet, consectetur adipiscing elit. Nullam pellentesque \n\n quis lacus in lacinia. \n\n\nPellentesque \n sapien odio,     fermentum id ante.'

z tohto stringu má vyhodiť zbytočné medzery, riadky, ale ponechať riadky v prípade keď sú 2 a viac vedľa seba pretože sa má zachovať odsek. Takže po úprave by mal string vyzerať takto:

string =  'Lorem ipsum dolor\n\nsit amet, consectetur adipiscing elit. Nullam pellentesque\n\nquis lacus in lacinia.\n\nPellentesque sapien odio, fermentum id ante.'

Naprogramoval som to tak, že cyklom som prešiel celý text. Ak prišiel na medzeru, tak ju vymaže iba v prípade, že predňou je tiež medzera alebo riadok, Ak nájde riadok, tak zistí počet riadkov od danej pozície, Ak je počet riadkov práve 1, tak sa tento riadok nahradí medzerou. Ak je počet riadkov 2, tak nieje o čom, preskočí ich. Ak je počet 3 a viac, tak prvé 2 nechá, ostatné vymaže. Tu je čo som naprogramoval:

#táto funkcia zistí počet riadkov od indexu kde je prvý riadok + vymaže medzery medzi nimi
def pocet_riadkov(text, index):
    pocet = 0
    while index < len(text) and (text[index] == ' ' or text[index] == '\n'):
        if text[index] == '\n':
            pocet += 1
            index += 1
        else:
            text = text[:index] + text[index+1:] #vymazanie medzery
    return pocet

#táto funkcia vymaže nepotrebné riadky + medzery v texte
def vymazNepotrebne(text):
    i = 0
    medzera = ' '
    riadok  = '\n'
    text = text.strip()
    while i < len(text):
        if text[i] == medzera:
            if text[i+1] == medzera or text[i+1] == riadok:
                text = text[:i] + text[i+1:] #vymaze sa
            else:
                i += 1
        elif text[i] == riadok:
            pocetRiadkov = pocet_riadkov(text, i)
            if pocetRiadkov == 1:
                if text[i+1] == medzera:
                    text = text[:i] + text[i+1:] #vymaze sa
                else:
                    text = text[:i] + medzera + text[i+1:]  #nahradenie riadka medzerou
                    i += 1
            if pocetRiadkov == 2:
                i += 2
            if pocetRiadkov >= 3:
                text = text[:i+2] + text[i+pocetRiadkov:]
                i += 2
        else:
            i+=1
    return text

dobre, to by sme mali, text máme teraz pekne premazaný, Ale teraz je potrebné do textu vložiť riadky podľa zadanej šírky. Ak máme teda tento string:

string =  'Lorem ipsum dolor\n\nsit amet, consectetur adipiscing elit. Nullam pellentesque\n\nquis lacus in lacinia.\n\nPellentesque sapien odio, fermentum id ante.'

a šírku riadka napr.:14, tak string má byť takýto:

string =  'Lorem ipsum\n
dolor
\n\n
sit amet,\n
consectetur\n
adipiscing\n
elit. Nullam\n
pellentesque
\n\n
quis lacus in\n
lacinia.
\n\n
Pellentesque\n
sapien odio,\n
fermentum id\n
ante.'

Naprogramoval som to takto:

#táto funkcia vloží riadky do textu podľa danej šírky riadka
def vlozRiadky(text, sirka):
    i = 0
    pocet = 0
    medzera = 0
    while i < len(text):
        if text[i] == ' ':
            medzera = i
        if pocet == sirka:
            pocet = -1
            if text[i:].find(' ') == 0:
                 text = text[:i] + '\n' + text[i+1:]
            else:
                text = text[:medzera] + '\n' + text[medzera+1:]
                i = medzera
        i += 1
        pocet += 1
    return text

#táto funkcia sformátuje text
def format(text, sirka):
    text = vymazNepotrebne(text)
    zaciatok = 0
    while zaciatok < len(text):
        odsek = text[zaciatok:].find('\n')
        if odsek != -1:
            substr = text[zaciatok:zaciatok + odsek]
            substr = vlozRiadky(substr, sirka)
            text = text[:zaciatok] + substr + text[zaciatok + odsek:]
            zaciatok += odsek + 2
        else:
            substr = vlozRiadky(text[zaciatok:len(text)], sirka)
            text = text[:zaciatok] + substr
            zaciatok = len(text)
    return text

Teda nájde pozíciu odseku, vyberie substring z pozície začiatok po index odseku, vloží tam riadky a substring naspäť vloží do textu. Toto opakuje pokým nepríde na koniec

Ďalej je potrebné naprogramovať funkciu ktorá zistí šírku textu, teda šírku najdlhšieho riadka, toto som naprogramoval:

def sirka(text):

    zaciatok = 0
    najdlhsi = 0
    koniec = False

    while koniec == False:

        riadok = text[zaciatok:].find('\n')
        if riadok != -1:
            dlzka = riadok
            if dlzka > najdlhsi:
                najdlhsi = dlzka
            if text[riadok+1] == '\n':
                posun = 2
            else:
                posun = 1
            zaciatok = zaciatok + riadok + posun
        else:
            koniec = True
            dlzka = len(text) - zaciatok
    return najdlhsi

Ešte funkciu na počet slov, musí byť rovnaký pred aj po preformátovaní:

def pocet_slov(text):
    pocet = 0
    i = 0
    zapocitane = False
    while i < len(text):
        if text[i] != ' ' and text[i] != '\n' and zapocitane == False:
            pocet +=1
            zapocitane = True
        if text[i] == ' ' or text[i] == '\n':
            zapocitane = False
        i += 1
    return pocet

Na koniec funkciu na zistenie najdlhšieho slova:

def najdlhsie_slovo(text):
    i = 0
    najdlhsie = ''
    slovo = ''
    pocetZnakov = 0
    maximum = 0
    while i < len(text):
        if text[i] != ' ' and text[i] != '\n':
            slovo += text[i]
            pocetZnakov += 1
        else:
            if pocetZnakov > maximum:
                maximum = pocetZnakov
                pocetZnakov = 0
                najdlhsie = slovo
                slovo = ''
            else:
                pocetZnakov = 0
                slovo = ''
        i += 1
    return najdlhsie

Dobre, všetko mi funguje, krásne naformátuje, ale musíme to odovzdať na jeden server kde sa to kontroluje a ten mi to nevyhodnotí ako správne pretože prekročí povolený časový limit. Takže je to strašne neefektívne. Moja otázka je, ako tie funkcie ZEFEKTÍVNIŤ. Nemôžem použiť funkciu split()

 
Odpovědět 19.10.2015 0:21
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 1 zpráv z 1.