Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Schimbare adresa DNS IPv4 pe rout...

Recomandare Barebone

Monede JO 2024

Suprasolicitare sistem electric
 CIV auto import

Mutare in MOZAMBIC - pareri, expe...

Scoatere antifurt airtag de pe ha...

Magnet in loc de clește pent...
 Cumparat/Locuit in apartament si ...

Pot folosi sistemul PC pe post de...

Sokol cu distorsiuni de cross-over

Filtru apa potabila cu osmoza inv...
 Kanal D va difuza serialul “...

Upgrade xiaomi mi11

securitate - acum se dau drept - ...

Farmacia Dr Max - Pareri / Sugest...
 

Coroutines – cod ce pare a sfida logica

- - - - -
  • Please log in to reply
3 replies to this topic

#1
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,236
  • Înscris: 24.02.2007
Recent dorea cineva sa populeze o matrice cu numere prime: https://forum.softpe...-in-codul-asta/ (ignoram detaliul ca le si ridica la puterea a 3-a)

A rezultat urmatorul cod:
for (i = 1; i <= n; i++)
	for (j = 1; j <= n; j++) {
		if (prim(z))
			a[i][j] = z * z * z;
		else {
			while (!prim(z))
				z++;
			a[i][j] = z * z * z;
		}
		z++;
	}


Codul, foarte reprezentativ pentru genul de cod scris de elevi/studenti vine cu o sumedenie de probleme:
  • while in else in for in for Posted Image ... am pierdut sirul (da, codul scris de elevi e adesea write-only, nici cine l-a scris nu-l mai intelege peste cateva luni, fara a depune efort)
  • Cine-i z? [5 minute mai tarziu], aaa... z e numarul prim curent. De ce i-o zice z si nu numarPrimCurent?
  • Iterarea prin matrice se amesteca cu logica de iterare prin numerele prime. Daca vreau sa populez un vector, copiez iar tot acel if, else, while
  • Saraca functie prim o ia mereu de la inceput, cand ar putea sari multi pasi: daca am vazut ca i nu divide pe 2 sau 3, e clar ca nu divide nici multipli ai acestora

Exista vreun mod de a curata codul, a separa popularea matricii de iterarea prin numere prime si a imbunatatii si performanta?

Exista o metoda, ce, suprinzator, poate conduce si la mai putin cod. Posted Image

#include <iostream>
#include <vector>

#include <boost/coroutine2/coroutine.hpp>

using namespace boost::coroutines2;

coroutine<unsigned int>::pull_type genereazaNumerePrime([&](coroutine<unsigned int>::push_type& ofera)
{
	ofera(2);
	std::vector<unsigned int> valoriDejaGasite;//nu-l includem si pe 2 deoarece iteram doar prin numere impare

	for (unsigned int i = 3; ; i += 2)
	{
		bool eNumarPrim = true;
		for (auto numarPrim : valoriDejaGasite)
		{
			if ((i % numarPrim) == 0)
			{
				eNumarPrim = false;
				break;
			}
		}
		if (eNumarPrim)
		{
			valoriDejaGasite.push_back(i);
			ofera(i);
		}
	}
});

int main()
{
	unsigned int matrice[10][10];

	auto generator = begin(genereazaNumerePrime);
	for (unsigned int y = 0; y < 10; ++y)
	{
		for (unsigned int x = 0; x < 10; ++x, ++generator)
		{
			matrice[y][x] = *generator;
		}
	}

	//afisare matrice...
}


Posted Image

Quote

Pai vad un loop infinit in acel
for (unsigned int i = 3; ; i += 2)
Se mai termina codul asta de executat?

Surprinzator: da.

Attached File  Untitled.png   25.35K   38 downloads

Pe scurt, coroutines permit transferul executiei dintr-o parte in alta, cele doua functii ruland cu schimbul

  • Iterarea prin matrice ajunge sa ceara urmatorul numar prim si transfera executia functiei generatoare
  • Functia generatoare gaseste urmatorul numar prim si paseaza mingea inapoi la iterarea prin matrice

Rezultatul:
  • Popularea matricii e foarte simpla, codul fiind aproape la fel de simplu cu acel ce ar popula-o cu o constanta.
  • Codul ce itereaza prim numerele prime e si el simplu. Nu-i pasa ce se va intampla cu fiecare numar gasit, codul doar il ofera
  • Codul ce itereaza prin numerele prime poate fi scris mai eficient, pastrand numerele gasite pana atunci si verificand divizibilitatea doar cu acestea.

Nu e un subiect chiar usor. Cine e curios de mai multe are la dispozitie documentatia: http://www.boost.org...html/index.html

Edited by dani.user, 11 November 2017 - 11:26.


#2
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Articolul e bine venit.

Cred că cei care ar beneficia cel mai mult de pe urma articolului nu s-ar descurca cu instalarea boost și cu linkerul.

În Ubuntu e simplu: apt-get install libboost-all-dev
ArchLinux:  pacman -S boost

Similar și în alte distribuții.

Poate un CMakeFiles ar fi o idee bună.

#3
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,236
  • Înscris: 24.02.2007
Nu e chiar grea compilarea din sursa a boost (vreo doua comenzi), dar pun diversi builduri gata facute si pentru Windows: https://sourceforge....boost-binaries/ (trebuie aleasa arhiva pentru versiunea de Visual Studio ce urmeaza a fi folosita, ABI-ul nu e compatibil intre versiuni).

Mai departe, pentru proiectul in cauza:
  • Click dreapta -> Properties pe proiect
  • VC++ Directories
  • Se adauga folderul de include sub Include Directories
  • Se adauga folderul cu lib-uri sub Library Directories
  • Compile/run

VS 2017 stie lucra si cu CMakeFiles direct.

Edited by dani.user, 11 November 2017 - 12:20.


#4
Daniel2222

Daniel2222

    Junior Member

  • Grup: Members
  • Posts: 196
  • Înscris: 21.07.2015
Vad ca si tu ai folosit for in for.
Nu vreau sa crezi ca am vreo intentie sa te atac in vreun fel, vreau sa inteleg de ce in codul tau ai folosit tot for in for.
Ce stiu eu despre Coroutines este ca, la un anumit punct, cedeaza executia catre firul principal si dupa asta revin/e in locul unde a/u cedat executia.
De asta ai folosit for in for? Pentru ca oricum nu asteapta pana termina primul for?


//Edit:
M-am grabit, nu am citit cu atentie si din aceasta cauza am inteles ca ai zis ca nu e bine sa folosesti for in for. Dar nu e cazul, tot ce am scris mai sus nu are sens, scuzati.
Se poate sterge.

Edited by Daniel2222, 11 November 2017 - 13:39.


Anunturi

Bun venit pe Forumul Softpedia!

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate