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. #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 ]; 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 <<( 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 ... |
|
Gabes |
» 2016-12-25 12:18:54 Dodać losowość. |
|
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ć. #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; } |
|
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" . #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 ); return answer; }
int main() { size_t count = getSequenceLength(); size_t counter = 0; string sequence; while(( sequence = getSequenceString( counter++ ) ),( count >= sequence.length() ) ) { cout << sequence << "\n"; } }
|
|
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. |
|
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. #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 ); 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 |
|
mateczek |
» 2016-12-26 13:04:34 troszkę zmodyfikowałem rozwiąznaie poprzednika #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++ ) { string tempString; int counter = i; do { tempString.insert( tempString.begin(), tablicaZnakow[ counter % rozmiarTablicy ] ); counter /= rozmiarTablicy; } while( counter != 0 ); int roz = tempString.size(); 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 ); } } |
|
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. |
|
« 1 » 2 |