Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wyrazy jednolite/(palindromy?)

Ostatnio zmodyfikowano 2017-05-25 09:04
Autor Wiadomość
Avaris
Temat założony przez niniejszego użytkownika
Wyrazy jednolite/(palindromy?)
» 2017-05-24 16:49:52
Hej,
pisałem już o tym wcześniej ale nadal mam problem z pierwszym podpunktem pewnego zadania maturalnego. Mam sprawdzić czy napisy pobrane z pliku są napisami jednolitymi.
Treść podpunktu: Napis nazywamy jednolitym, jeżeli wszystkie jego litery są takie same. Przykładem takiego napisu
jest AAAA. Podaj liczbę wierszy zawierających parę napisów jednolitych, które są wzajemnie
swoimi anagramami.
Przykład
Dla pliku zawierającego następujące dane:
AAAA AAAA
AHHAH AHHAH
AAAA AAAAAAA
BBBBBBB BABBAB
CCCCC CCCCC
wynikiem jest liczba 2 (pierwszy i ostatni wiersz). Zwróć uwagę, że napisy w trzecim wierszu są
napisami jednolitymi, ale nie są wzajemnie swoimi anagramami..

Uporałem się już z drugim podpunktem gdzie miałem sprawdzić czy napisy wzajemnie są anagramami, mam ideę by sprawdzić najpierw długość ciągu znaków a potem sprawdzać po znaku, czy sobie odpowiadają lecz nie mam pomysłu jak to zrobić. Myślę także, że działa to na zasadzie szukania palindromów. Proszę powiedzieć czy dobrze myślę, oraz o ewentualne instrukcje :)
Pozdrawiam!

C/C++
#include <iostream>
#include<fstream>
#include<string>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;

void zad1jednolite() {
    fstream plik;
    plik.open( "Dane/68/dane_napisy.txt", ios::in | ios::out );
    if( plik.good() == true ) { cout << "Uzyskano dostep do pliku" << endl; } else cout << "Brak dostepu do pliku" << endl;
   
    ifstream fin( "Dane/68/dane_napisy.txt" );
    ofstream fout( "wyniki_anagramy.txt" );
    string anagramy[ 2000 ];
    int ilosc_wierszy = 0;
    string odwrocony;
    int k = 0;
    for( int i = 0; i < 2000; i++ ) {
        fin >> anagramy[ k ];
        k++;
    }
   
    for( int i = 0; i < 2000; i = i + 2 )
         if( anagramy[ i ].size() != anagramy[ i + 1 ].size() ) continue;
   
   
   
   
   
   
   
    void zad2anagramy() {
        fstream plik;
        plik.open( "Dane/68/dane_napisy.txt", ios::in | ios::out );
        if( plik.good() == true ) { cout << "Uzyskano dostep do pliku" << endl; } else cout << "Brak dostepu do pliku" << endl;
       
        ifstream fin( "Dane/68/dane_napisy.txt" );
        ofstream fout( "wyniki_anagramy.txt" );
        string anagramy[ 2000 ];
        int ilosc_wierszy = 0;
        int k = 0;
        for( int i = 0; i < 2000; i++ ) {
            fin >> anagramy[ k ];
            k++;
        }
        for( int i = 0; i < 2000; i = i + 2 )
        {
            if( anagramy[ i ].size() != anagramy[ i + 1 ].size() ) continue;
            else
            {
                sort( anagramy[ i ].begin(), anagramy[ i ].end() );
                sort( anagramy[ i + 1 ].begin(), anagramy[ i + 1 ].end() );
                if( anagramy[ i ] == anagramy[ i + 1 ] )
                     ilosc_wierszy = ilosc_wierszy + 1;
               
            }
        }
       
        fout << "Zad68.2\n";
        fout << "Anagramow jest: " << ilosc_wierszy;
        fin.close();
        fout.close();
    }
   
   
   
   
   
   
   
   
    int main()
    {
        zad1jednolite();
        zad2anagramy();
       
        return 0;
    }
P-161535
latajacaryba
» 2017-05-24 18:07:59
Ja bym to zrobił tak:
C/C++
vector < string > wiersz1; // pierwszy wyraz wiersza
vector < string > wiersz2; //drugi wyraz danego wiersza
vector < int > ktore_wiersze; // ktore wiersze sa anagramami i sa jednolite
int licznik = 0;
fstream plik;

plik.open( "plik" );

while( plik.eof == false )
{
    licznik++; // liczymy, ktory to wiersz
    wiersz1.push_back( "" );
    wiersz2.push_back( "" );
    plik >> wiersz1[ wiersz1.size() - 1 ] >> wiersz2[ wiersz2.size() - 1 ];
    if( wiersz1[ wiersz1.size() - 1 ] == wiersz2[ wiersz2.size() - 1 ] ) // sprawdzanie czy sa takie same
    {
        ktore_wiersze.push_back( licznik );
        for( int i = 0; i < wiersz1[ wiersz1.size() - 1 ].length; i++ )
        {
            if( wiersz1[ wiersz1.size() - 1 ][ 0 ] != wiersz1[ wiersz.size() - 1 ][ i ] ) // sprawdzanie, czy znak w stringu o indeksie zero jest nie rowny wszystkim innym znakom, jesli jest, to:
            {
                ktore_wiersze.pop_back; // jednak w tym wierszu wyrazy nie sa takie same :<
                break;
            }
        }
    }
}

cout << "rowne wiersze to: \n"
for( int i = 0; i < ktore_wiersze.size(); i++ )
     cout << ktore_wiersze << " wiersz\n";


Oczywiście trzeba coś tam jeszcze porobić, warto by  też gdzieś na boku zapisywać długość wiersz1 i wiersz2 żeby ciągle nie wywoływać niepotrzebnie tej samej metody.
Jak masz jakieś pytania to pisz.
Jeśli ktoś zauważył błąd, proszę o sprostowanie
P-161539
michal11
» 2017-05-24 18:25:25
Przecież w poprzednim temacie napisałem ci nawet gotową funkcję z wyjaśnieniem  tego jak rozwiązać to zadanie, z czym dokładnie masz problem?
P-161540
Avaris
Temat założony przez niniejszego użytkownika
» 2017-05-24 21:13:27
Przepraszam Michale, na początku zauważyłem tylko twoją odpowiedź jak Ty to byś zrobił (kod nie był jeszcze wtedy wklejony). Dlatego zaszło to całe nieporozumienie. Przepraszam. Próbowałem coś sam wymyślić i nie udawało mi się. Dlatego napisał kolejny post.
Nie jestem zbyt obyty z językiem c++, dlatego nie mam pojęcia o co biega z vectorami i sposobami, które użył latającaryba. Dlatego mam pytanie, wklejam mój kod, który poprawiłem używając funkcji Michała i proszę by ktoś mógł zerknąć i odpowiedzieć dlaczego nie działa i ewentualnie go poprawić. Jedyne co mogę powiedzieć to fakt, że niedawno rozpocząłem naukę języka C++ dlatego jeżeli popełniłem jakiś głupi błąd, proszę o konstruktywną krytykę.
C/C++
#include <iostream>
#include<fstream>
#include<string>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;

void zad1jednolite() {
    fstream plik;
    plik.open( "Dane/68/dane_napisy.txt", ios::in | ios::out );
    if( plik.good() == true ) { cout << "Uzyskano dostep do pliku" << endl; } else cout << "Brak dostepu do pliku" << endl;
   
    ifstream fin( "Dane/68/dane_napisy.txt" );
    ofstream fout( "wyniki_anagramy.txt" );
    string anagramy[ 2000 ];
    int ile_par = 0;
    string odwrocony;
    int k = 0;
    for( int i = 0; i < 2000; i++ ) {
        fin >> anagramy[ k ];
        k++;
    }
    for( int i = 0; i < 2000; i = i + 2 ) {
        const string & pierwszy_napis = anagramy[ i ], const std::string & drugi_napis = anagramy[ i + 1 ];
        if( pierwszy_napis.size() != drugi_napis.size() ) { continue; }
       
        if( pierwszy_napis[ 0 ] != drugi_napis[ 0 ] ) { continue; }
       
        int pierwszy_napis_1_litera = std::count( pierwszy_napis.cbegin(), pierwszy_napis.cend(), pierwszy_napis[ 0 ] );
        int drugi_napis_1_litera = std::count( drugi_napis.cbegin(), drugi_napis.cend(), drugi_napis[ 0 ] );
       
        if( pierwszy_napis_1_litera != pierwszy_napis.size() ||
        drugi_napis_1_litera != drugi_napis.size() )
        {
            continue;
        }
       
        ile_par++;
    }
}
fout << "Zad68.1\n";
fout << "Wyrazów jednolitych jest: " << ile_par;
fin.close();
fout.close();
}









void zad2anagramy() {
fstream plik;
plik.open( "Dane/68/dane_napisy.txt", ios::in | ios::out );
if( plik.good() == true ) { cout << "Uzyskano dostep do pliku" << endl; } else cout << "Brak dostepu do pliku" << endl;

ifstream fin( "Dane/68/dane_napisy.txt" );
ofstream fout( "wyniki_anagramy.txt" );
string anagramy[ 2000 ];
int ilosc_wierszy = 0;
int k = 0;
for( int i = 0; i < 2000; i++ ) {
    fin >> anagramy[ k ];
    k++;
}
for( int i = 0; i < 2000; i = i + 2 )
{
    if( anagramy[ i ].size() != anagramy[ i + 1 ].size() ) continue;
    else
    {
        sort( anagramy[ i ].begin(), anagramy[ i ].end() );
        sort( anagramy[ i + 1 ].begin(), anagramy[ i + 1 ].end() );
        if( anagramy[ i ] == anagramy[ i + 1 ] )
             ilosc_wierszy = ilosc_wierszy + 1;
       
    }
}

fout << "Zad68.2\n";
fout << "Anagramow jest: " << ilosc_wierszy;
fin.close();
fout.close();
}








int main()
{
zad1jednolite();
zad2anagramy();



return 0;
}
P-161545
michal11
» 2017-05-24 21:57:35
Twój kod jest źle sformatowany, przez co jest nieczytelny.
W tym programie nie musisz zapisywać wczytanych wyrazów, ani do tablicy ani do vectora.

Zastosuj taki algorytm:
1. wczytaj pierwszy wyraz
2. wczytaj drugi wyraz
3. sprawdź czy wyrazy mają taką samą długość
3.1 jeżeli nie to na pewno nie są jednolite więc przechodzi do pkt 1 (sprawdzanie kolejnej pary)
4. sprawdź czy zaczynają się na tą samą literę
4.1 jeżeli nie to na pewno nie są jednolite więc przechodzi do pkt 1 (sprawdzanie kolejnej pary)
5. policz ile razy w pierwszym wyrazie występuje pierwsza litera
5.1 jeżeli mniej razy niż długość pierwszego wyrazu to znaczy, że wyraz nie jest jednolity, przechodzimy do pkt 1
6. policz ile razy w drugim wyrazie występuje pierwsza litera
6.1 jeżeli mniej razy niż długość drugiego wyrazu to znaczy, że wyraz nie jest jednolity, przechodzimy do pkt 1
7. jeżeli doszedłeś aż tutaj to znaczy, że para wyrazów jest jednolita (mają tyle samo takich samych liter)

jeżeli chodzi o zmienne to potrzebujesz dwóch stringów na wczytanie wyrazów, jednego inta na zliczanie ile jest jednolitych wyrazów, main powinien wyglądać mniej więcej tak
C/C++
int main()
{
    std::string pierwszWyraz, drugiWyraz;
    int ileJednolitych = 0;
   
    while( plik >> pierwszyWyraz >> drugiWyraz )
    {
       
        if( saJednolite( pierwszyWyraz, drugiWyraz )
        {
            ++ileJednolitych;
        }
    }

funkcję saJednolite już wcześniej napisałem, jeżeli nie wiesz co robi funkcja std::count i nie chcesz się dowiedzieć to można ja samemu napisać
C/C++
int policz( const std::string & napis, char znak )
{
    int wynik = 0;
   
    for( char c: napis )
    {
        if( c == znak )
        {
            ++wynik;
        }
    }
    return wynik;
}
P-161546
Avaris
Temat założony przez niniejszego użytkownika
» 2017-05-24 22:32:24
Wiem do czego służy funkcja count i jak jej używać :)
Wyskrobałem coś takiego, program kompiluje się i uruchamia ale nie zapisuje nic do pliku.
C/C++
void zad1jednolite() {
    fstream plik;
    plik.open( "Dane/68/dane_napisy.txt", ios::in | ios::out );
   
    if( plik.good() == true ) { cout << "Uzyskano dostep do pliku" << endl; } else cout << "Brak dostepu do pliku" << endl;
   
    ifstream fin( "Dane/68/dane_napisy.txt" );
    ofstream fout( "wyniki_anagramy.txt" );
    string anagramy[ 2000 ];
    int ile_par = 0;
    int k = 0;
    for( int i = 0; i < 2000; i++ )
    {
        fin >> anagramy[ k ];
        k++;
    }
   
    for( int i = 0; i < 2000; i = i + 2 ) {
       
        if( anagramy[ i ].size() != anagramy[ i + 1 ].size() ) { continue; } //sprawdzenie czy mają tę samą długość
       
        if( anagramy[ i ][ 0 ] != anagramy[ i + 1 ][ 0 ] ) { continue; } //sprawdzanie czy zaczynają się na tę samą literę
       
        int pierwszy_napis_1_litera = count( anagramy[ i ].begin(), anagramy[ i ].end(), anagramy[ i ][ 0 ] ); //liczenie ile razy w pierwszym razie znajduje się pierwsza litera
        int drugi_napis_1_litera = count( anagramy[ i + 1 ].begin(), anagramy[ i + 1 ].end(), anagramy[ i + 1 ][ 0 ] ); //liczenie ile razy w drugim razie znajduje się pierwsza litera
       
        if( pierwszy_napis_1_litera != anagramy[ i ].size() || drugi_napis_1_litera != anagramy[ i + 1 ].size() ) //jeżeli ilość wystąpień pierwszej litery jest mniejsza niż długość wyrazu to wyrazy nie są jednolite
        {
            continue;
        }
       
        if( pierwszy_napis_1_litera == anagramy[ i ].size() || drugi_napis_1_litera == anagramy[ i + 1 ].size() ) { ile_par++; }
    }
    fout << "Zad68.1\n";
    fout << "Wyrazów jednolitych jest: " << ile_par;
    fin.close();
    fout.close();
}
P-161547
michal11
» 2017-05-24 23:13:27
Dwa razy otwierasz ten sam plik. Jest jakiś powód dla którego wczytujesz wyrazy do tablicy?
P-161549
Avaris
Temat założony przez niniejszego użytkownika
» 2017-05-24 23:23:25
Powód nie jest jakiś olbrzymi. Po prostu jest to dla mnie wygodne i w miarę wiem jak się z tym obchodzić. Poza tym sporo czasu w szkole poświęciliśmy tablicą. Czy funkcja jest poprawnie napisana i będzie zapisywać dane do pliku gdy poprawie otwieranie go? Czy jednak wymaga poprawek?
P-161551
« 1 » 2
  Strona 1 z 2 Następna strona