Anagramy(file,dynamic_array,char analisys)

0

Dzień dobry, a w sumie kolejny nerwowy bo już myślałem że skończe pisać pierwszy program z tych od cke ale jednak wymieklem. miesiac nauki za mna jednak wystartuje z c++ na maturze a nie c# ^^
no więc mamy 1001 wierszy z różnymi dużymi literami od a do j ostatni jest pusty wiec zostaje 1000, wiec nie moge sobie poradzic z:

  1. wczytaniem tego litera po literze do dynamicznie(tylko wiersze) stworzonej tablicy.

  2. dynamiczna kolumny do tablicy... jaki blad? hmm brak wskaznikow?
    no to moze jakies wskazowki ;]

  3. czy zeby stworzyc tablice wskaznikow do tablicy czar bez uzywania listy to czy potrzebuje zrobic dany ruch 2 razy? raz zeby zdobyc tab = new czar*[wiersze] a pozniej tab[wiersze] = new char [kolumny]

Dziękuję z góry za każdą podpowiedź

ex.

BFDAFBCCGBDIIEDCJAACDF
ADFBJADEAJAAD
EFCCCEBFFCBABEAEBAFGC
HGCDCECECADBFCBAGH
BDAEDDAEIICFDEFAADEAF
CIEAEG

Code.

#define IN 1
#define OUT 0
#define MAX 25
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include <new>
#include <cstdio>
using namespace std;

int main(int argc, char argv[])
{
//tu nie ma jeszcze char
* temp
int i = 0, j =0, i_w = 0, i_k = 0;
char c;
char** wiersze = NULL;
short* kolumny = NULL;

ifstream wejscie("dane.txt");

//odczytuje jak duza ma byc tablica do wskaznikow char
if(!wejscie)
return -1;
else{
while(!wejscie.eof())
if((wejscie.get()) == '\n')
i_w++;
wejscie.close();
cout << "Odczytałem:" << i_w << " wyraz z pliku\n";
}
// buduje tablice wskaznikow
try
{
wiersze = new char *[i_w];
}
catch(bad_alloc)
{
cout << "nie ma miejsca w pamieci\n";
}
cout << "Odczytałem:" << i_w << " wyrazów\n";
//to mi tez wypier.. blad hmmm "segmentation fault"
/*wejscie.open("dane.txt");
wejscie.clear();
wejscie.seekg(+OUT,ios_base::beg);

while(!wejscie.eof()){
if((wejscie.get()) == '\n'){ // zawsze przechodzi do else? wtf
i++;
try
{
wiersze[i] = new char [i_k];
}
catch(bad_alloc)
{
cout << "nie ma miejsca w pamieci\n";
}
try
{
kolumny = new short [i];
}
catch(bad_alloc)
{
cout << "nie ma miejsca w pamieci\n";
}
kolumny[i] = i_k;
i_k=0;
}

 else
   i_k++;
     }*/

//wyrazy w dane.txt maja max 25 daje 26 zeby dac '\0' na koncu
for(i=0; i<i_w; i++)
try
{
wiersze[i] = new char [MAX+1];
}
catch(bad_alloc)
{
cout << "nie ma miejsca w pamieci\n";
}

//resetuje wskaznik do pliku i chyba wczytuje znaki do tablicy oO
i=0;j=0;
wejscie.open("dane.txt");
wejscie.clear();
wejscie.seekg(+OUT,ios_base::beg);
while(!wejscie.eof()){
c = wejscie.get();
if(c == '\n'){
wiersze[i++][j] = '\0'; // po 21 ruchach daje '\n' gdzie pierwszy wyraz ma 22
else
wiersze[i][j++] = c;
}
wejscie.close();
// a tu juz w ogole nie mam dostepu do pamieci ;]
for( i= 0; i< i_w; i++ && putchar('\n'))
for( j= 0; j != '\n'; j++)
putchar(wiersze[i][j]);
// tu chyba ladnie wszystko usuwam
for(i= 0; i< i_w; i++)
delete [] wiersze[i];
delete [] wiersze;
delete [] kolumny;
// tu bedzie jeszcze czesc analizy tablic anagramow,
//kopiowanie do tempa jezeli sa dobre i zapisanie do pliku.. help

cout << "Odczytałem:" << i_w << " wyrazów\n";
system("PAUSE");
return EXIT_SUCCESS;

}

0

To było proste :D warunek trzeba ustawic za pierwszym ruchem w pliku - na jezeli nie jest nowym wierszem to zapisz do tablicy shortów indeks kolumny ;D no dziękuję ;] skończe pisać to zaprezentuje cały kod, no chyba że dalej tez bede mial

0

Skoro znasz C# to może pisz w C++/CLI? Będzie prościej, szybciej, mniej nerwów. Wczytanie całego pliku wierszami to jedna linijka. Takie rzeczy na maturze ułatwiają sprawę. W im mniej rzeczach możesz się pomylić, tym lepiej.

0

Podaj treść zadania, również jes sobie zrobię. Matura niedługo :D

0

a może tak: http://ideone.com/eV1ZU

0

kur!!! ;] Zmieniłem troche ale dalej nie mam miejsca w pamięci pomimo tego że mam oO no ale może nie ciągłej na tablice drobne zmiany w tworzeniu tablic
// kolumny dalem statycznie kolumny[1000].... czy to cheating? :D

else{
     while(!wejscie.eof())
       if((wejscie.get()) == '\n')
       {
         i_w++; **kolumny[i_w] = i_k; i_k=0;**
       }
       else{
            **i_k++;**
            }
     wejscie.close();
     cout << "Odczytałem:" << i_w << " wyraz z pliku\n";
    }

// buduje tablice wskaznikow
try
{
wiersze = new char [i_w];
}
catch(bad_alloc)
{
cout << "nie ma miejsca w pamieci\n";
}
** cout << "Odczytałem:" << i_w << " wyrazów\n";
for( i = 0; i < i_w; i++)
{i_k = kolumny[i];
try
{
wiersze[i] = new char [i_k];
}
catch(bad_alloc){
cout << "za malo miejsca w pamieci"; // tu juz nie mam pamieci
}
}
*

czy zrobic to na strukturze? --'

0

A przy strukturze daje mi puste znaki w tablicy
struct wyraz
{
short id;
char tab[25];
};
wyraz anagram[1000];

while(!wejscie.eof())
if((c = wejscie.get()) == '\n')
{
anagram[i_w++].id = i_w; i_k=0;
}
else{
anagram[i_w].tab[i_k++] = c;
}

for( i= 0; i< i_w; i++ && putchar('\n'))
for( j= 0, c = anagram[i_w].tab[j]; isalpha(c); j++)
putchar(c);

a może ktoś spróbuje mi to na tablicy stringow wytlumaczyc i na getline() i strlen()?, bo ja nie ogarniam stringów.
C# się uczyłem pół roku temu jak planowalem mature z infy, zdecdowalem sie jednak na c++
a zadanie brzmi wczytaj plik tekstowy i zanalizuj czy tekst jest anagramem... te example z pierwszego postu to nie sa anagramy, tu masz kilka przykladow:
AJA
AGFFGA
AAMAA

0
  1. używaj tagów kolorowania składni: <cpp></cpp>
  2. podaj treść zadania, bo ten kod spagetii zniechęca do czytania i rozszyfrowywnia co to ma właściwie robić
0

@Marek22 Marku dzięki za znacznik CPP, ale nic poza tym nie wniosłeś a zadanie opisałem w pierwszym poście i w poście przed Twoim. A dla tych co już naprawde nie wiedzą co to są anagramy... to wyrazy które zawsze czytane od końca są takie same jak od początku.
btw. jak otworze strumien ktory wczytuje... hmm.. znak po znaku? to jak sciagac ze strumienia cala linie do stringa?

  1. no chyba że jednak ktoś poradzi sobie z błędami albo **struktury **albo dynamicznej tablicy char

Lece czytać dalej...

0
Hiro napisał(a)

A dla tych co już naprawde nie wiedzą co to są anagramy... to wyrazy które zawsze czytane od końca są takie same jak od początku

Pojechałeś chłopcze. To o czym piszesz to palindrom.

0

@odp Faktycznie masz rację to palindromy - widze że pierwszego buga znalazłeś - ale reszta dalej nie dziala...
....no ideas..keep working.

0
string reverse(string s)
{
    string tmp;
    string::reverse_iterator it = s.rbegin();
    for(;it != s.rend(); ++it)
        tmp += *it;
   
    return tmp;
}

inline bool palindrom(string s) { return (reverse(s) == s) ? true : false; }

string alg(string s)
{
    string w1 = "";
    if(palindrom(s))
        return s;
    for(int i = 0; i < s.size(); ++i)
    {
        string tmp = s.substr(0, i);
        if(palindrom(tmp))
            w1 = tmp;
    }
    string w2 = s.substr(w1.size(), s.size()-1);
    return  reverse(w2) + w1 + w2;
}

Jeśli to zadanie 5 z matury z 2008 to masz moje rozwiązanie. Może ci coś pomoże. Nie mam zamiaru przeglądać tego tasiemca co wrzuciłeś :)
Chciałeś wskazówki to masz jedną: stosuj stl. Nic bardziej pomocnego na maturze nie będziesz posiadał. Po co pieprzyć się wskaźnikami, zarządzaniem pamięcią itd. ? Liczy się czas pisania i poprawność algorytmu, a w tym ci pomoże biblioteka standardowa i jeśli masz zamiar się czegoś uczyć to właśnie jej stosowania.

0
inline bool palindrom(string s) { return (reverse(s) == s) ? true : false; }

jeszcze w sumie to ukrócić. Troszkę masło maślane wyszło ale pisałem to kiedyś na "szybciocha" i nie pomyślałem o tym.

0

No ja myślałem że po prostu(jeżeli już nie moge dynamicznie jej stworzyć) z tablicy(statycznej 25 max liter) odczytac ostatni nie bialy znak i zrobic funkcje zacznij gdzie zwracana wartosc pokazywala by do funkcji porownujacej pojedyncze znaki wartosc od konca tablicy i na jeden ruch porownywalaby jedna litere z konca i jedna z poczatku dopoki bylyby rowne zwraca 1 inaczej 0:
czyli wywolalbym to:

for( i = 0 ; i < ilosc_wierszy; i++ )
if( porównaj(tablica_wczytana_z_pliku[i], zacznij(tablica_wczytana_z_pliku,25)
... tutaj bym dal char* tempa do którego bym kopiował wyniki, tylko znowu nie wiem jak on duzy musi byc skoro dostaje plik musze raz obliczyc ile palindromow jest w srodku a pozniej stworzyc od nowa char** tempa, no i tu bolaczka pamieci dynamicznej, poszukuje specjalisty od pamieci! ^^

//tutaj dopoki nie jest liczba zwroc ilosc pustych pol w tablicy
int zacznij(char* tab, int max);
{
int i=max, zacznij=0;
while((!isalpha(tab[i--])) );
zacznij++;
return zacznij
}
// tutaj porownaj elementy char z koncow tablicy i sprawdz czy to palindrom
bool porownaj(char* tab, int koniec)
bool palindrom = true;
int i = 0;
for( i ; i < koniec; i++)
{
if(tab[i] != tab[max - i]){ palindrom = false; return palindrom;}
else{palindrom = true; continue;}
}

1

osbiście mam obiekcje co do robienia odwrotnej kopii.

bool isPalindrom(const string &s)
{
    for(int i=0; i<s.size()/2; ++i)
        if (tolower(s.at(i))!=tolower(s.at(s.size()-1-i)))
            return false;
    return true;
}
0

// proszę Moda o usunięcie wyżej posta, stworzyłem sobie konto, zle napisalem kilka spraw musialem poprawic

po prostu(jeżeli już nie moge dynamicznie jej stworzyć) z tablicy(statycznej 25 max liter) odczytac ostatni nie bialy znak i zrobic funkcje zacznij gdzie zwracana wartosc pokazywala by do funkcji porownujacej pojedyncze znaki wartosc od konca tablicy i na jeden ruch porownywalaby jedna litere z konca i jedna z poczatku dopoki bylyby rowne zwraca 1 inaczej 0:
czyli wywolalbym to:

for( i = 0 ; i < ilosc_wierszy; i++ )
if( porównaj(tablica_wczytana_z_pliku[i], zacznij(tablica_wczytana_z_pliku,25)
... tutaj bym dal char* tempa do którego bym kopiował wyniki, tylko znowu nie wiem jak on duzy musi byc skoro dostaje plik musze raz obliczyc ile palindromow jest w srodku a pozniej stworzyc od nowa char** tempa, no i tu bolaczka pamieci dynamicznej, poszukuje specjalisty od pamieci! ^^

//tutaj dopoki nie jest znakiem zwroc ilosc pustych pol w tablicy
int zacznij(char* tab, int max);
{
int i=max, zacznij=0;
while((!isalpha(tab[i--])) );
 zacznij++;
return zacznij
}
// tutaj porownaj elementy char z koncow tablicy i sprawdz czy to palindrom
bool porownaj(char* tab, int koniec)
 bool palindrom = true;
int i = 0;
for( i ; i < koniec; i++)
{
if(tab[i] != tab[koniec - i]){ palindrom = false; return palindrom;}
else{palindrom = true; continue;}
}

ps. macie jakiś materiał z którego ogarnę dzisiaj stringi?

0

A co w stringach jest trudnego?

#include <iostream>
#include <string>

#include <cstdio>

using namespace std;

int main()
{
  string napis1("Ala");
  string napis2 = " ma";
  string napis3 = " kota";

  cout << napis1 << napis2 << napis3 << '\n';

  string razem = napis1 + napis2 + napis3;

  cout << razem << '\n';

  for (int i = 0; i < razem.length(); i++)
    cout << razem[i] << " ";
  cout << '\n';
 
  printf("%s\n", razem.c_str());
  return 0;
}

To chyba tyle, jeśli chodzi o stringi.
Więcej znajdziesz tutaj: http://www.cplusplus.com/reference/string/string/

0

No to specjalisty od stringów potrzeba teraz ^^ nie umiem zwrocic funkcją stringa, zaznaczam w kodzie:
moze jednak zostawię komenty..

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cstdio>
#include <string>
using namespace std;

bool licz_porownaj(string tab, int max_tab) // czy może tu?
{
   int to_jest_palindrom = 0;
   for ( int i = 0; i < (max_tab - 1); i++)
     if(tab[i] !=  tab[(max_tab - 1) - i])
       continue;
     else to_jest_palindrom++;
   if(to_jest_palindrom < (max_tab) - 1)
    return false; 
   else return true;
}
string oddaj_porownaj(string tab,int max_tab)   // tu cos jest nie tak?
{
   if(licz_porownaj(tab,max_tab )) 
   return tab;
}

int main(int argc, char *argv[])
{
    int i, j, i_w, i_k, i_p;
    i = j = i_w = i_k = i_p = 0;
    char c;
    
    ifstream wejscie("dane.txt");
//odczytuje jak duza ma byc tablica stringów    
while(!wejscie.eof())
     if((c = wejscie.get()) == '\n')
       i_w++;
       
wejscie.clear();
string poli[i_w];
wejscie.seekg(+0,ios_base::beg);

// tu wczytuje wyrazy z pliku do stworzonej tablicy
while(!wejscie.eof()){
     if(wejscie)
     wejscie >> poli[i++]; 
     else
     wejscie.seekg(+(sizeof(poli[i-1]) - sizeof(char)),ios_base::cur);}
wejscie.close();

// sprawdzam czy wszystkie sie wczytały           
for(i = 0; i < i_w; i++)
 cout <<"wyraz nr: " << i+1 << "to: " << poli[i] << '\n';
 
//porównuję polindromy i wpisuje ilosc do tablicy wyników...  no i jak narazie ok wszystko
for(i =0; i< i_w; i++)
  if(licz_porownaj(poli[i],sizeof(poli[i])))
   i_p++;
string temp[i_p];
cout << "Odczytałem:" << i_w << " wyrazów\n"
         << "Odnalazlem: "<< i_p <<" palindromow\n";
 system("PAUSE");
for(i = 0; i < i_p; i++)
  temp[i] = oddaj_porownaj(poli[i], sizeof(poli[i]));   // a tu wypiepsza mi moj ulubiony blad segmentation fault, co rozumiem
cout         << "Wciśnij enter żeby zobaczyć wyniki.\n";  // jako błąd pamięci a jak ktoś wie też miło będzie dowiedzieć się
system("PAUSE");
for(i = 0; i < i_p; i++)
      cout << "Palindrom nr: "<< i << ' '<< temp[i] << '\n';
system("PAUSE");    
    return EXIT_SUCCESS;
}

@Azrael ;) Czekam na symfonie c++. Ale nie mam czasu żeby sobie robić przerwy ;)

btw. dzięki wszystkim za odpowiedzi i chęci współpracy, ciekawe metody mi pokazaliscie a jak jesteście od początku tematu zauważyliście - ja z C# poszedłem na c++ ale i tak czysty C mnie najbardziej kręci a pomiędzy c i c++ jest mini postęp technologiczny ;) strumienie od dzisiaj bede uwazal za fajny dodatek ;) pewnie nie raz jeszcze popiszemy. Pozdro



bool licz_porownaj(string tab, int max_tab)
{
   int to_jest_palindrom = 0;
   
   
   for ( int i = 0; i <(max_tab - 1 ) ; i++){ 
       cout << tab[i] <<" - "<< tab[max_tab -2 - i] <<" = " << (tab[i] - tab[max_tab -1 - i]) << endl;
     if((tab[i] - tab[max_tab -sizeof(char) - i])==0)// ogolnie to nie wiem czy mam zle zalozony warunek
       continue;                                                     //    bo jak tutaj wstawie odwrotnie
     else to_jest_palindrom++;}                             //  czyli tak jak powinno byc
   if(to_jest_palindrom < max_tab - 1)                  // to tu bedzie za malo w zmiennej
    return false;                                                    // zeby nie zwrocilo false
   else return true;                                               // tylko true
}

i na koniec zagadka :

if(licz_porownaj("CBJBC",sizeof("CBJBC")))
cout << "to jest palindrom :D... ja pierd*** udalo sie wreszcie xD " ;

funkcja daje wyniki
C - C = 67 < czy ja o czyms nie wiem
B - B = -1 < od kiedy char - ten sam char <>0?
J - J = 8 < wtf?
B - B = -8
C - C = 1
C - C = 67
B - B = -1
J - J = 8
B - B = -8
C - C = 1
to jest palindrom :D... ja pierd*** udalo sie wreszcie xD Aby kontynuować, naciśnij ...
nom przeczytałem to i się ucieszyłem później zobaczyłem że w petli for mam warunek przemieniony...damn! Specjalisty od znaków poczeba...!

0

"Mini postęp technologiczny" między C i C++? Hmm, ok. ;)

cout << tab[i] <<" - "<< tab[max_tab -2 /* odejmujesz _2_ */ - i] <<" = " << (tab[i] - tab[max_tab -1 /* odejmujesz _1_ */ - i]) << endl;

Poza tym, chyba powinieneś wiedzieć co robi endl: http://www.cplusplus.com/reference/iostream/manipulators/endl/

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