tablica haszująca input

tablica haszująca input

Wątek przeniesiony 2021-03-30 18:50 z Algorytmy i struktury danych przez kq.

ArtS
  • Rejestracja:około 7 lat
  • Ostatnio:3 dni
  • Postów:32
0

Cześć, mam coś takiego. Nie rozumiem jak mają być pobierane dane z pliku wejściowego.
screenshot-20210330001907.png

Czy po prostu wczytujemy pierwszą linię czyli ilość przypadków testowych czyli 1? Następnie wczytujemy drugi wiersz czyli wielkość tablicy. Następnie wczytujemy kolejne wiersze i w zależności od tego czy w kolejnym wierszu pliku jest add czy print czy delete wykonuje się konkretna metoda w programie? W jaki sposób zaimplementować, aby np. przy sprawdzaniu 3 linii program wiedział, że ma wykonać dodawanie stringa ala na indeksie 3 (13%10) w mojej tablicy? Czy to jest coś trywialnego, bo googlam chyba nie tam gdzie trzeba. Równie dobrze może być:
1
size 10
add 13 ala
add 23 ola
...
stop
czyli inna kolejność. Może porobić if`y i niech sprawdza czy w konkretnej lini jest słowo kluczowe np. add, jeżeli tak to wykonaj dodanie stringa itd.?

Możliwe, że zupełnie źle to rozumiem także proszę o wyrozumiałość.

edytowany 1x, ostatnio: ArtS
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
4

Ale skąd my mamy znać polecenie które masz wykonać? o_O Możemy najwyzej zgadywać na podstawie tego pliku... Wygląda że masz zrobić prosty interpreter "kodu"

  • czytasz linię
  • parsujesz ją i sprawdzasz co oznacza taka "instrukcja"
  • wykonujesz zadana operacje

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
ArtS
  • Rejestracja:około 7 lat
  • Ostatnio:3 dni
  • Postów:32
0

Trzeba utworzyć tablicę z mieszaniem umożliwiającą przechowanie danych obiektu składającego się z klucza oraz stringa, a następnie mają się wykonać operacje zawarte w pliku. Nie rozumiem po prostu tego w jaki sposób program ma odczytać którą operację ma wykonać (czy add czy print czy delete) oraz jak pobrać dane np. klucz 13 oraz wartość "ala" i wstawić ją do tablicy - czy możemy w konkretnej linii pobrać tylko wartość po pierwszej spacji i po drugiej? Chodzi bardziej o samo działanie tablicy z mieszaniem niż interpreter i stąd moje pytania czy mój tok rozumowania jest ok.

Tak jak napisałeś, chyba trzeba wczytać całą linię jako stringa i jeżeli linia zawiera dane słowo kluczowe to wykonuje się konkretna operacja, ale zanim się wykona to trzeba wstawić klucz-wartość do tablicy. Pytanie czy można w jakiś łatwy sposób z pobranej linii wyłuskać 13 i ala? Teoretycznie w stringu "add 13 ala" można pobrać tylko znak 5 i 6 czyli 13 i przekonwertować na inta i tak samo z pobrać 3 ostatnie znaki czyli ala.

edytowany 1x, ostatnio: ArtS
ArtS
  • Rejestracja:około 7 lat
  • Ostatnio:3 dni
  • Postów:32
0

Chyba poszedłem w złym kierunku, bo teraz jak będę chciał wyświetlić wszystkie elementy tablicy to będę miał dostęp tylko do ostatnio dodanego. Oczywiście w metodzie add powinno być jeszcze zabezpieczenie na wypadek takich samych indeksów. Czy może mi ktoś podpowiedzieć jak to ugryźć?

Kopiuj
#include <iostream>
#include <fstream>
#include <map>

using namespace std;


void add(string t[], int w , long k, string ww);
void print(string t[], int w , long k, string ww);
//void delete();
//void stop();

int main()
{

    fstream pobierz;
    pobierz.open("test.txt");
    string linia_1;
    string linia_2;
    string linia_3;
    string linia_4;
    string linia_5;
    string linia_6;
    string linia_7;
    string linia_8;
    string linia_9;
    string linia_10;


    getline(pobierz, linia_1);
    int ilosc_przypadkow = stoi(linia_1);

    getline(pobierz, linia_2);
    string stablica = linia_2.substr(5,6);
    int wielkosc = stoi(stablica);
    //cout<<wielkosc;
    string*tablica= new string[wielkosc];

    getline(pobierz, linia_3);
    string wyrazenie = linia_3.substr(0,2);
    if (wyrazenie == "add")
        {
            string key_z = linia_3.substr(4,5);
            long key = stoi(key_z);
            string wartosc = linia_3.substr(7,9);
            add(tablica, wielkosc, key, wartosc);
            if (wyrazenie == "pri")
            {

                print(tablica, wielkosc, key, wartosc);
            }
          //if (wyrazenie == "del")
          //{

          //}
          //if (wyrazenie == "sto")
          //{

          //}

        }

}


     void add(string t[], int w, long k, string ww)
    {
     int indeks_1  = k%w;
     t[indeks_1] = ww;

    }

    void print(string t[], int w , long k, string ww)
    {
       for(int i = 0; i<10; i++)
        cout<<t[i];
    }
LukeJL
  • Rejestracja:około 11 lat
  • Ostatnio:minuta
  • Postów:8405
2

Pytanie czy można w jakiś łatwy sposób z pobranej linii wyłuskać 13 i ala?

w każdej linijce masz jakieś znaki oddzielone spacją.
Możesz więc (sposób ręczny) iterować po każdym znaku aż do spacji, wtedy pobierasz słowo np. "add" i zapamiętujesz je gdzieś, potem jedziesz dalej aż do kolejnej spacji i wyłuskujesz cyfry "13", potem iterujesz dalej i łapiesz "ola" (ale - przy delete 13 masz tylko dwa symbole).

Ale możesz użyć jakiejś gotowej funkcji, jeżeli taką masz w języku (wczoraj robiłem coś podobnego w JS i tam jest funkcja split do tego).

No i na podstawie tego, co masz w pierwszym symbolu (size, add, delete itp.) podejmujesz decyzję (np. if, switch), w jaki sposób się zachowasz dalej. Plus trzeba będzie skonwertować cyfry w stringu "13" na faktyczną liczbę 13.

Kopiuj
    string linia_1;
    string linia_2;
    string linia_3;
    string linia_4;
    string linia_5;
    string linia_6;

Ale po co tak? W C++ masz pętle, więc możesz zrobić jedną zmienną linia i potem iterować po kolejnych liniach i obsługiwać każdą linię tak samo.

Kopiuj
string stablica = linia_2.substr(5,6);

przecież to ci się rozwali za chwilę. Wystarczy, że zamiast 10, będziesz miał 100 :D

Kopiuj
  string key_z = linia_3.substr(4,5);

Też zakładasz, że coś będzie miało dwa znaki zawsze (o ile w ogóle ta funkcja tak działa? https://www.cplusplus.com/reference/string/string/substr/ ). Czyli robisz program do obsługi jedynego pliku (który się wywali przy każdym innym pliku, chyba, że jakimś cudem będzie miał linijki w znaki w tych samych miejscach). To chyba wygodniej byłoby w ogóle nie robić tego programu, tylko napisać po prostu

Kopiuj
cout << "ala";
cout << "ola";

na to samo by wyszło w tym momencie...


edytowany 8x, ostatnio: LukeJL
ArtS
  • Rejestracja:około 7 lat
  • Ostatnio:3 dni
  • Postów:32
0

Przerobiłem wszystko. Utknąłem, bo w pętli nie jest przekazywany adres do tablicy Tabp oraz size. Pórbowałem z wskaźnikam, ale bez skutku ;/
Jeżeli chodzi o operacje na stringu to póki co łopatologicznie, potem zrobię myk z białym znakiem.

Kopiuj
#include <iostream>
#include <fstream>
#include <map>

using namespace std;


void Add(string T[], int r, long k, string w);
//void print();
//void delete();
//void stop();



int main()
{
    string linie;
    int licznik = 0;
    ifstream policz("test.txt");
    while(getline(policz, linie))
        licznik++;
    policz.close();



    string * Tabp = new string[licznik];
    fstream plik;
    plik.open("test.txt");
    string wiersz;

    for (int b =0; b<licznik; b++)
    {
        getline(plik, wiersz);
        Tabp[b] = wiersz;
    }

    string iloscprzypadkow = Tabp[0].substr(0);
    int n = stoi(iloscprzypadkow);

    string rozmiarstring = Tabp[1].substr(5,7); 
    int size = stoi(rozmiarstring);
    string * Tabh = new string[size];


    for (int ite=2; ite<licznik; ite++)
        if (Tabp[ite].substr(0) == "a")
        {
            cout <<Tabp[2]; //TEST: nie wyswietla się czyli problem z zasięgiem. Kombinowałem z wskaźnikami, ale nie mogę rozkminić czemu nei działa
            cout <<size;  //TEST_2: nie wyswietla się czyli problem z zasięgiem Kombinowałem z wskaźnikami, ale nie mogę rozkminić czemu nei działa
            string temp = Tabp[ite].substr(4,5);
            long klucz = stoi(temp);

            string wartosc = Tabp[ite].substr(7,14);


            Add(Tabh, size, klucz, wartosc);

        }
        //if (wyrazenie == "p")
        //{

        //}
        //if (wyrazenie == "d")
        //{

        //}
        //if (wyrazenie == "s")
        //{

}
    void Add(string Tabh[], int rozmiar, long klucz, string wartosc)
    {

        cout<<rozmiar<<klucz<<wartosc;
    int indeks = klucz%rozmiar;
    Tabh[indeks] = wartosc;

    cout<<indeks<<" "<<klucz<<" "<<wartosc;

    }

Ma ktoś pomysł co robię nie tak? ;/

edytowany 4x, ostatnio: kq
ArtS
  • Rejestracja:około 7 lat
  • Ostatnio:3 dni
  • Postów:32
0

Hej, głupi błąd, zamiast if (Tabp[ite].substr(0) == "a") powinno być if (Tabp[ite].substr(0,1) == "a")```
Teraz mam problem jak wyświetlić klucz oraz indeks elementu tablicy w metodzie print. Podpowie ktoś?

Kopiuj
#include <iostream>
#include <fstream>


using namespace std;

void Add(string T[], int r, long k, string w);
void Print(string Print[], int size);

//void delete();
//void stop();

int main()
{
   string linie;
   int licznik = 0;
   ifstream policz("test.txt");
   while(getline(policz, linie))
         licznik++;
   policz.close();

   string * Tabp = new string[licznik];
   fstream plik;
   plik.open("test.txt");
   string wiersz;

   for (int b =0; b<licznik; b++)
   {
         getline(plik, wiersz);
         Tabp[b] = wiersz;
   }

   string iloscprzypadkow = Tabp[0].substr(0);
   int n = stoi(iloscprzypadkow);

   string rozmiarstring = Tabp[1].substr(5,7);
   int size = stoi(rozmiarstring);
   string * Tabh = new string[size];

   for (int ite=2; ite<licznik; ite++)
   {
            if (Tabp[ite].substr(0,1) == "a")
            {
               string temp = Tabp[ite].substr(4,5);
               long klucz = stoi(temp);
               string wartosc = Tabp[ite].substr(7,14);
               Add(Tabh, size, klucz, wartosc);
            }
            if (Tabp[ite].substr(0,1) == "p")
            {

               Print(Tabh, size);

            }
    }
          //if (wyrazenie == "d")
          //}
          //{
          //if (wyrazenie == "s")
          //{
          //}

}

void Add(string Tabh[], int rozmiar, long klucz, string wartosc)
{

int indeks = klucz%rozmiar;
    if (Tabh[indeks] == "")
        {
        Tabh[indeks] = wartosc;

        }
    else
        {
        Tabh[indeks+1] = wartosc;

        }

}

void Print(string Tabh[], int size)
{
    for (int e=0; e<size; e++)
    cout<<indeks<<klucz<<Tabh[e];
}



edytowany 1x, ostatnio: ArtS
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
  • Nie musisz magazynować danych w pamięci
  • Nie musisz używać dziwnych substr.
  • Radze zrobić to po ludzku
Kopiuj
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

struct Record {  int number; string text; };
struct TestData {  size_t capacity,size; Record *tb; }; // lepiej użyć wektora zamiast całej TestData

typedef void Executer(TestData &data,istream &is);

void executeSize(TestData &data,istream &is)
{
   int capacity;
   is>>capacity;
   data.tb=new Record[capacity]; // lepiej użyć wektora zamiast całej TestData, tu będzie reserve(capacity)
}

void executeAdd(TestData &data,istream &is)
{
   int number;
   string text;
   is>>number>>ws>>text;
   // zrobić dodawanie
}

void executePrint(TestData &data,istream &is)
{
   for(int i=0;i<data.capacity;++i) cout<<data.tb[i].number<<' '<<data.tb[i].text<<endl;
}

void executeDelete(TestData &data,istream &is)
{
   int number;
   is>>number;
   // zrobić usuwanie
}

void executeStop(TestData &data,istream &is)
{
   delete[] data.tb; // lepiej użyć wektora zamiast całej TestData, tu będzie zwyczajnie NIC!
}

struct { string key; Executer executer; } map[]=
{
   {"size",executeSize},
   {"add",executeAdd},
   {"print",executePrint},
   {"delete",executeDelete},
   {"stop",executeStop},
};

int main()
{
   ifstream file("test.txt");
   int tests;
   for(file>>tests;tests--;)
   {
     TestData data;
     string word;
     file>>ws>>word;
     for(int i=0;i<sizeof(map)/sizeof(*map);++i) if(word==map[i].key) map[i].executer(data,file);
   }
   return 0;
}

Uwaga pisane na kolanie, więc mogą być drobne błędy.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
edytowany 1x, ostatnio: _13th_Dragon
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)