Na początku chciałbym zaznaczyć, że nie chce pokazywać oryginalnego programu na zadanie, bo całkiem nie o to tutaj chodzi. Zaczynam rozwiązywać zadanie z popularnego serwisu z problemami programistycznymi SPOJ. Jakiś czas temu walczyłem, jednak się poddałem – brak chęci do programowania.
Category Archives: C++
Naprawione – problem z funkcją losowania w C++
Na zajęciach programowania, napotkaliśmy na problem który wygląda tak : po wylosowaniu liczb, cały czas zostawały one na poziomie tysięcy/dziesiatek a zmieniały się tylko ich końcówki.
Wyjście:
1346, 1368, 1356 …
Z problemem sobie poradziłem korzystając z biblotek dla funkcji srand. Sprawa tak prosta że az głupia, po prostu zapomnielismy o deklaracji bibloteki <time.h> która odpowiada za obsluge time(null), czyli nasz rdzeń losowania :).
Przykładowy program na którym testowałem funkcje losowania :
#include<iostream>
#include <time.h>
using namespace std;
int main() {
srand ( time(NULL) );
for ( int i=1; i<10; i++ ){
cout<<endl<<"Proba: "<<i<<endl<<endl;
cout<<rand()<<'\n';
cout<<rand()<<'\n';
cout<<rand()<<'\n';
}
system("PAUSE");
return 0;
}Przesyłanie argumentów przez referencję
O co chodzi z tą referencją, i co to takiego jest ?
Patrząc na ekran, po kompilacji programu, zauwazamy ze funkcja, która chciała wyzerować dwa obiekty a i b wysłane do niej jako argumeny, zaskoczyła nas.
Oczywiście obiekt a jest nietknięty. To znamy, jednak obiekt b ma wartość 0, dlaczego?
Kilka słów o funkcji zer:
Widzimy,że to funkcja , która przyjmuje dwa argumenty, pierwszy z nich jest przesyłany – tak jak poprzednio – przez wartość, drugi natomiast jest przesyłany przez referencję. Zauważ znak &.
W main mamy dwie zmienne, które wysyłamy do funkcji zer. Inaczej mówiąc: wywołujemy funkcje zer z parametrami aktualnymi a,b.
Wewnątrz funkcji zer, na moment przed egzekucją, wypisujemy jeszcze wartość dwóch parametrów formalnych wart,ref.
Tu następuje jakaś operacja zmieniająca wartość zmiennych wart i ref.W naszym przypadku wpisanie im zer.
Na dowód, że tak się stało w istocie – wypisujemy ich wartość na ekran.
Kończymy pracę funkcji, będąc już w main wypisujemy na ekranie wartości zmiennych a i b. I tu cała niespodzianka.
a pozostało bez zmian, a b?
pozostało zmienione właśnie ze względu na referencję.
- dwie nazwy ref, b określały ten sam obiekt. W tym cała filozofia referencji w języku C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include<iostream> using std::cin; using std::cout; using std::endl; void zer(int wart, int &ref) { cout<<"\tW funkcji zer przed zerowaniem\n"; cout<<"\twart="<<wart<<"ref."<<ref<<endl; wart = 0; ref = 0; cout<<"\tW funkcji zer po zerowaniu\n"; cout<<"\twart="<<wart<<"ref="<<ref<<endl; } int main() { int a = 44, b= 77; cout<<"Przed wywolaniem funkcji:zer\n"; cout<<"a "<<a<<" b "<<b; zer(a,b); cout<<"Po powrocie z funkcji zer\n"; cout<<" a "<<a<<" b"<<b<<endl; system("PAUSE"); } |
Funkcja inline( w lini )
Program na obliczanie poteg liczb calkowitych z zadanego przedzialu
Przerabiajac książke [ Symfonia C++ ] , znalazłem ciekawy program który oblicza potęge liczby z zadanego mu przedziału.
Warto przetestować, fajny program.
A tak obok, mam zamiar cześciej opisywać takie problemy programistyczne*, z zasaday a może się komuś przyda :)
Zawsze mnie to zmusza, do przepisania kodu z książki, może zapamiętam ![]()
W każdym razie zapraszam do analizy kodu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include<iostream> using std::cout; using std::cin; using std::endl; long potega(int stopien, long liczba); //***************************************************************************** int main() { int pocz, koniec; cout<<"Program na obliczanie poteg liczb calkowitych z zadanego przedzialu\n" <<"Podaj poczatek przedzialu:"; cin>>pocz; cout<<"Podaj koniec przedzialu:"; cin>>koniec; //petla drukujaca wyniki z danego przedzialu for(int i=pocz; i<= koniec; i++ ) { cout<<i <<" Do kwadratu=" <<potega(2,i) <<" a do szczescianu=" <<potega(3,i) <<endl; } system("PAUSE"); } //***************************************************************************** long potega( int stopien, long liczba) { long wynik = liczba; for(int i = 1; i<stopien; i++) { wynik = wynik * liczba; // zwiezlej mozna zapisac to samo jako wynik*=liczba; } return wynik; } |
*Mateusz mam nadzieje że pomożesz
[Zadanie C++] Dodaj dwie tablice – wynik zapisz w trzeciej.
Dokładnie tak jak w temacie, zadanie polega na dodaniu tablicyA+tablicaB = tablicaC.
Dodawanie dwóch tablic do siebie.
Niby proste, ale jednak trochę kodzenia jest. Szczególnie dla początkujących.
Poniżej przedstawiam rozwiązanie problemu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #include<iostream> #include<iomanip> using std::cout; using std::setw; void wypisz(int tab[], int n) { for (int i=0; i<n; ++i) cout<<setw(3)<<tab[i]; } int main() { int tablica[20], tablica2[20], tablica3[20]; srand (time(NULL)); for( int i=0; i<10; ++i) tablica[i] = rand()%10; for( int i=0; i<10; ++i) tablica2[i] = rand()%10; cout << "Tablica wypelniona losowo liczbami z przedzialu <0,10>:\n"; wypisz(tablica,10); cout<<"\n\n"; cout << "Tablica2 wypelniona losowo liczbami z przedzialu <0,10>:\n"; wypisz(tablica2,10); cout<<"\n\n"; cout<<"Dodawanie dwoch tablic\n"; for ( int i = 0; i<10; ++i ) { tablica3[i] = tablica[i] + tablica2[i]; cout<<setw(3)<<tablica3[i]; } cout<<"\n"; system( "PAUSE" ); return 0; } |
* Dzięki Mateusz.
[C++] Szyfr cezara – ulepszony!
Jest takie zadanie ze strony spoj.pl , które wymaga od nas zakodzenia programu który będzie szyfrował tekst konkretnym szyfrem – Szyfr cezara.
Polega on na zamianie liter o 3, czyli a=c itd.
Program poniżej , jest bardziej uniwersalny nie tylko szyfruje – szyfrem cezara ale także innymi szyframi które mu zadamy. Możemy sami ustawić przesunięcie , w szyfrze cezara = 3, w naszym szyfrze może być to 4 ..
Jest zrobiony na tablicy liter ASCII, ponieważ każda litera jest zaprezentowana w ów kodzie zadanie można dość prosto rozwiązać.
#include<iostream> using namespace std; void szyfruj(char tekst[], int klucz) { int i = 0; klucz = klucz%26; // reszta z dzielenia wartosci wpisanego klucza(przesuniecie znaku o całkowitą wielokrotność liczby 26).. while(tekst[i]!='\0') { if((int)tekst[i]>122-klucz) // ograniczenie aby nie wyjść poza zakres alfabetu tekst[i]=(char)((int)tekst[i]+klucz-26); else tekst[i] =(char)((int)tekst[i]+klucz); i++; } } void deszyfruj(char tekst[], int klucz) { int i = 0; klucz = klucz%26; while (tekst[i]!='\0') { if((int)tekst[i]-klucz<97) tekst[i] = (char)((int)tekst[i]-klucz); else tekst[i]=(char)((int)tekst[i]-klucz); i++; } } int main() { char a[50]; int klucz; cout<<"Podaj klucz(dla szyfru CEZARA WPISZ 3 )"; cin>>klucz; cout<<"Tekst do zaszyfrowania:"; cin>>a; cout<<"Tekst zaszyfrowany"; szyfruj(a,klucz); cout<<a<<endl; cout<<"Tekst odszyfrowany: "; deszyfruj(a,klucz); cout<<a<<endl; system("PAUSE"); return 0; }
* Wszystko działa poprawnie, jednak polecam przetestować.
Nie jest to mój kod, lecz kod z książki – jednak bardzo się przydał do zrozumienia tematu.
Losowanie serial, bezsensowny kod
Miałem pomysł na coś fajnego, ale nie do końca umiem go opisać.
Losowanie sezonu 1-10, odcinka 1-24. Wykorzystałem funkcje rand, do losowania.
Tylko nie zrobiłem tablicy, która nie pozwoliłaby na występowania zera.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> #include <conio.h> using namespace std; int main(){ int l,k; srand(time(NULL)); cout<<"Losowanie sezonu friends: "<<endl; int ,j; k=rand()%10+1; cout<<"sezon: "<<k<<endl; cout<<"Losowanie odcinka friends: "<<endl; l=rand()%24; cout<<"Odcinek ktory powinienes obejzec to: "<<l; getch(); return 0; } |
Ćwiczenie z bibloteką String. – Bibloteka STRING cz.2
.. Dalsza część tego co wczoraj próbowałem opanować.
( Będzie łatwiej to przeczytać. )
Wykorzystując tablice możemy stworzyć coś ciekawego, np. zamienić litery w słowie.
Efekt poniżej. Sprawa całkiem prosta.
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Wykorzystanie tablicy. wyswietlenie napisu Kaska #include<iostream> #include<string> using namespace std; int main(){ string s("Baska"); s[0] = 'K'; for ( int i = 0; i < 5; i++ ) cout << s[i]; system("PAUSE"); return 0; } |
—————————————————
string substr(size_type start = 0, size_type ile = npos)
– zwraca napis będący podciągiem napisu na rzecz którego metoda została wywołana.
Podciąg składa się ze znaków od pozycji start i liczy ile znaków.
Jeśli start+ile jest większe niż długość napisu, to błędu nie ma;
do podciągu brane są wszystkie znaki napisu od tego na pozycji start.
Na przykład :
string s(“Pernambuco”);
cout << s.substr(5,3) << endl;
wypisze ' mbu'.
Podajemy string, w tym wypadku "Pernambuco", a poniżej wywołując funkcję substr wybieramy co ma zostać wyświetlone, 5 od początku(Perna, uwzględniamy następną litere czyli M .. ), a po przecinku piszemy ile liter ma zostać wyświetlone( Po tych 5 literach ). - Trochę chaotycznie, jednak wszystko wyjdzie po kompilacji ![]()
Mój test :
1 2 3 4 5 6 7 8 9 | //Test funkcji substr #include<iostream> #include<string> using namespace std; int main(){ string a("Chandler"); cout<<a.substr(2,3)<<endl; // wypisze and system("PAUSE"); return 0; } |
—————————————————
size_type copy(char cn[], size_type ile, size_type start = 0)
- kopiuje do C-napisu cn podciąg złożony z ile znaków, poczynając od tego na pozycji start.
Zwraca liczbę przekopiowanych znaków. Znak ‘ \0′ nie jest dostawiany.
Zwróćmy uwagę na kolejność argumentów start i ile – odwrotną niż w metodzie substr.
Na przykład:
char nap[] = “xxxxxx”;
string s(“Barbara”);
string:
ize_type siz = s.copy(nap,3,2);
cout << "Skopiowano " << siz << " znaki: \n"
<< nap << endl;
wypisze ' Skopiowano 3 znaki: rbaxxx'.
Tak jak podaje to opis wyżej, odwrotna metoda niż w substr, tutaj dodatkowo możemy dodać opis - ile znaków skopiowaliśmy. //s.copy(nap,3,2) - Skopiuj 3 litery zaczynając od 2.//
Używamy tak jak poprzednio string'a + wskazujemy na nasz napis, który wcześniej zadeklarowaliśmy.
Dobra koniec tego, trochę potestujmy.
b.copy(a,3,2)
// char a
Kopiuję 2-litery, licząc od 3 czyli ic
// string b
Kopiuje 3 litery licząc od 2 czyli eyy.
Trochę tak na odwrót, ale mniej więcej idzie się w tym połapać. Poniżej mój test.
1 2 3 4 5 6 7 8 9 10 11 | // Funkcja size_type copy #include<iostream> #include<string> using namespace std; int main(){ char a[] = "Monica"; string b("Joeyy"); string::size_type siz = b.copy(a,3,2); cout<<"Skopiowano "<<siz<<" znaki:\n"<<a<<endl; // Wyswietli "eyyic" system("PAUSE"); return 0; } |
—————————————————
void swap(string s1)
- zamienia napis s1 z tym, na rzecz którego metodę wywołano.
Na przykład:
string s(“Arles”), s1(“Berlin”);
s.swap(s1);
cout << s << " " << s1 << endl;
wypisze ' Berlin Arles'.
Teoretycznie nie widze jakoś zastosowania dla tej funkcji
Równie dobrze możemy dobrze ustawić stringi s1, s.
1 2 3 4 5 6 7 8 9 10 11 | //zamienia napis s1 z wybranym na rzecz swap #include<iostream> #include<string> using namespace std; int main(){ string s("911"), s1("Lot"); s.swap(s1); cout<<s<<" "<<s1<<endl; // Wyswietli Lot 911 cout<<s1<<" "<<s<<endl; // Wyswietli 911 Lot system("PAUSE"); return 0; } |
—————————————————
string& assign(const string& wzor)
string& assign(const char* wzor)
string& assign(string wzor, size_type start, size_type ile)
string& assign(const char* wzor, size_type ile)
string& assign(size_type ile, char c)
string& assign(const char* start, const char* kon)
- ustala zawartość napisu i zwraca odniesienie do niego (zastępuje operator przypisania).
Argumenty mają podobną postać jak dla konstruktorów.
W ostatniej metodzie typem argumentów może być iterator wskazujący na znaki:
na przykład są to po prostu wskaźniki do znaków C-napisu.
W najprostszym przypadku argumentem jest inny napis w postaci napisu C++ lub C-napisu;
tak więc po
string s1(“xxx”), s2(“Zuzia”);
s1.assign(s2);
s2.assign(“Kasia”);
wartością s1 będzie ‘ Zuzia’ a zmiennej s2 ‘ Kasia’.
Tak jak dla konstruktorów, jako argument można podać podnapis napisu C++ o podanej pozycji początku i długości – za duża długość znaczy aż do końca.
Można też podać podnapis C-napisu złożony z podanej liczby znaków licząc od początku:
1 2 3 4 5 6 7 8 9 10 11 | #include<iostream> #include<string> using namespace std; int main(){ string s1("0123456781"), s2; const char* p = "012345526"; s1.assign(s1,3,5); s2.assign(p, 5); cout<<s1<<" "<<s2<<endl; system("PAUSE"); return 0; } |
—————————————————
Za pomocą metody assign można utworzyć napis złożony z ile powtórzeń znaku (piąta forma z wymienionych powyżej).
Można też użyć wskaźników do znaków w C-napisie jako iteratorów wyznaczających podciąg;
trzeba tylko pamiętać, że wskazywany podnapis nie zawiera wtedy znaku wskazywanego jako górne ograniczenie podciągu:
string s1(“0123456789″), s2;
const char* p = “0123456789″;
s1.assign(5,’x');
s2.assign(p+3,p+5);
cout << s1 << " " << s2 << endl;
wypisze ' xxxxx 34'.
1 2 3 4 5 6 7 8 9 10 11 | #include<iostream> #include<string> using namespace std; int main(){ string s1("01234567"), s2; const char* p = "012345"; s1.assign(5, 's'); s2.assign(p+3, p+5); cout<<s1<<" "<<s2<<endl; system("PAUSE"); return 0; } |
Na razie koniec, więcej będę pisał w następnej części.
Tak pozatym Word count: 666.
Ćwiczenie z bibloteką String. – Bibloteka STRING cz.1
Ambitny dość plan, w chwile chciałbym się zaznajomić z całą bibloteką String. No przynajmniej jej ważniejszymi funkcjami, podczas gdy ja będę poznawał i starał się coś nauczyć, wy drodzy czytelnicy również poznacie biblotekę string,
ponieważ będę niżej co nieco pisał, i starał się tłumaczyć na laikowski język.
Post bardziej mając w celu utrwalić moją wiedzę, a Tym samym chciałbym przekazać coś innym.
Początek:
Konstruktory STRING.
/*Konstruktor string,|| Jego szczególnym przypadkiem jest konstruktor, którego dwoma argumentami są dwa wskaźniki do znaków w zwykłym C-napisie: nowo utworzony napis C++ zainicjowany zostanie ciągiem znaków od tego wskazywanego przez pierwszy argument (włącznie) do znaku wskazywanego przez drugi argument, ale bez niego (czyli wyłącznie).*/ #include<iostream> #include<string> using namespace std; int main(){ const char* napis = "0123456789"; string s(napis+1,napis+7); cout<<s<<endl; // wyswietli 123456 system("PAUSE"); return 0; }
Iterator ( Wybieramy co z podanego wyrazu ma zostać wyświetlone, a konkretniej mówiąc proszę spojżeć na kod )
// Iterator #include<iostream> #include<string> using namespace std; int main(){ string s("Czestochowa"); string s1(s.begin()+5, s.end()-2); cout<<s1<<endl; //wyswietl ocho system("PAUSE"); return 0; }
Klasa przypisania String ( W skrócie na wejściu podajemy co ma być posklejane, i zostaje to właśnie zrobione, zostaje wykorzystany tu wskaźnik. )
// Cwiczenie Klasa String klasa przypisania #include<iostream> #include<string> using namespace std; int main(){ const char* cstr = "strin"; string s1, s2, s3, s(" C++"); s1 = cstr; s2 = 'g'; s3 = s; cout<<s1<<s2<<s3<<endl; //wyswietli String C++ system("PAUSE"); return 0; }
Dodanie do napisu String wyrazu( w tym wypadku znaku ‘-’).
// Dodanie do napisu string wyrazu - #include<iostream> #include<string> using namespace std; int main(){ string s1 = "C"; const char* ca = "string"; string s = s1 + '-' + ca; // Wystwiel C-String cout<<s<<endl; system("PAUSE"); return 0; }
W dalszych postach, dalej będę opisywał co możemy zrobić z tą blibloteką.
Komentarze: