#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <locale.h>
#include <algorithm>
using namespace std;
/*
ELŐDEKLARÁCIÓK (header nélkül):
--------------------------------
Minden másik .cpp-ben megírt függvény itt van kihirdetve, hogy a main meghívhassa.
A megvalósításuk a saját .cpp fájljaikban van — ott NINCS kiírás, csak logika.
*/
// funktorok.cpp
int osszead_funktor_hivas(int a, int b);
double skalar_szorzo_hivas(double c, double x);
// predikatumok_alg.cpp
int db_hosszabb_mint(const std::vector<std::string>& v, size_t n);
int db_kisbetu(const std::string& s);
// lambdak.cpp
int lambdas_osszeadas(int a, int b);
int hozza_k_ertek_szerint(int x, int k);
void ref_capture_novel(int& a, int b);
// hivas_tipusok.cpp
int duplaz_fvptr(int x);
int lambda_pluszegy(int x);
int std_function_valtas(int x, int mode);
// feladatok.cpp
std::vector<int> parosak_kimasolasa(const std::vector<int>& src, int& kidobott_db);
std::vector<std::pair<std::string, int>> gyakorisag(const std::vector<std::string>& szavak);
int main() {
setlocale(LC_ALL, "");
cout << "=== FUNKTOROK és LAMBDAK — labor ===\n\n";
// 1) FUNKTOROK — állapot nélküli és állapotos példa (kívül implementálva)
cout << "[1] Funktorok\n";
cout << "Osszead funktor (2 + 3) = " << osszead_funktor_hivas(2, 3) << endl;
cout << "SkalarSzorzo funktor (c=1.5, x=4.0) = " << skalar_szorzo_hivas(1.5, 4.0) << "\n\n";
// 2) PREDIKÁTUMOK STL algoritmusokhoz
cout << "[2] Predikátumok algoritmusokhoz\n";
vector<string> szavak{ "alma", "Korte", "banan", "szilva", "Citrom" };
cout << "5 karakternél hosszabb szavak száma: " << db_hosszabb_mint(szavak, 4) << endl;
string s = "AbCdEfG";
cout << "Kisbetűk száma \"AbCdEfG\"-ben: " << db_kisbetu(s) << "\n\n";
// 3) LAMBDA — alap és capture minták (érték, referencia)
cout << "[3] Lambda alapok és capture\n";
cout << "lambdas_osszeadas(10, 20) = " << lambdas_osszeadas(10, 20) << endl;
cout << "hozza_k_ertek_szerint(5, k=10) = " << hozza_k_ertek_szerint(5, 10) << endl;
int a = 7;
ref_capture_novel(a, 100); // a referencia-capture miatt módosul
cout << "ref_capture_novel(a=7, b=100) után a = " << a << "\n";
//[=] – mindent érték szerint
int m = 5, n = 3;
auto osszeg_ertek_szerint = [=]() {
// m és n másolatát látja
return m + n;
};
cout << "[=] capture (m=5,n=3) -> " << osszeg_ertek_szerint() << "\n";
// [&] – mindent hivatkozással
auto novel_minden_ref = [&]() {
m += 10;
n += 20;
};
novel_minden_ref();
cout << "[&] capture után m = " << m << ", n = " << n << "\n\n";
// A) Skálázás konfigurálható állandóval – [c] (érték szerinti), mert NEM akarjuk,
// hogy későbbi módosítások megváltoztassák a működést.
double c = 1.5;
auto skala = [c](double x) { return c * x; };
cout << "A) skala(4.0) c=1.5 -> " << skala(4.0) << "\n";
c = 100.0; // NEM hat a már létrehozott lambda-ra (értékmásolat!)
cout << " (c=100-ra állítva kívül) skala(4.0) -> " << skala(4.0) << "\n\n";
// B) Dinamikus küszöb szerinti szűrés – [&threshold] (hivatkozás),
// mert a küszöböt futás közben állítgatjuk, és azt AZONNAL lássa a lambda.
vector<int> minta = { 1,5,7,9,2,10,3 };
int threshold = 5;
auto nagyobb_mint = [&threshold](int x) { return x > threshold; };
cout << "B) threshold=5: nagyobb_mint(7) -> " << nagyobb_mint(7) << "\n";
threshold = 8; // azonnal látszik a változás
cout << " threshold=8: nagyobb_mint(7) -> " << nagyobb_mint(7) << "\n\n";
// C) Akkumulálás algoritmussal – [&sum] (hivatkozás), mert KÍVÜL akarjuk látni az eredményt.
vector<int> nums = { 1,2,3,4 };
int sum = 0;
for_each(nums.begin(), nums.end(), [&sum](int x) { sum += x; } );
cout << "C) for_each + [&sum] akkumulált összeg = " << sum << "\n\n";
// D) Részleges alkalmazás (partial) – [k] érték szerint, készítünk „hozzáadó” függvényt.
int k = 7;
auto addk = [k](int x) { return x + k; };
cout << "D) addk(10) (k=7) -> " << addk(10) << "\n";
k = 100; // nem hat vissza a már elkészült addk-ra
cout << " (k=100 kívül) addk(10) -> " << addk(10) << "\n\n";
// E) Állapot módosítása kívül – [&flag] (hivatkozás), tipikus „toggle”/jelző beállítás.
bool flag = false;
auto jeloles = [&flag]() { flag = true; };
jeloles();
cout << "E) jeloles() után flag = " << (flag ? "true" : "false") << "\n\n";
// F) Prefilter + transzform vektoron – [prefix] érték szerint, mert fix szabály szerint dolgozunk.
vector<string> nevek = { "alfa","beta","gamma","alfa2" };
string prefix = "al";
vector<string> csak_al;
copy_if(nevek.begin(), nevek.end(), back_inserter(csak_al),
[prefix](const string& s) {
return s.size() >= prefix.size()
&& equal(prefix.begin(), prefix.end(), s.begin());
});
cout << "F) copy_if prefix=\"al\" -> ";
for (size_t i = 0; i < csak_al.size(); ++i) cout << csak_al[i] << " ";
cout << "\n\n";
// G) Egyedi rendezési kulcs külső „súlytáblával” – [&w] ref capture:
// nagy/ritka táblát NEM akarunk másolni, csak hivatkozni rá.
int w[256] = { 0 }; // primitív „súlytábla” (ASCII)
w[(unsigned char)'a'] = 1; w[(unsigned char)'b'] = 2; w[(unsigned char)'g'] = 3;
vector<string> vstr = { "beta","alfa","gamma" };
sort(vstr.begin(), vstr.end(),
[&w](const string& A, const string& B) {
auto key = [&w](const string& s) {
int ssum = 0;
for (size_t i = 0; i < s.size(); ++i) ssum += w[(unsigned char)s[i]];
return ssum;
};
int ka = key(A), kb = key(B);
if (ka != kb) return ka < kb;
return A < B; // másodlagos: lexikografikus
});
cout << "G) súlyozott rendezés: ";
for (size_t i = 0; i < vstr.size(); ++i) cout << vstr[i] << " ";
cout << "\n\n";
// H) „Egylövéses” akció – [=] minden érték szerint, biztonságos lezárás (semmit nem ír vissza).
int xh = 3, yh = 4;
auto egyloves = [=]() { return xh * xh + yh * yh; };
cout << "H) [=] egyloves: x^2+y^2 -> " << egyloves() << " (xh=" << xh << ", yh=" << yh << ")\n\n";
// I) Referencia-„drót” két függvény között – [&out] ref capture,
// amikor egy belső függvény számolja ki az eredményt.
int out = 0;
auto belso = [&out](int a_, int b_) { out = (a_ + b_) * (a_ + b_); };
belso(2, 3);
cout << "I) [&out] belső számítás után out = " << out << "\n\n";
// 4) HÍVHATÓK összevetése: fv. mutató, lambda, std::function
cout << "[4] Függvény mutató vs lambda vs std::function\n";
cout << "duplaz_fvptr(10) = " << duplaz_fvptr(10) << endl;
cout << "lambda_pluszegy(10) = " << lambda_pluszegy(10) << endl;
cout << "std_function_valtas(10, mode=0:lambda) = " << std_function_valtas(10, 0) << endl;
cout << "std_function_valtas(10, mode=1:fvptr) = " << std_function_valtas(10, 1) << "\n\n";
cout << "\n=== VÉGE ===\n";
return 0;
}