zbiór słów"

NI
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:535
0

Zawsze gdy miałem w programie zbiór dostępnych słów był to wektor stringów. Przy paru wyrazach nie ma problemu ale przy paru tysiącach już jest... Spróbowałem to zrobić bez wektora i wyszło mi takie coś:
types.h

Kopiuj
#ifndef TYPES_H
#define TYPES_H

#include<cstdlib>
#include<iostream>

struct Alphabet
{
    char letters[2][26];
    Alphabet();
    Alphabet(const Alphabet & target);
    ~Alphabet();
};

class StringMap
{
    StringMap**cells;
    unsigned int number;
public:
    void add(std::string source,Alphabet alph);
    bool contains(std::string source,Alphabet alph);
    StringMap();
    StringMap(const StringMap & target);
    ~StringMap();
};

#endif // TYPES_H
 

types.cpp

Kopiuj
#include "types.h"

Alphabet::Alphabet()
{
    for (unsigned short i=0; i<26; i++)
    {
        letters[0][i]='a'+i;
        letters[1][i]='a'+i;
    }
}

Alphabet::Alphabet(const Alphabet & target)
{
    for (unsigned short i=0; i<26; i++)
    {
        letters[0][i]=target.letters[0][i];
        letters[1][i]=target.letters[1][i];
    }
}

Alphabet::~Alphabet(){}

void StringMap::add(std::string source,Alphabet alph)
{
    if (!contains(source,alph))
    {
        StringMap*next=this;
        int num=0;
        for (unsigned int i=0; i<source.size(); i++)
        {
            num=-1;
            for (unsigned short j=0; j<26; j++)
            {
                if (alph.letters[0][j]==source[i])
                {
                    num=j;
                    break;
                }
                else if (alph.letters[1][j]==source[i])
                {
                    num=26+j;
                    break;
                }
            }
            if (num==-1)
                break;
            if (next->cells[num]!=NULL)
            {
                next->cells[num]->number++;
            }
            else
                next->cells[num]=new StringMap;

            next=next->cells[num];
        }
    }
}

bool StringMap::contains(std::string source,Alphabet alph)
{
    int num=0;
    unsigned int pos=0;
    StringMap * next=this;
    for (unsigned int i=0; i<source.size(); i++)
    {
        num=-1;
        for (unsigned int j=0; j<26; j++)
        {
            if (alph.letters[0][j]==source[i])
            {
                num=j;
                break;
            }
            else if (alph.letters[1][j]==source[i])
            {
                num=j+26;
                break;
            }
        }
        if (num==-1)
            break;
        if (next->cells[num]==NULL)
        {
            return false;
        }
        next=next->cells[num];
        pos=next->number;
    }
    for (unsigned int i=0; i<52; i++)
        if (next->cells[i]!=NULL and next->cells[i]->number==pos)
            return false;
    return true;
}

StringMap::StringMap()
{
    cells=new StringMap*[52];
    for (unsigned int i=0; i<52; i++)
        cells[i]=NULL;
    number=0;
}

StringMap::StringMap(const StringMap & target)
{
    cells=new StringMap*[52];
    for (unsigned int i=0; i<52; i++)
    {
        if (target.cells[i]!=NULL)
        {
            cells[i]=new StringMap(*target.cells[i]);
        }
        else
            cells[i]=NULL;
    }
}

StringMap::~StringMap()
{
    for (unsigned short i=0; i<52; i++)
        if (cells[i]!=NULL)
            delete cells[i];
    delete[] cells;
} 

niestety pojawiają się losowe błędy, na przykład mówi że nie ma jakiegoś słowa gdy wiele słów nachodzi na nie(w całości) albo mówi, że jakieś jest, mimo że nie zostało dodane. Nie wiem gdzie jest błąd, kod piszę od nowa 3 raz z tym samym efektem.


Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
edytowany 2x, ostatnio: Niikelion
SO
  • Rejestracja:ponad 10 lat
  • Ostatnio:12 miesięcy
2

Może zacznijmy od tego co chcesz osiągnąć, bo zdaje mi się, że do przechowywania zbioru słów wystarczy unordered_set.

NI
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:535
0

wiem, że już ktoś coś potrzebnego do tego zrobił, ale nie chcę korzystać z gotowca


Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
edytowany 1x, ostatnio: Niikelion
kq
to wróćmy do tego co chesz osiągnąć.
NI
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:535
0

Chcę doprowadzić moją klasę do stanu używalności-usunąć błędy związane z szukaniem(a przynajmniej mnie się tak wydaje, że to błędy szukania a nie zapisywania)


Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
stryku
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad rok
  • Postów:607
2

Wiem, że nie prosiłeś o to, ale takie rzeczy wyłapałem.

Kopiuj
for (unsigned short i=0; i<52; i++)

użycie unsigned short w takim miejscu jest żadną optymalizacją, a nawet może spowolnić program bo np. na x86 jeżeli są wykonywane jakieś operacje na "zmiennych" dwu bajtowych to w kodzie maszynowym do kodu operacji dodawany jest dodatkowy bajt prefiksu (0x80 jeżeli dobrze pamiętam), więc rozkaz jest dłuższy => procesor dłużej go wczytuje i wykonuje.
Używanie takich optymalizacji wykonuje się tylko jeżeli bardzo zależy Ci na pamięci. Tu to chyba przesada.

Niekonsekwencja. Jak już używasz unsighed short to używaj wszędzie tam gdzie można.

Nie rozumiem idei struktury Alphabet. W konstruktorze masz

Kopiuj
for (unsigned short i=0; i<26; i++)
    {
        letters[0][i]='a'+i;
        letters[1][i]='a'+i;
    }

Czyli tworzysz dwie tablice z małymi literami. (tak w ogóle to może to jest przyczyną błędów bo po copypajście linijki zapomniałeś zmienić na 'A' :p i Ci program nie ogarnia dużych liter)

Mimo wszystko idei nie rozumiem. Bo potem robisz takie cudo

Kopiuj
for (unsigned int j=0; j<26; j++)
        {
            if (alph.letters[0][j]==source[i])
            {
                num=j;
                break;
            }
            else if (alph.letters[1][j]==source[i])
            {
                num=j+26;
                break;
            }
        }

Czyli porównujesz kolejny znak słowa z kolejnym znakiem alfabetu małymi i dużymi i przypisuje do num małą wersję znaku (chyba). I za nic nie ogarnę po co ten cały alfabet. Czemu nie zrobisz tak

Kopiuj
for (char c = 'a'; c <= 'z'; ++c)
        {
            if (source[i] == c)
            {
                num=j;
                break;
            }
            else if (source[i] == c - 32)
            {
                num=c + 32; //czemu tu bylo 26?
                break;
            }
        }

Tyle że to dalej lipa bo ta pętla tu tylko zawadza

Kopiuj
if( isalpha( source[i] ) )
    num = tolower( source[i] );

A tak już w ogóle to wydaje mi się, że chcesz zaimplementować coś w stylu drzewa Trie (https://en.wikipedia.org/wiki/Trie). Czemu nie skorzystasz z jakiejś gotowej implementacji?

A tak już w ogóle, w ogóle to na prawdę warto się męczyć dla tych paru KB RAMu zamiast użyć unordered_set?

edytowany 2x, ostatnio: stryku
_13th_Dragon
implementacja Trie - daje naprawdę świetne wyniki, 10-krotnie mniejszy (albo i lepiej) rozmiar w pamięci niż mapa, wszystko zależy od ilości słów.
stryku
@_13th_Dragon Ja wiem, ale @Niikelion pisał o paru tysiącach, więc wątpie, żeby zabawa z Trie była w tym przypadku opłacalna
_13th_Dragon
Przy paru tysiącach może już zacząć być opłacalna, przy sensownej budowie tego Trie oczywiście.
NI
faktycznie to short nie wiele daje, a o tym że może spowalniać to nie wiedziałem :)
NI
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:535
0

To short to tak z automatu walnąłem :) Struktura Alphabet jest dlatego, że używam różnych alfabetów np polski lub niemiecki

Kopiuj
Alphabet alph;
alph.letters[0][numer]//podstawowe litery,np a ,b ,c itd, najczęściej zwyczajny angielski alfabet
alph.letters[1][numer]//dodatkowe litery ą,ć,ł itd,najczęściej dodatkowe litery, które nie zmieściły się w podstawowej części  

Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
NI
  • Rejestracja:około 11 lat
  • Ostatnio:prawie 5 lat
  • Lokalizacja:Warszawa
  • Postów:535
0

Sprawdziłem dokładniej co nie działa i zauważyłem, że problem pojawia się w tedy, kiedy dodaję nowe słowo, które jest częścią innego, losowy przykład:

Kopiuj
eloo//dodaje
 elo//dodaje
el//wykrywa jako dodane, jak dodam poprzednie słowa w odwrotnej kolejności to nie ma problemu 

Programuje i programuje ,przychodzi człowiek "o niższej inteligencji" i rok pracy zmarnowany
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)