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

Wyswietlanie różnych n cyfrowych ciagów znaków

Ostatnio zmodyfikowano 2016-12-28 22:46
Autor Wiadomość
Tomal
Temat założony przez niniejszego użytkownika
Wyswietlanie różnych n cyfrowych ciagów znaków
» 2016-12-24 21:20:05
Napisałem program który wpisuje do pliku ciągi znaków do podanej długości (czyli dla n= 3 wypisze mi ciągi znaków 1,2 i 3 cyfrowe). Tylko haczyk jest w tym że te ciągi znaków zawsze są takie same :P A powinne być różne. Jakieś uwagi, sugestie byłby mile widziane, bo nie potrafię rozwiązać tego problemu, a jedyne rozwiązania jakie mi przychodzą do głowy są nieopatymalne i wymagają długich linijek.

C/C++
#include <iostream>
#include <fstream>
#include <cmath>
#include <stdio.h>
using namespace std;

int main()
{
    ofstream ciag;
    int n, i, j, m;
    long long int rozmiar = 1;
    static int k = 0;
    string * tab;
    char tempc = 33;
    cout << "Ilu znakowa biblioteke chcesz utworzyc?" << endl;
    cin >> n;
    for( int z = 0; z < n; z++ )
         rozmiar = rozmiar * 94;
   
    tab = new string[ rozmiar ];
    //cout<<rozmiar<<endl;
    rozmiar = 1;
    for( j = 1; j < n + 1; j++ )
    {
        rozmiar = rozmiar * 94;
        for( int z = 0; z < j; z++ )
        {
            for( i = k; i < rozmiar; i++ )
            {
                if( tempc >= 127 )
                     tempc = 33;
               
                tab[ i ] += tempc;
                tempc++;
                //cout<<tab[i]<<endl;
            }
            cout <<( int ) tempc << endl;
            tempc += z;
        }
        k = k + i;
       
    }
    ciag.open( "ciag.txt", ios::in | ios::out );
    for( i = 0; i < rozmiar; i++ )
         ciag << tab[ i ] << endl;
   
    ciag.close();
    delete[] tab;
    return 0;
}

Generalnie chodzi o to ze teraz dane w pliku tekstowym który mam wyglądają mniej więcej:
1
2
3
...
aa
bb
..
aa
bb
..


A powinne wyglądać:
1
2
3
..
aaa
aab
aac
...
P-155383
Gabes
» 2016-12-25 12:18:54
Dodać losowość.
P-155400
Tomal
Temat założony przez niniejszego użytkownika
» 2016-12-25 13:07:14
Tylko wtedy będę bazować na tym jak mi się wylosuje, a ja chce miec konkretnie baze kolejnych kombinacji znaków. Czyli np dla jedynki to jest około 94 znaki, dla dwójki to już będzie 94 do kwadratu (z kombinatoryki), czyli ponad 8800.

Napisałem nowy kod, gdzie to mniej więcej działa poprawnie, ale ostatnie 100 wyrazów z racji nowego rozwiązania są nieprawidłowo dopisywane.
Może tutaj by ktoś znalazł błąd/ jak to poprawić.

C/C++
#include <iostream>
#include <fstream>
#include <cmath>
#include <stdio.h>

using namespace std;

char znak( int a )
{
    char c;
    return c = 33 +( a % 94 );
}

void generator( string * tab, long long int rozmiar, int n )
{
    int a = 0;
    if( n > 1 )
    {
        for( int i = 0; i < rozmiar; i++ )
        {
            a = i / 94;
            tab[ i ] += tab[( i + a ) % rozmiar ];
        }
        generator( tab, rozmiar, n - 1 );
    }
}

int main()
{
    ofstream ciag;
    string * tab;
    long long int rozmiar = 1;
    int n = 2;
    for( int z = 0; z < n; z++ )
         rozmiar = rozmiar * 94;
   
    tab = new string[ rozmiar ];
    for( int i = 0; i < rozmiar; i++ )
         tab[ i ] += znak( i );
   
    generator( tab, rozmiar, n );
    ciag.open( "ciag.txt", ios::in | ios::out );
    for( int i = 0; i < rozmiar; i++ )
         ciag << tab[ i ] << endl;
   
    ciag.close();
    delete[] tab;
    return 0;
}

P-155404
mokrowski
» 2016-12-25 15:20:02
Może podpowiem. Wyświetlony ciąg znaków uzależnij od licznika. Ostatni znak to: Licznik % długość_całej_sekwencji_możliwych_znaków, przed ostatni to: licznik = licznik / długość_całej_sekwencji_możliwych_znaków itd.
Tu masz na szybko napisany przykład do samodzielnego przestudiowania i ew. poprawienia :-) Starałem się by było "szkolnie" .
C/C++
#include <iostream>
#include <limits>
#include <string>

using namespace std;

size_t getSequenceLength() {
    size_t length;
    while( true ) {
        cout << "Podaj długość sekwnencji znaków większą od 0: ";
        cin >> length;
        if( !cin ) {
            cerr << "Nieprawidłowa długość sekwnecji. Powtarzamy aż do skutku!" << endl;
            cin.clear();
            cin.ignore( numeric_limits < streamsize >::max(), '\n' );
            continue;
        }
        break;
    }
   
    return length;
}

string getSequenceString( size_t counter ) {
    static const string sequenceChars( "0123456789abcdefghijklmnopqrstuvwxyz" );
    static const size_t seqLength = sequenceChars.length();
    string answer;
    do {
        answer += sequenceChars[ counter % seqLength ];
        counter /= seqLength;
    } while( counter != 0 );
    // Tu możesz ew. odwrócić ciąg jeśli nie odpowiadają Ci takie wyniki.
    return answer;
}

int main() {
    size_t count = getSequenceLength();
    size_t counter = 0;
    string sequence;
    while(( sequence = getSequenceString( counter++ ) ),( count >= sequence.length() ) ) {
        cout << sequence << "\n";
    }
   
}
P-155413
Tomal
Temat założony przez niniejszego użytkownika
» 2016-12-25 17:07:17
O kurde, działa. No nieźle,dzięki wielkie za pomoc. Przestudiuje jak najszybciej!

Temat rozwiązany.
P-155419
mateczek
» 2016-12-26 11:54:27
tu jest jeden problem bo generowanie liczb w sposób po kolei

0 1 2 3 4 5 ....10 11 12 ...99 100
 i mamy cały przekrój. ale jeśli generujemy powiedzmy pin n cyfrowy to potrzebne są zera wodzące i tym samym ciągi znaków


000 001...010 011...099 100

tym samym 1 01 001 to są inne ciągi znaków i mechanizm generowania liczb po kolei zwyczajnie nie jest na to odporny.

C/C++
#include <iostream>
#include <limits>
#include <string>

using namespace std;

size_t getSequenceLength() {
    size_t length;
    while( true ) {
        cout << "Podaj długość sekwnencji znaków większą od 0: ";
        cin >> length;
        if( !cin ) {
            cerr << "Nieprawidłowa długość sekwnecji. Powtarzamy aż do skutku!" << endl;
            cin.clear();
            cin.ignore( numeric_limits < streamsize >::max(), '\n' );
            continue;
        }
        break;
    }
   
    return length;
}

string getSequenceString( size_t counter ) {
    static const string sequenceChars( "0123456789" );
    static const size_t seqLength = sequenceChars.length();
    string answer;
    do {
        answer.insert( answer.begin(), sequenceChars[ counter % seqLength ] );
        counter /= seqLength;
    } while( counter != 0 );
    // Tu możesz ew. odwrócić ciąg jeśli nie odpowiadają Ci takie wyniki.
    return answer;
}

int main() {
    size_t count = getSequenceLength();
    size_t counter = 0;
    string sequence;
    while(( sequence = getSequenceString( counter++ ) ),( count >= sequence.length() ) ) {
        cout << sequence << " ";
    }
   
}
output:
[codoe]

Wygeneruje liczby od 0 do 1000. jednak do wygenerowania wszystkich "pinów" jedno, dwu, lub trzy znakowych. Jeszcze trzeba by pokombinować z dodawaniem zer wodzących i generowanie najpierw ciągu jedno-znakowego potem dwu-znakowego a następnie trzy-znakowego
P-155445
mateczek
» 2016-12-26 13:04:34
troszkę zmodyfikowałem rozwiąznaie poprzednika
C/C++
#include <iostream>
#include<cmath>
#include <limits>
#include <string>

using namespace std;
void SequenceString( int dlugoscCiagu, const string & tablicaZnakow, int rozmiarTablicy ) {
   
    for( int i = 0; i < pow( rozmiarTablicy, dlugoscCiagu ); i++ ) { // liczba elementów ciągu o zadanej dlugości jest równa" liczbieZnaków^dlugośćCiągu
        string tempString;
        int counter = i;
        do {
            tempString.insert( tempString.begin(), tablicaZnakow[ counter % rozmiarTablicy ] );
            counter /= rozmiarTablicy;
        } while( counter != 0 );
       
        int roz = tempString.size();
       
        //pętla dopełnia zera wodzące do żądanej długości ciągu
        for( int k = 0; k <( dlugoscCiagu - roz ); k++ ) {
            tempString.insert( tempString.begin(), tablicaZnakow[ 0 ] );
        }
        cout << tempString << " ";
    }
}

int main() {
   
    const string tablicaZnakow( "abc" );
    int rozmiarTab = tablicaZnakow.size();
    int dlCiag;
    cin >> dlCiag;
    for( int i = 1; i <= dlCiag; i++ ) {
        SequenceString( i, tablicaZnakow, rozmiarTab );
    }
}
P-155449
mokrowski
» 2016-12-26 17:46:47
Oczywiście pewnie w tym przykładzie nie ma co "kruszyć kopii" o zagadnienie wydajności, zwróć jednak uwagę że insert będzie za każdym razem robił niepotrzebne kopiowanie pamięci (konieczność kopiowania "ogona" string'u). Wydajniej będzie dołączyć znak na końcu i ew. jeśli to potrzebne obrócić string. Pozbyć się niepotrzebnych alokacji dynamicznych ew. można także dodając wywołanie reserve() na stringu.
P-155456
« 1 » 2
  Strona 1 z 2 Następna strona