Home > Back-end >  C set of HashMap functions not outputting properly. No errors given
C set of HashMap functions not outputting properly. No errors given

Time:12-13

I am going to provide all of my code below because I cannot figure out where the error is. Functions 5 and 6 are commented out because they cause so many warnings I cannot see any of my output. with those commented out my output is

1

2

Date Name of EmployeeVolunteers

Date Name of Employee 2 Erica 1 Ben

I do not understand why it is printing twice for the final function or why function 1 is not working or why the vector functions return so many warnings and no output.

Any help is greatly appreciated. All notes I have and code I have looked at online seem to have the same code structure as me so I do not understand why it is not working.

#include <iostream>
#include <unordered_map>
#include <vector>
#include <iomanip>
#include <algorithm>

using namespace std;

bool addEmployee(unordered_map <int, string> employeeInfo, string employeeName, int date)
    {
        bool answer = true;
        for(auto item:employeeInfo)
        {
            if(item.first==date)
                answer=false;
        }
            
        if (answer==true)
            employeeInfo[date]=employeeName;
        
        return answer;

    }

string findEmployee (unordered_map <int, string> employeeInfo, int date)
{
        string answer = "";
        for(auto item:employeeInfo)
        {
            if(item.first==date)
               answer=employeeInfo[date];
        }
        return answer;
        
}

int findDate (unordered_map <int, string> employeeInfo, string employeeName)
{
    int answer = -1;
        for(auto item:employeeInfo)
        {
            if(item.second==employeeName)
               answer=item.first;
        }
        return answer;
}

int totalSignedUp (unordered_map <int, string> employeeInfo)
{
    int count=0;
    for (auto item:employeeInfo)
        count=count 1;
    return count;
}


vector<string> employeesByDate (unordered_map <int, string> employeeInfo, int startDate, int endDate)
{
    vector <string> names;
    for(auto item:employeeInfo)
    {
        if (item.first >=startDate && item.first <= endDate)
        {
            names.push_back(item.second);
        }
    }
    return names;
}

vector<string> employees (unordered_map <int, string> employeeInfo)
{
    vector <string> employees;
    for(auto item:employeeInfo)
    {
        employees.push_back(item.second);
    }
    
    return employees;
    
}
void printMonth (string title, unordered_map <int, string> employeeInfo)
{
    cout<<title<<"\n";
    printf("Date    Name of Employee\n");
    for(auto item: employeeInfo)
    {
        cout << item.first << "    " << item.second << endl;
    }
}


int main()
{    
        unordered_map <int, string> employeeInfo;
        employeeInfo[1]="Ben";
        employeeInfo[2]="Erica";
        cout<<addEmployee(employeeInfo,"Sierra", 13)<<"\n";
        cout<<findEmployee(employeeInfo, 13)<<"\n";
        cout<<findDate(employeeInfo, "Erica")<<"\n";
        cout<<totalSignedUp(employeeInfo) "\n";
      //  cout<<employeesByDate(employeeInfo, 1, 10)<<"\n";
      //  cout<<employees(employeeInfo)<<"\n");
        printMonth("Volunteers", employeeInfo);
    
}

Sorry for posting my entire code but I cannot pinpoint where the problem is.

CodePudding user response:

There are several issues with your code:

  1. You are passing std::unordered_map by value. What this means is that the function is working on a temporary copy of the map. The temporary copy is then destroyed at the end of the function, thus you will not see any changes when the function returns.

  2. You are writing functions that you do not need to write. The one glaring case is that you are using a loop to find a key value in std::unordered_map. This defeats the entire purpose of unordered_map, as it is used for fast lookups. You should be using the unordered_map::find() method to search for the key.

  3. You have code that will compile, but is clearly wrong probably due to typos.

    Here is an example:

    cout<<totalSignedUp(employeeInfo) "\n";

    Clearly the extraneous isn't supposed to be there.

Here is a rewrite of your code, addressing the issues outlined:

#include <iostream>
#include <unordered_map>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <string>

using EmployeeInfo = std::unordered_map<int, std::string>;

bool addEmployee(EmployeeInfo& employeeInfo, std::string employeeName, int date)
{
    auto pr = employeeInfo.insert({date, employeeName});
    return pr.second;
}

std::string findEmployee (EmployeeInfo& employeeInfo, int date)
{
    auto iter = employeeInfo.find(date);
    if ( iter != employeeInfo.end())
        return iter->second;
    return {};        
}

int findDate (EmployeeInfo& employeeInfo, std::string employeeName)
{
    auto iter = std::find_if(employeeInfo.begin(), employeeInfo.end(),
                            [&](auto& pr) { return pr.second == employeeName;});
    if ( iter != employeeInfo.end())
        return iter->first;
    return -1;
}

int totalSignedUp (EmployeeInfo& employeeInfo)
{
    return employeeInfo.size();
}

std::vector<std::string> employeesByDate (EmployeeInfo& employeeInfo, 
                                          int startDate, int endDate)
{
    std::vector <std::string> names;
    for ( auto& item : employeeInfo)
    {
        if (item.first >=startDate && item.first <= endDate)
            names.push_back(item.second);
    }
    return names;                 
}

std::vector<std::string> employees (EmployeeInfo& employeeInfo)
{
    std::vector<std::string> employees;
    for(auto& item : employeeInfo)
        employees.push_back(item.second);
    return employees;
    
}
void printMonth (std::string title, EmployeeInfo& employeeInfo)
{
    std::cout<<title<<"\n";
    std::cout << "Date    Name of Employee\n";
    for(auto& item: employeeInfo)
    {
        std::cout << item.first << "    " << item.second << std::endl;
    }
}

int main()
{    
    EmployeeInfo employeeInfo;
    employeeInfo[1]="Ben";
    employeeInfo[2]="Erica";
    std::cout << "Adding employee\n";
    std::cout << (addEmployee(employeeInfo,"Sierra", 13)?"Added OK":"Not Added") << "\n";
    std::cout << "\nFinding employee\n";
    std::cout << findEmployee(employeeInfo, 13) << "\n";
    std::cout << "\nFinding date of Erica\n";
    std::cout<< findDate(employeeInfo, "Erica")<<"\n";
    std::cout << "\nNumber of employees\n";
    std::cout << totalSignedUp(employeeInfo) << "\n";
    std::cout << "\nPrinting employees:\n";
    printMonth("Volunteers", employeeInfo);
}

Output:

Adding employee
Added OK

Finding employee
Sierra

Finding date of Erica
2

Number of employees
3

Printing employees:
Volunteers
Date    Name of Employee
13    Sierra
2    Erica
1    Ben

Not the prettiest output, but it appears.

The changes made were basically what was outlined above as to the mistakes you were making.

  1. Note the usage of using to give an alias to the unordered_map. This makes the coding simpler and less terse.

  2. Note the usage of unordered_map::find() to search for the date.

  3. In addEmployee, the unordered_map::insert() is used. If the item already existed, the returned std::pair has a second that will be set to false. This replaces your entire logic of setting a bool to false.

  4. When searching for the name, since the name isn't a key value, this is where a linear search would have to be done. Given that, the std::find_if is used to linearly search through the map. The returned iterator will either point to the found entry, or employeeInfo.end() if not found.

The rest of the changes should be self-explanatory.

  • Related