User Tools

Site Tools


cpp:lamdas

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
cpp:lamdas [2026/05/21 22:14] – [Παράδειγμα 2ο - Αθροιστής] gthanoscpp:lamdas [2026/05/22 08:13] (current) – [Παράδειγμα 1ο - Φιλτράρισμα και εξαγωγή μέσου όρου] gthanos
Line 64: Line 64:
 === Πως διαχειρίζεται ο compiler το lambda expression; === === Πως διαχειρίζεται ο compiler το lambda expression; ===
  
-Ο compiler μετατρέπει τη λάμδα σε μια ανώνυμη κλάση (anonymous functor). Για την παραπάνω έκφραση //lamda// ο compiler γράφει το εξής:+Ο compiler μετατρέπει τη λάμδα σε μια ανώνυμη κλάση (anonymous functor). Για την παραπάνω έκφραση //lamda// ο compiler δημιουργεί την παρακάτω ανώνυμη κλάση.
  
-<code cpp>+<code cpp lamda2functor.cpp>
 class __lambda_unique_name { class __lambda_unique_name {
 private: private:
Line 121: Line 121:
 </code> </code>
  
-Στο παράδειγμα, η μεταβλητή ''total'' μεταβάλει την τιμή της σε κάθε κλίση της έκφρασης //lamda//. Εδώ η προσθήκη της λέξης //mutable// είναι απαραίτητη και χωρίς αυτή το πρόγραμμα δεν μεταγλωττίζεται. H λέξη //mutable// σηματοδοτεί ότι η μεταβλητή στο //Capture Clause// μπορεί να αλλάξει τιμή. Ο λόγος που συμβαίνει αυτό είναι γιατί η λέξη mutable σηματοδοτεί η συνάρτηση υπερφόρτωσης του τελεστή () δε θα είναι const. Παρακάτω δίνουμε το functor που παράγεται για τη δεδομένη //lambda// έκφραση.+Στο παράδειγμα, η μεταβλητή ''total'' μεταβάλει την τιμή της σε κάθε κλίση της έκφρασης //lamda//. Εδώ η προσθήκη της λέξης //mutable// είναι απαραίτητη και χωρίς αυτή το πρόγραμμα δεν μεταγλωττίζεται. H λέξη //mutable// σηματοδοτεί ότι η μεταβλητή στο //Capture Clause// μπορεί να αλλάξει τιμή. Ο λόγος που συμβαίνει αυτό είναι γιατί η λέξη //mutable// σηματοδοτεί ότι η συνάρτηση υπερφόρτωσης του τελεστή () δε θα είναι const. Παρακάτω δίνουμε την ανώνυμη κλάση (functorπου παράγεται για τη δεδομένη //lambda// έκφραση.
  
-<code cpp >+<code cpp lamda2functor2.cpp>
 class __lambda_accumulator_unique { class __lambda_accumulator_unique {
 private: private:
Line 145: Line 145:
 }; };
 </code> </code>
 +
 +==== Παράδειγμα 3ο - Password Cheker ====
 +
 +Παρακάτω δίνεται ένα πρόγραμμα που διαβάζει από ένα std::vector ένα σύνολο από passwords, εφαρμόζει κάποια κριτήρια για τον αν τα passwords είναι valid ή όχι και εκτυπώνει για κάθε passowrd τη θέση του στη λίστα και τόσα αστεράκια όσα είναι το μέγεθος του. Τα κριτήρια για το αν ένα passowrd είναι valid είναι α) μέγεθος τουλάχιστον 8 χαρκτήρες, β) πρέπει να περιέχει τουλάχιστον ένα πεζό, ένα κεφαλαίο, έναν αριθμό και ένα ειδικό χαρακτήρα. 
 +
 +<code cpp password_checker.cpp>
 +#include <iostream>
 +#include <vector>
 +#include <string>
 +#include <algorithm>
 +#include <cctype>
 +
 +//using namespace std;
 +
 +int main() {
 +    // Λίστα με passwords για έλεγχο
 +    std::vector<std::string> passwords = {
 +        "Pass123!",      // Valid
 +        "weak",          // Invalid (μικρό μέγεθος)
 +        "OnlyLetters",   // Invalid (λείπουν αριθμοί/σύμβολα)
 +        "NoSpecial12",   // Invalid (λείπει ειδικός χαρακτήρας)
 +        "Valid_Pass_2026", // Valid
 +        "12345678",      // Invalid (λείπουν γράμματα)
 +        "Ab1!"           // Invalid (πολύ μικρό)
 +    };
 +
 +    // Λάμδα για τον έλεγχο εγκυρότητας
 +    auto isValid = [specialChars = std::string("!@#$%^&*()-_=+[]{}|;:,.<>?/")](const std::string& p) -> bool {
 +        if (p.length() < 8) return false;
 +
 +        bool hasUpper = false, hasLower = false, hasDigit = false, hasSpecial = false;        
 +
 +        for (char c : p) {
 +            if (std::isupper(c)) hasUpper = true;
 +            else if (std::islower(c)) hasLower = true;
 +            else if (std::isdigit(c)) hasDigit = true;
 +            else if (specialChars.find(c) != std::string::npos) hasSpecial = true;
 +        }
 +
 +        return hasUpper && hasLower && hasDigit && hasSpecial;
 +    };
 +
 +    std::cout << "------- Checking Passwords -----------" << std::endl;
 +    std::cout << "Position | Masked Password | Status" << std::endl;
 +    std::cout << "--------------------------------------" << std::endl;
 +
 +    for (size_t i = 0; i < passwords.size(); ++i) {
 +        bool valid = isValid(passwords[i]);
 +        
 +        // Εκτύπωση θέσης (i + 1)
 +        std::cout << "[" << i + 1 << "     ";
 +
 +        // Εκτύπωση αστερίσκων αντί για το password
 +        std::string masked(passwords[i].length(), '*');
 +        std::cout << masked;
 +
 +        // Ευθυγράμμιση εξόδου (padding)
 +        int padding = 15 - (int)passwords[i].length();
 +        for(int j=0; j < (padding > 0 ? padding : 1); ++j) std::cout << " ";
 +
 +        std::cout << "| " << (valid ? "VALID" : "INVALID") << std::endl;
 +    }
 +
 +    return 0;
 +}
 +</code>
 +
 +==== Παράδειγμα 4ο - Μετασχηματισμός ====
 +
 +Ας υποθέσουμε ότι έχουμε ένα //std::vector// από αντικείμενα τύπου Student (βλέπε παρακάτω) και θέλουμε να μετασχήματίσουμε τα αντικείμενα αυτά ώστε να κρατήσουμε μόνο τους φοιτητές με ΑΕΜ από 1000 εως 2000 και το αποτέλεσμα να το εισάγουμε σε ένα νέο //std::vector// ή ένα νέο //std::set//.
 +
 +<code cpp Student.hpp>
 +#ifndef _STUDENT_HPP_
 +#define _STUDENT_HPP_
 +#include <cstring>
 +#include <iostream>
 +
 +class Student {
 +private:
 +  char *name;
 +  int aem;
 +public:
 +  Student();
 +  Student(const char *name, int aem);
 +  Student(const Student& );
 +  ~Student();
 +  
 +  char* getName() const;
 +  int getAEM() const;  
 +  void setName(char*);
 +  void setAEM(int);
 +  
 +  friend std::ostream& operator<<(std::ostream& out, const Student & st);
 +  bool operator>(const Student& st) const;
 +  bool operator<(const Student& st) const;
 +  Student& operator=(const Student& st);
 +};
 +
 +Student::Student(const char *name, int aem) {
 +  this->name = new char [strlen(name) + 1];
 +  strcpy(this->name, name);
 +  this->aem = aem;
 +  std::cerr << "Argu Construct : " << *this << std::endl;
 +}
 +
 +Student::Student(const Student& st) {
 +  name = new char [strlen(st.name) + 1];
 +  strcpy(name, st.name);
 +  aem = st.aem;
 +  std::cerr << "Copy Construct : " << *this << std::endl;
 +}
 +
 +Student::Student() {
 +  this->name = nullptr;
 +  this->aem = 0;
 +}
 +
 +Student::~Student() {
 +  if(name != nullptr) {
 +    std::cerr << "Destruct: " << *this << std::endl;
 +    delete []name;
 +  }
 +}
 +
 +char* Student::getName() const {
 +  return name;
 +}
 +
 +int Student::getAEM() const {
 +  return aem;
 +}
 +
 +void Student::setName(char* name) {
 +  this->name != nullptr;
 +  delete this->name;
 +  this->name = new char [strlen(name) + 1];
 +  strcpy(this->name, name);
 +}
 +
 +void Student::setAEM(int aem) {
 +  this->aem = aem;
 +}
 +
 +Student& Student::operator=(const Student& st) {
 +  if(name != nullptr)
 +    delete name;
 +  name = new char [strlen(st.name) + 1];
 +  strcpy(name, st.name);
 +  aem = st.aem;
 +  std::cerr << "Copy : " << *this << std::endl;
 +  return *this;
 +}
 +
 +std::ostream& operator<<(std::ostream& out, const Student& st) {
 +  if(st.name != nullptr)
 +    out << st.name << " " << st.aem;
 +  return out;
 +}
 +
 +bool Student::operator>(const Student& st) const {
 +  if(aem > st.aem)
 +    return true;
 +  return false;
 +}
 +
 +bool Student::operator<(const Student& st) const {
 +  if(aem < st.aem)
 +    return true;
 +  return false;
 +}
 +#endif
 +</code>
 +
 +<code cpp trasfrorm_vector2vector.cpp>
 +#include <iostream>
 +#include <vector>
 +#include <algorithm> // Για το std::copy_if
 +#include <iterator>  // Για το std::back_inserter
 +#include "Student.hpp"
 +
 +int main() {
 +    // 1. Αρχικό vector με 5 αντικείμενα Student
 +    std::vector<Student> students;
 +    students.push_back(Student("Giannis", 1050));
 +    students.push_back(Student("Maria", 950));
 +    students.push_back(Student("Kostas", 1500));
 +    students.push_back(Student("Eleni", 2500));
 +    students.push_back(Student("Nikos", 1999));
 +
 +    // 3. Το ΝΕΟ vector όπου θα αποθηκευτούν οι φοιτητές που θα "επιζήσουν"
 +    std::vector<Student> filteredStudents;
 +
 +    std::cout << "\n--- Φιλτράρισμα με Lambda σε νέο Vector ---\n" << std::endl;
 +
 +    // 2. Φιλτράρισμα και αποθήκευση στο νέο vector
 +    std::copy_if(students.begin(), students.end(), 
 +                 std::back_inserter(filteredStudents), // Εισαγωγή στο τέλος του νέου vector
 +                 [](const Student& st) {
 +                     return st.getAEM() >= 1000 && st.getAEM() <= 2000;
 +                 });
 +
 +    // Εκτύπωση των αποτελεσμάτων του νέου vector
 +    std::cout << "\n--- Φοιτητές στο Νέο Vector ---" << std::endl;
 +    for (const auto& student : filteredStudents) {
 +        std::cout << student << std::endl;
 +    }
 +    
 +    std::cout << "\n--- Τέλος Προγράμματος ---" << std::endl;
 +    return 0;
 +}
 +</code>
 +
 +<code cpp trasfrorm_vector2set.cpp>
 +#include <iostream>
 +#include <vector>
 +#include <set>
 +#include <algorithm> // Απαραίτητο για το std::copy_if
 +#include <iterator>  // Απαραίτητο για το std::inserter
 +#include "Student.hpp"
 +
 +int main() {
 +    // 1. Δημιουργία vector με 5 αντικείμενα Student
 +    std::vector<Student> students;
 +    students.push_back(Student("Giannis", 1050));
 +    students.push_back(Student("Maria", 950));
 +    students.push_back(Student("Kostas", 1500));
 +    students.push_back(Student("Eleni", 2500));
 +    students.push_back(Student("Nikos", 1999));
 +
 +    // 3. Το set όπου θα αποθηκευτούν οι φοιτητές που θα "επιζήσουν"
 +    std::set<Student> filteredStudents;
 +
 +    std::cout << "\n--- Φιλτράρισμα με Lambda και std::copy_if ---\n" << std::endl;
 +
 +    // 2. Φιλτράρισμα και αποθήκευση ταυτόχρονα
 +    std::copy_if(students.begin(), students.end(), 
 +                 std::inserter(filteredStudents, filteredStudents.end()), 
 +                 [](const Student& st) {
 +                     return st.getAEM() >= 1000 && st.getAEM() <= 2000;
 +                 });
 +
 +    // Εκτύπωση των αποτελεσμάτων
 +    std::cout << "\n--- Φοιτητές στο Set ---" << std::endl;
 +    for (const auto& student : filteredStudents) {
 +        std::cout << student << std::endl;
 +    }
 +    
 +    std::cout << "\n--- Τέλος Προγράμματος ---" << std::endl;
 +    return 0;
 +}
 +</code>
 +
 +
 +
  
  
cpp/lamdas.1779401671.txt.gz · Last modified: 2026/05/21 22:14 by gthanos