Program haszujący + biblioteka słów

Odpowiedz Nowy wątek
2012-02-29 21:28

Rejestracja: 8 lat temu

Ostatnio: 5 lat temu

0

Witam... Nie za bardzo ogarniam sie w c++ , więc jeżeli mógłbym prosić uniżenie o pomoc to by bylo super :D...
Otóż mam do napisania program haszujacy z bazą słów + hasło które użytkownik wpisze. Już kij z tym że tablica ma byc max 100 elementowa i każdy element w indeksie ma być listą. z tym chyba sobie poradzę... ale nie umiem ogarnąć jak ta baza słów(która u mnie jest wczytywana z pliku do stringa) ma zostać zhaszowana... ogólnie mam problem z funkcją gdzie program ma za zadanie zrobić z każdego słowa w bazie hasz i dalej ten hasz wpisać do wyżej wymienionej tablicy(a jesli już taka liczba istnieje to wpisać jako kolejny element listy)... Innymi słowy string zamienić na wiele małych stringów i z kazdego z nich po kolei ma wyliczyć hasze... Jak to zrobić? Zaznaczam że nie ogarniam C, nie ogarniam (jeszcze) list i jestem na poziomie,erm...struktur? Taa... także klasy też mi obce..
Na razie mam to(czyt.jeden wielki chaos):

#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream> 
using namespace std;
int liczba;
wchar_t tab[]=
    {
        '?','/','.','>','<',',','M','N','B','V',
        'C','X','Z','A','S','D','F','G','H','J',
        'K','L',';',':','"','|',']','}','{','[',
        'P','O','I','U','Y','T','R','E','W','Q',
        '+','=','-','_','0',')','(','9','*','8',
        '%','5','4','$','3','#','@','2','!','1',
        '~','`','q','w','e','r','t','y','u','i',
        'o','p','a','s','d','f','g','h','j','k',
        'l','z','x','c','v','b','n','m','&','7',
        '6','^',
    };
typedef struct{
        wchar_t tab[S]; //moze byc tez char
        int dl;
        string p;
}struktura;
string slowa()//moja biblioteka ktora jest wczytywana z pliku
{
    string slowa;
    fstream plik("nazwa.txt",ios::in); //(nazwa umieszczona w folderze z kodem źródłowym)
    getline(plik, slowa);//( w nawiasach kolejno: argument z którego są zczytywane dane, zmienna do ktorej są wczytywane dane)
    void close(void);
    return slowa;
}
struktura strpassword()
{
            struktura strpassword;
            cout<<"\nPlease enter your password: ";
            cin>>strpassword.p;
            return strpassword;
}
int encryptor(struktura strpassword)
{
    struktura nowatab;
    int sumakontrolna=0;
    for(int i=0;i<strpassword.p.length();i++)
        nowatab.tab[i]=0;
    for(int j=0; j<strpassword.p.length();j++)
        for(int i=0;i<92;i++)
            if(strpassword.p[j]==tab[i])
                nowatab.tab[j]=i;//kodowanie hasla
    for(int i=0;i<strpassword.p.length();i++)
        sumakontrolna=sumakontrolna+nowatab.tab[i]; //obliczanie sumy kontrolnej
    if(sumakontrolna>100)
        do
            sumakontrolna=sumakontrolna%2;
        while(sumakontrolna>100); //przycinanie sumy kontrolnej do 100 żeby tablica nie urosła
    return sumakontrolna;
}
void strcpy(char *zrodlo)
{
    struktura strpassword;
    int suma;
    bool wyr=false;
    for(;*zrodlo;++zrodlo) // pętla znak po znaku ze źródła
    {
    if(*zrodlo!=' ') // jeżeli nie spacja
    {
        if(!wyr) // jeżeli to pierwsza litera słowa
        {
            if(suma*suma++=' ') 
            {
                wyr=true; // już jesteśmy w słowie
                *zrodlo=strpassword.p;
                struktura nowatab;
                int sumakontrolna=0;
                for(int i=0;i<strpassword.p.length();i++)
                    nowatab.tab[i]=0;//zerowanie nowataba...bo by były krzaki...
                for(int j=0; j<strpassword.p.length();j++)
                    for(int i=0;i<92;i++)
                        if(strpassword.p[j]==tab[i])
                            nowatab.tab[j]=i;//kodowanie hasla
                for(int i=0;i<strpassword.p.length();i++)
                    sumakontrolna=sumakontrolna+nowatab.tab[i]; //obliczanie sumy kontrolnej
                if(sumakontrolna>100)
                    do
                        sumakontrolna=sumakontrolna%2;
                    while(sumakontrolna>100); //przycinanie sumy kontrolnej do 100 żeby tablica nie urosła
            }

        }
    else wyr=false; // już jesteśmy pomiędzy słowami
    }

}
int main()
{
    cout<<"############################################"<<endl;
    cout<<"   ###    PASSWORD ENCRYPTOR(1)   ###       "<<endl;
    cout<<"   ###     HASH DECRYPTOR(2)      ###       "<<endl;
    cout<<"   ###      SEEK & FIND (3)       ###       "<<endl;
    cout<<"   ###          EXIT(0)           ###       "<<endl;
    void strcpy(string *zrodlo,char *suma);
    char suma[100];
    cin>>liczba;
    switch(liczba)
    {
    case 1: 
        {
            system("CLS");
            cout<<"### PASSWORD ENCRYPTOR ###\n\n"<<endl;
            cout<<"initializing encryption stream # .......\n"<<endl;
            system("PAUSE");
            encryptor(strpassword());
            strcpy(slowa,suma);
        }
    case 2:
            {
                cout<<"### PASSWORD DECRYPTOR ###\n\n";
                system("PAUSE");
                system("CLS");
            }
    case 3: 
        {
            cout<<"#########   SEEK & FIND  ################"<<endl;
            return main();
        }
    case 0: break;
    default: cout<<"jeszcze raz..."<<endl;
    }

    return 0;
}

Już nie patrzeć na te wchar_t... akurat szybkość wykonywania i wielkość najmniej mnie interesują...eh..

edytowany 2x, ostatnio: red1791, 2012-02-29 21:34

Pozostało 580 znaków

2012-02-29 21:51

Rejestracja: 12 lat temu

Ostatnio: 1 godzina temu

0

Google się zepsuło?
http://pl.wikipedia.org/wiki/Tablica_mieszaj%C4%85ca


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2012-02-29 22:58

Rejestracja: 8 lat temu

Ostatnio: 1 rok temu

0

spuść z tonu. Dużo linijek nadźgałeś i nie chce mi się tego całego analizować, ale wystarczy, że spojrzałem i wiem, że na pewno da sie to napisać 2/3 razy mniejszą ilością linijek.
Czyli te funkcje haszujące działają? Jeżeli tak, to dlaczego nie zrobisz sobie jakiejś struktury pomocniczej w main, którą przekazujesz przez referencje do funkcji i nie zapisujesz w niej wyniku?
Napisz dokładnie jak brzmi treść zadania które dostałeś.

edytowany 1x, ostatnio: kopernik, 2012-02-29 23:10

Pozostało 580 znaków

2012-03-01 11:16

Rejestracja: 8 lat temu

Ostatnio: 5 lat temu

0
kopernik napisał(a)

spuść z tonu. Dużo linijek nadźgałeś i nie chce mi się tego całego analizować, ale wystarczy, że spojrzałem i wiem, że na pewno da sie to napisać 2/3 razy mniejszą ilością linijek.
Czyli te funkcje haszujące działają? Jeżeli tak, to dlaczego nie zrobisz sobie jakiejś struktury pomocniczej w main, którą przekazujesz przez referencje do funkcji i nie zapisujesz w niej wyniku?
Napisz dokładnie jak brzmi treść zadania które dostałeś.

Duzą ilość linijek nadźgałem bo musiałem jakoś drugi raz koło wymyśleć... Ogólnie sama funkcja haszująca działa. Nie działa przekazanie wyniku tej funkcji dalej... Ale to będę dalej pisać i w razie czego poproszę o pomoc :) Głównie problemem jest przekazanie całej biblioteki haseł do funkcji haszującej, które dalej zostaną przypisane do odpowiedniego indeksu tablicy zawierającej te hasze,a jeżeli istnieje już na danym indeksie tablicy hasło, to przez listę dopisanie dalej tego hasła... A zadanie brzmi mniej więcej tak, że mam stworzyć funkcję haszującą która zapisuje wyniki do tabeli z listami na poszczególnych indeksach, do tego mam stworzyć funkcję wyszukiwania i usuwania haseł z tablicy. Tak to mniej więcej wygląda...

Pozostało 580 znaków

2012-03-02 11:16

Rejestracja: 8 lat temu

Ostatnio: 5 lat temu

0

Troszkę poprawiłem kod(teraz mi wczytuje i zapisuje do tablicy to co użytkownik podaje) ale nadal mam problem z tą tablicą list... nie wiem jak to poprawnie zaimplementować... Byłbym bardzo wdzięczny za każdą pomoc...


#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int S=500,Q=200;
wchar_t tab[]=
{
'?','/','.','>','<',',','M','N','B','V',
'C','X','Z','A','S','D','F','G','H','J',
'K','L',';',':','"','|',']','}','{','[',
'P','O','I','U','Y','T','R','E','W','Q',
'+','=','-','_','0',')','(','9','*','8',
'%','5','4','$','3','#','@','2','!','1',
'~','`','q','w','e','r','t','y','u','i',
'o','p','a','s','d','f','g','h','j','k',
'l','z','x','c','v','b','n','m','&','7',
'6','^',
};
typedef struct
{
    char tab[S]; //moze byc tez char
    string p;
    char hasz[Q];
}struktura;
string slowa()
{
    string slowa;
    fstream plik("nazwa.txt",ios::in); //(nazwa umieszczona w folderze z kodem źródłowym)
    getline(plik, slowa);//( w nawiasach kolejno: argument z którego są zczytywane dane, zmienna do ktorej są wczytywane dane)
    void close(void);
    return slowa;
}
string strpassword()
{
    string password;
    cout<<"\nPlease enter your password: ";
    cin>>password;
    return password;
}
int encryptor(string strpassword)
{
    struktura nowatab;
    int sumakontrolna=0;
    for(int i=0;i<strpassword.length();i++)
        nowatab.tab[i]=0;
    for(int j=0; j<strpassword.length();j++)
        for(int i=0;i<92;i++)
            if(strpassword[j]==tab[i])
                nowatab.tab[j]=i;//kodowanie hasla
    for(int i=0;i<strpassword.length();i++)
        sumakontrolna=sumakontrolna+nowatab.tab[i]; //obliczanie sumy kontrolnej
    if(sumakontrolna>Q)
        do
            sumakontrolna=sumakontrolna/7;
        while(sumakontrolna>Q); //przycinanie sumy kontrolnej do 100 żeby tablica nie urosła
    cout<<"suma kontrolna: "<<sumakontrolna<<endl;
    string *password=&strpassword;
    return sumakontrolna;
}
string tablicahaszy[Q];
int main()
{
    int suma,liczba;
    string password;
    cout<<"Funkcja haszujaca (1)"<<endl;
    cout<<"Tablica haszy (2)"<<endl;
    cout<<"EXIT 0"<<endl;
    cin>>liczba;
    do
    {
        switch(liczba)
        {
            case 1:
            {
                suma=encryptor(password=strpassword());
                for(int i=0;i<Q;i++)
                {
                    if(tablicahaszy[i].empty()==true)
                        tablicahaszy[suma]=password;
                    else//tu ma prawdopodobnie zadziałać lista...
                    {

                    };
                return main();
            }
            case 2:
            {
                system("CLS");
                for(int i=0;i<Q;i++)
                    if(tablicahaszy[i].empty()!=true)
                        cout<<tablicahaszy[i]<<endl;
                return main();
            }
            case 0: break;
            default: break;
            }}}
    while(liczba!=0);
return 0;
}

Pozostało 580 znaków

2012-03-02 12:22

Rejestracja: 12 lat temu

Ostatnio: 1 godzina temu

0

Cały twój problem polega na tym, że źle określiłeś swój problem.
Napisz dokładnie CO MASZ ZROBIĆ, bo nikt nie ma ochoty rozszyfrowywać tego na podstawie kodu? Przy czym: zero wstępniaków, zero narzekania, zero pisania co ci się wydaje!

Czy masz wyszukiwać słowa w słowniku (sprawdzanie pisowni)?
A może masz zaszyfrować hasło, by w ten sposób weryfikować uprawnienia?
W obu wypadkach potrzebna jest funkcja hash, ale nieco inaczej się jej używa.

WTF: rekurencja na main !


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 1x, ostatnio: MarekR22, 2012-03-02 12:22
No przecież napisałem... program haszujący który haszuje podane przez użytkownika znaki(wygodniejsze podobno na stringach),później na podstawie danego hasza traktowanego jako indeks tablicy dodaje do niej podany przez użytkownika password(a jeśli tablica o podanym indeksie jest już używana to dodaje jako kolejny element listy tego indeksu) , do tego usuwa podane przez użytkownika elementy i szuka w tablicy czy jeśli natrafi na dany hasz i jeśli na liscie znajduje się podane przez użytkownika słowo, to wyrzuca że istnieje taki element... - red1791 2012-03-02 13:07

Pozostało 580 znaków

2012-03-02 12:34
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

2

Dobra, ja ogarniam o co chodzi. Łap przykładowy kod. Pisany dawno i na kolanie, a teraz nie mam jak przetestować ;] Jak ktoś ma czas to niech poprawi (np. zamiast char* dając stringi ;])

//Autor: Stanisław Podgórski
#include <iostream>
using namespace std;

int modulo=91; //od tego zalezy ile będzie pozycji w tablicy, proponowałbym liczbe pierwszą w okolicach np. ilosc wyrazow / 2 albo /3

struct Node
  {
    char* val;
    Node* next;
  };

int hash(const char* slowo);
void add(char* klucz, Node*& lista);
void search(char* klucz, Node* lista);

int main()
{
  char* buf=new char[150]; //zakładam ze dłuższego slowa nie będzie :P
  int ile;
  cout<<"Ile elementow?"<<endl;
  cin>>ile;

  Node** tablica = new Node*[modulo]; //nasza tablica z hashująca
  for (int i=0;i<modulo;i++)
    tablica[i]=NULL;

  for (int i=0;i<ile;i++)
  {
    cin>>buf; //wczytywanie wyrazów do tablicy
    char* str = new char[150];
    strcpy(str,buf);
    add(str, tablica[hash(str)]); //dodawanie kolejnych wyrazów do tablicy
  }

  for (int i=0;i<modulo;i++) //wypisanie tablicy
  {
    Node* rob=tablica[i];
    cout<<"Tablica["<<i<<"] =";
    while(rob)
      {
        cout<<" "<<rob->val;
        rob=rob->next;
      }
    cout<<endl;
  }

  cout<<"Czego szukac?"<<endl;
  cin>>buf;
  search(buf, tablica[hash(buf)]);

  cin.sync();
  cin.get();
  return EXIT_SUCCESS;
}
//////////////////////////////////////////////////////////
int hash(const char* slowo)
{
  int ret=0;
  int n=strlen(slowo); //dlugosć słowa

  while(n>=sizeof(int)) //dopóki są kawałki po 4 bajty
  {
   ret^=*(int*)slowo; //xor na 4 bajtach
   n-=sizeof(int); //"skracamy słowo"
   slowo+=sizeof(int); //przesuwamy sie dalej
  }

  int rem=0; //to co nam zostało, tzn 1,2 lub 3 bajty
  while(n--)
  {
    rem<<=8; //przesuwamy się o 1 bajt
    rem^=*slowo++; //xor
  }
  ret^=rem;
  return ret%modulo;
}
//////////////////////////////////////////////////////////
void add(char* klucz, Node*& lista)
{
  Node* tmp = new Node;
  tmp->val = klucz;
  tmp->next = lista;
  lista=tmp;
}
/////////////////////////////////////////////////////////////
void search(char* klucz, Node* lista)
{
  int ile = 1;
  if (!lista)
    cout<<"Brak, lista dla danego hasha pusta"<<endl;
  else
    {
      while((lista) && (strcmp(lista->val,klucz)))
      {
        lista=lista->next;
        ile++;
      }
      if (lista && !strcmp(lista->val,klucz))
        cout<<klucz<<" znalezione po "<<ile<<" porownaniach"<<endl;
    }
}

Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
Super,dziękuję bardzo :) Możesz mi jeszcze wytłumaczyć co robią te linijki? ret^=rem; return ret%modulo; Da się to zrobić na stringach? Żeby czarów nie używać? :P - red1791 2012-03-02 12:57
ret^=rem robi xora hasha z końcówką słowa (tzn z kawałkiem krótszym niż 4 bajty). ret%modulo zwraca nam finalny indeks w tablicy. Zauważ ze tablica ma modulo elementów, więc musimy zwrócić indeks od 0 do modulo-1 - Shalom 2012-03-02 13:15

Pozostało 580 znaków

2012-03-02 14:00

Rejestracja: 8 lat temu

Ostatnio: 5 lat temu

0
Shalom napisał(a)

Dobra, ja ogarniam o co chodzi. Łap przykładowy kod. Pisany dawno i na kolanie, a teraz nie mam jak przetestować ;] Jak ktoś ma czas to niech poprawi (np. zamiast char* dając stringi ;])


//Autor: Stanisław Podgórski
#include <iostream>
using namespace std;

int modulo=91; //od tego zalezy ile będzie pozycji w tablicy, proponowałbym liczbe pierwszą w okolicach np. ilosc wyrazow / 2 albo /3

struct Node
{
char val;
Node
next;
};

int hash(const char slowo);
void add(char
klucz, Node& lista);
void search(char
klucz, Node* lista);

int main()
{
char* buf=new char[150]; //zakładam ze dłuższego slowa nie będzie :P
int ile;
cout<<"Ile elementow?"<<endl;
cin>>ile;

Node* tablica = new Node[modulo]; //nasza tablica z hashująca
for (int i=0;i<modulo;i++)
tablica[i]=NULL;

for (int i=0;i<ile;i++)
{
cin>>buf; //wczytywanie wyrazów do tablicy
char* str = new char[150];
strcpy(str,buf);
add(str, tablica[hash(str)]); //dodawanie kolejnych wyrazów do tablicy
}

for (int i=0;i<modulo;i++) //wypisanie tablicy
{
Node* rob=tablica[i];
cout<<"Tablica["<<i<<"] =";
while(rob)
{
cout<<" "<<rob->val;
rob=rob->next;
}
cout<<endl;
}

cout<<"Czego szukac?"<<endl;
cin>>buf;
search(buf, tablica[hash(buf)]);

cin.sync();
cin.get();
return EXIT_SUCCESS;
}
//////////////////////////////////////////////////////////
int hash(const char* slowo)
{
int ret=0;
int n=strlen(slowo); //dlugosć słowa

while(n>=sizeof(int)) //dopóki są kawałki po 4 bajty
{
ret^=(int)slowo; //xor na 4 bajtach
n-=sizeof(int); //"skracamy słowo"
slowo+=sizeof(int); //przesuwamy sie dalej
}

int rem=0; //to co nam zostało, tzn 1,2 lub 3 bajty
while(n--)
{
rem<<=8; //przesuwamy się o 1 bajt
rem^=slowo++; //xor
}
ret^=rem;
return ret%modulo;
}
//////////////////////////////////////////////////////////
void add(char
klucz, Node& lista)
{
Node
tmp = new Node;
tmp->val = klucz;
tmp->next = lista;
lista=tmp;
}
/////////////////////////////////////////////////////////////
void search(char klucz, Node lista)
{
int ile = 1;
if (!lista)
cout<<"Brak, lista dla danego hasha pusta"<<endl;
else
{
while((lista) && (strcmp(lista->val,klucz)))
{
lista=lista->next;
ile++;
}
if (lista && !strcmp(lista->val,klucz))
cout<<klucz<<" znalezione po "<<ile<<" porownaniach"<<endl;
}
}



Visual robi mi jakieś wielkie halo podczas pisania i w mainie mówi że hash is too ambigous... Co to znaczy?
edytowany 1x, ostatnio: red1791, 2012-03-02 14:01

Pozostało 580 znaków

2012-03-02 14:13
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

0

http://ideone.com/S24CH
Brakowało kilku includów najwyżej.


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...

Pozostało 580 znaków

goscaa
2012-03-02 15:42
goscaa
0

@Shalom
Przy przekonwertowaniu charów na stringi wszystko zaczyna sie walić...
Możesz powiedziec co znaczy w funkcji:
void search(char klucz, Node lista)
{
int ile = 1,s;
if (!lista)
cout<<"Brak, lista dla danego hasha pusta"<<endl;
else
{
while((lista) && (strcmp(lista->val,klucz)))
{
lista=lista->next;
ile++;
}

  if (lista && !strcmp(lista->val,klucz))
    cout<<klucz<<" znalezione po "<<ile<<" porownaniach"<<endl;
}

}

ta linijka while((lista) && (strcmp(lista->val,klucz)))? Bo przy skonwertowaniu do stringów to wszystko zaczyna sie walic...

dopóki lista nie wskazuje na NULL i lista->val nie pokaże na to samo co klucz, jedziesz następny element listy i powiększasz ile. - kopernik 2012-03-02 15:49

Pozostało 580 znaków

2012-03-02 16:03
Moderator

Rejestracja: 16 lat temu

Ostatnio: 1 godzina temu

0

Jak masz tam string to powinno tam być:

while((lista) && (lista->val!=klucz))

i wszystkie inne strcmp trzeba pozamieniać na == i !=


Masz problem? Pisz na forum, nie do mnie. Nie masz problemów? Kup komputer...
edytowany 1x, ostatnio: Shalom, 2012-03-02 16:04

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0