Cześć! Zaczynam przygotowania do matury z informatyki, przerabiam arkusze i mam do Was taką prośbę. Robię zadania maturalne na logikę i często chyba nie wykorzystuje tego, co umożliwili nam twórcy bibliotek c++ (w szczególności fstream i string). Proszę o napisanie w jak najłatwiejszy sposób zrobić te zadania. Nie chodzi o gotowe rozwiązania a podpowiedzi z jakich funkcji korzystać i jakie funkcje mogę stworzyć. Z góry dzięki : )
Jeśli podasz plik na standardowe wejście w linii poleceń, to nie będziesz musiał nawet fstream używać. Chociaż to jest bardziej mechanizm systemu operacyjnego, to ja nie widzę przeszkód, by go użyć ;)
program < plik_wejsciowy.txt > plik_wyjsciowy.txt
Masz w treści zadania podane, że plik ma 1000 linii, więc sprawa wygląda bardzo prosto.
A program można tak zacząć:
#include <iostream>
using namespace std;
int main()
{
string s;
int parzyste=0; // a)
int zera_jedynki=0; // b)
int same_zera=0; // c1)
int same_jedynki=0; // c2)
int tab_k[17]={0}; // d)
for (int i=0;i<1000;i++)
{
cin >> s;
if (s.length()%2==0)
parzyste++;
}
cout << "a) Napisow o parzystej dlugosci jest: " << parzyste << endl;
return 0;
}
Do tego, żeby było klarowne można podopisywać funkcje wykonujące obliczenia na stringach według podpunktów.
Rozumiem, ale w tym przypadku co napisałeś teraz trzeba recznie wpisywac liczby. Ja z fstream używałem - dopóki !eof to getline do stringa i wtedy porównywałem i nie ma innej metody bez tej biblioteki ? A co do drugiego podpunktu jak ułożyc taka funkcje? Bo każdy kolejny obiekt musi być porównywany z wszystkimi następnymi prawda?
up:
Np. można wykorzystać operator >> dla std::ifstream; można pozbyć się tego sprawdzania eof i dać tylko getline np. w while ( while(getline(...)) ).
krystiant94 napisał(a):
A co do drugiego podpunktu jak ułożyc taka funkcje? Bo każdy kolejny obiekt musi być porównywany z wszystkimi następnymi prawda?
Nieprawda :) To by było przegięcie. Chodzi o to, żeby zliczyć zera i jedynki jednego stringa i jeśli liczba zer i jedynek są sobie równe to zera_jedynki++;
Jezu... do matury chce podchodzić a nie umiem przeczytać dokładnie. Ja zrozumiałem to polecenie, jako że ile jest stringów, które mają taką samą ilość zer i jedynek. A macie pomysł jak szybko sprawdzić ilość zer i jedynek, bo ja każdego stringa rozbijam na tablice i wtedy to wykonuje. Dzięki bardzo za pomoc chłopaki : )
#include <algorithm>
std::string s;
[...]
size_t zera = std::count(s.begin(), s.end(), '0');
size_t jedynki = std::count(s.begin(), s.end(), '1');
if (zera==jedynki)
zera_jedynki++;
Calosc mozesz upchnac w foreachu (tym z algorithm) i dodajac obiekt klasy zawierajacej wszystkie potrzebne dane. W tej klasie fajnie by bylo miec operator<< (no i operator(), ale to mus, dla foreacha). Nie dosc, ze bedzie ladnie wygladac, to nie zajmie duzo miejsca i czasu.
Zrobiłem taki programik, wszystkie podpunkty dobrze rozwiązane bo sprawdziłem w kluczu. Czy jeżeli używam tablicy w taki sposób ja na przykładzie, użyłem dużej ilości funkcji i akurat w taki sposób to uciekną mi punkty? Liczy się efekt końcowy - tzn jeżeli zrobię byle jaki program napisany byle jak, ale odpowiedzi będą dobre, nie będzie problemów?
#include <iostream>
#include <conio.h>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
void wczytywanieNapisow(string napisy[1000])
{
fstream dane;
dane.open("napisy.txt");
for(int i = 0; i < 1000; i++) getline(dane,napisy[i]);
dane.close();
}
int funkcjaA(string napisy[1000])
{
int licznik = 0;
for(int i = 0; i < 1000; i++) if(napisy[i].length() % 2 == 0) licznik++;
return licznik;
}
int funkcjaB(string napisy[1000])
{
int licznik = 0;
for(int i = 0; i < 1000; i++)
{
size_t zera = std::count(napisy[i].begin(), napisy[i].end(), '0');
size_t jedynki = std::count(napisy[i].begin(), napisy[i].end(), '1');
if(zera == jedynki) licznik++;
}
return licznik;
}
int funkcjaC1(string napisy[1000])
{
int licznik = 0;
for(int i = 0; i < 1000; i++)
{
size_t zera = std::count(napisy[i].begin(), napisy[i].end(), '0');
if(zera == napisy[i].length()) licznik++;
}
return licznik;
}
int funkcjaC2(string napisy[1000])
{
int licznik = 0;
for(int i = 0; i < 1000; i++)
{
size_t jedynki = std::count(napisy[i].begin(), napisy[i].end(), '1');
if(jedynki == napisy[i].length()) licznik++;
}
return licznik;
}
void funkcjaD(string napisy[1000], int iloscLiczb[17])
{
for(int i = 0; i < 1000; i++)
{
iloscLiczb[napisy[i].length()]++;
}
}
int main()
{
fstream odpowiedzi;
odpowiedzi.open("zadanie4.txt", ios::out | ios::trunc);
string napisy[1000];
int liczbyParzyste; //A
int tyleSamoCyfr; //B
int sameZera; //C1
int sameJedynki; //C2
int iloscLiczb[17];
for(int i = 2; i <= 16; i++) iloscLiczb[i] = 0;
wczytywanieNapisow(napisy);
odpowiedzi << "a) Napisy parzyste = " << funkcjaA(napisy) << endl;
odpowiedzi << "b) Napisy z taka sama iloscia zer i jedynek = " << funkcjaB(napisy) << endl;
odpowiedzi << "c1) Napisy z sama iloscia zer = " << funkcjaC1(napisy) << endl;
odpowiedzi << "c2) Napisy z sama iloscia jedynek = " << funkcjaC2(napisy) << endl;
funkcjaD(napisy, iloscLiczb);
odpowiedzi << "d) Ilosc napisow w zaleznosci od ich dlugosci" <<endl;
for(int i = 2; i <= 16; i++)
{
odpowiedzi << " " << i << " znakowych = "<<iloscLiczb[i] << endl;
}
return 0;
}
W kluczu do zadania powinno być napisane co jest punktowane ;)
Moim zdaniem nie powinieneś wczytywać całego pliku do pamięci, bo zadanie tego nie wymaga. Możesz podczas przelatywania po pliku naliczać liczniki, a funkcje niech zwracają bool. To co masz teraz wykonuje 1000 iteracji na podpunkt + 1000 iteracji na wczytanie danych z pliku, a przecież jedna pętla przelatująca po wszystkich liniach pliku mogłoby wykonać 1000 iteracji na całe zadanie.
BTW. w świecie programowania taki 1000 ni z gruszki, ni z pietruszki nazywa się "magic number". Żeby przestał być "magic", to trzeba go zadeklarować słownie przy użyciu np. #define i wszędzie w programie, gdzie ma być ten 1000 wpisujesz nazwę stałej/define.
Raczej efektywność programu nie ma większego znaczenia, bo to nie jest olimpiada. Jeśli chodzi o te zadanie, to ja bym napisał to w jednej pętli, no ale jak kto woli.
Zamiast:
void wczytywanieNapisow(string napisy[1000])
Lepiej:
void wczytywanieNapisow(string napisy[], const size_t rozmiar)
Lub:
void wczytywanieNapisow(string* napisy, const size_t rozmiar)
A ogarnia ktoś z was CryEngine3?
Hahaha, genialna odskocznia od tematu matur :D
Ja z 3D ogarniam tylko Pandę 3D, a do 2D mam własne "technikalia".
Poprzedni arkusz pięknie ogarnąłem, cofam się o kolejny rok i proszę o pomoc ; ) Mam takie pytanie:
- Czy jest jakaś biblioteka za łatwą konwersje typów string -> int.
- Czy dzięki getline() można pobrać jakoś int'a.
- Jak sprawdzić ostatni char stringa - ja używam napis[napis.length()].
Chodzi głównie o pomoc przy punkcie b i c matury z tej strony (zadanie4) http://www.cke.edu.pl/images/stories/00000000000000002012_matura2012/infor/a2_pp.pdf. Z góry dzięki!
- standardowa (stoi)
- nie bezposrednio
- str[str.length()-1] afair
b)
vector<int> max;
int maxtmp;
foreach(istream_iterator<string>(cin), istream_iterator<string>(), [](const string& str)
{
int sum=0;
for(const char ch : str) sum += ch;
if(sum>maxtmp) {max.clear(); max.push_back(stoi(str)); maxtmp = sum; }
// ...
})
c) rownie proste, wiec napisz sam.
Do b) nawet nie trzeba vectora, bo chodzi o 1 liczbe.
krystiant94 napisał(a):
Poprzedni arkusz pięknie ogarnąłem, cofam się o kolejny rok i proszę o pomoc ; ) Mam takie pytanie:
- Czy jest jakaś biblioteka za łatwą konwersje typów string -> int.
- Czy dzięki getline() można pobrać jakoś int'a.
- Jak sprawdzić ostatni char stringa - ja używam napis[napis.length()].
Chodzi głównie o pomoc przy punkcie b i c matury z tej strony (zadanie4) http://www.cke.edu.pl/images/stories/00000000000000002012_matura2012/infor/a2_pp.pdf. Z góry dzięki!
Ad. 1 istringstream
- Konwersje int na string i string na int
Ad. 2 A po co w taki sposób? http://www.cplusplus.com/forum/unices/10761/
Ad. 3
char ostatni = napis.at( napis.length() - 1 );
lub
char ostatni = napis[napis.length() - 1];
"Podaj liczbę z pliku cyfry.txt, której suma cyfr jest największa oraz liczbę z tego pliku, której suma cyfr jest najmniejsza. W obu przypadkach jest tylko jedna taka liczba." Chciałem to zrobić tak, że jedna pętla jest odpowiedzialna za pobieranie jednego napisu z pliku, wtedy wchodzi tu druga pętla i ona zlicza każdą cyfre, jak jest większa to zapisuje ją i porównuje z kolejnym, ale mam problem, bo albo konwertuje napis na cyfrę i nie moge użyć zliczania w formie tablicy, a jak to jest string to nie moge tego dodać...
- Jak sprawdzić ostatni char stringa - ja używam napis[napis.length()].
- str[str.length()-1] afair
char ostatni = napis.at( napis.length() - 1 );
Najlepiej użyć std::string::back()
.