Podpowiedzi do matury z informatyki

0

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 : )

1

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.

0

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?

1

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(...)) ).

1
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++;

0

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 : )

1
#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++;
1

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.

0

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;
}
1

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.

1

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)
1

A ogarnia ktoś z was CryEngine3?

1

Hahaha, genialna odskocznia od tematu matur :D

Ja z 3D ogarniam tylko Pandę 3D, a do 2D mam własne "technikalia".

0

Poprzedni arkusz pięknie ogarnąłem, cofam się o kolejny rok i proszę o pomoc ; ) Mam takie pytanie:

  1. Czy jest jakaś biblioteka za łatwą konwersje typów string -> int.
  2. Czy dzięki getline() można pobrać jakoś int'a.
  3. 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!

2
  1. standardowa (stoi)
  2. nie bezposrednio
  3. 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.

1
krystiant94 napisał(a):

Poprzedni arkusz pięknie ogarnąłem, cofam się o kolejny rok i proszę o pomoc ; ) Mam takie pytanie:

  1. Czy jest jakaś biblioteka za łatwą konwersje typów string -> int.
  2. Czy dzięki getline() można pobrać jakoś int'a.
  3. 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];
0

"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ć...

0
  1. Jak sprawdzić ostatni char stringa - ja używam napis[napis.length()].
  1. str[str.length()-1] afair

char ostatni = napis.at( napis.length() - 1 );

Najlepiej użyć std::string::back().

1 użytkowników online, w tym zalogowanych: 0, gości: 1