在类对象数组中搜索

searching through an array of class objects c++

本文关键字:搜索 数组 对象      更新时间:2023-10-16

我需要帮助尝试搜索类对象数组。我有一个类叫用户,并有一个数组,其中3名球员存储。我希望能够在输入一个特定球员的两个名字时显示他的信息,并在输入他的名字时删除他的记录。

我知道我可以使用向量列表来使这更容易,但是我设置了限制。我也认为可以实现线性搜索,但我不知道这是否足够有效。

#include <iostream>
#include <string>
#include <math.h>
using namespace std;
void storeinfo() ;
void showinfo() ;
void menu() ;

class user 
{
    string firstname, lastname, currentteam, position, status ;
    int age ;
public:
    user() {};
    user(string fname, string lname, string cteam, string pos, string stat, int age) 
    {
        setFirstName(fname);
        setLastName(lname);
        setCurrentTeam(cteam);
        setPosition(pos);
        setStatus(stat);
        setAge(age);
    } ;
    void setFirstName(string fname)
        {firstname = fname;}
    void setLastName(string lname)
        {lastname = lname;}
    void setCurrentTeam(string cteam)
        {currentteam = cteam;}
    void setPosition(string pos)
        {position = pos;}
    void setStatus(string stat)
        {status = stat;}
    void setAge(int _age)
        {age = _age;}
    string getFirstName()
        {return firstname ;}
    string getLastName()
        {return lastname ;}
    string getCurrentTeam()
        {return currentteam ;}
    string getPosition()
        {return position ;}
    string getStatus()
        {return status ;}
    int getAge()
        {return age ;}
};
user player[20] ;
int main()
{
    menu() ;

    cin.get() ;
    return 0 ;
}
void storeinfo()
{
    string firstname ;
    string lastname ;
    string currentteam ;
    string position;
    string status ;
    int age ;
    for (int i=0; i < 3; i++)
    {
        cout << "Enter First Name : " ; 
        cin >> firstname ;
        player[i].setFirstName(firstname) ;
        cout << "Enter Last Name : " ; 
        cin >> lastname ;
        player[i].setLastName(lastname) ;
        cout << "Enter Player's Age : " ; 
        cin >> age;
        player[i].setAge(age) ;
        cout << "Enter Current Team : " ; 
        cin >> currentteam ;
        player[i].setCurrentTeam(currentteam) ;
        cout << "Enter Position : " ; 
        cin >> position ;
        player[i].setPosition(position) ;
        cout << "Enter Status : " ; 
        cin >> status ;
        player[i].setStatus(status) ;
        cout << "nnn" ;
    }
    /*cout << string(50, 'n');*/
    menu() ;
}
void showinfo()
{
    for (int i=0; i < 3; i++)
    {
        cout << "First Name : " << player[i].getFirstName() << "n" << "Last Name : " << player[i].getLastName() <<
            "n" << "Age : " << player[i].getAge() << "n" << "Current Team : " << player[i].getCurrentTeam() << 
            "n" << "Position : " << player[i].getPosition() << "n" << "Status :  " << player[i].getStatus()  << "nn";
    }
    cin.get() ;
    menu() ;
}
void menu()
{
    cout << "n MENU" << "n" ;
    cout << "n 1. Store Player Information" ;
    cout << "n 2. Show Player Informaton" ;
    cout << "n 0. Exit n n" ;
    string x =  "";
    cin >> x ;
    if (x=="a")
    { 
        storeinfo() ;
    }
    else if (x=="b")
    {
        showinfo() ;
    }
    else if (x=="c")
    {
        exit(0) ;
    }
    else
    {
        cout << "Invalid Choice" ;
        menu() ;
    }   
}

我已经做了一个线性搜索算法,似乎正在工作,但我得到的输出是不正确的,下面是两个函数的代码,再次感谢你

int linsearch(string val)
{
    for (int j=0; j < 3; j++)
    {
        if  (player[j].getLastName()==val)
        {
            return j;
        }
        else 
        {
            return 1;
        }
    }


void showinfo()
{
    string search;
    int found ;

    cout << "Please Enter The Player's Last Name : " ;
    cin >> search ;
    found=linsearch(search);
    if (found== 1)
    {
        cout << "n There is no player called " << search ;
    }
    else
    {
        cout << "n First Name : " << player[found].getFirstName() << "n" << "Last Name : " << player[found].getLastName() <<
            "n" << "Age : " << player[found].getAge() << "n" << "Current Team : " << player[found].getCurrentTeam() << 
            "n" << "Position : " << player[found].getPosition() << "n" << "Status :  " << player[found].getStatus()  << "nn";
    }
    cin.get() ;
    menu() ;
}

如果你的数据集可以变大,哈希表是一个想到的解决方案。确保为您的任务选择没有太多冲突的散列算法。顺便说一下,有"完美的哈希算法"——如果"任何时候都不发生碰撞"很重要,你应该看看——无碰撞的快速哈希表将显著提高速度

将键(如用户名)映射到某种记录的标准解决方案是map

stock std::map使用平衡树,它给您O(log N)搜索,这通常足够好(并且比线性好得多),并且还允许您按排序顺序迭代名称。这需要一个有序类型,这意味着user1 < user2是有意义的。

或者,std::unordered_map使用哈希表,它给您O(1)个搜索,但没有任何排序。这需要一个哈希类型,这意味着hash(user1)是有意义的。它还需要c++ 11或c++ 03实现,将其作为tr1boost的一部分。

哪一个是合适的取决于你的需要——但通常,它们都很好,这只是一个你是否有一个自然排序或自然哈希函数的问题。

除了比vector, list或其他需要线性搜索的集合更有效地从中间搜索和删除之外,它也更简单,更自然。例如,比较这两个:

user find_by_name(vector<user> users, string name) {
    return find_if(users.begin(), users.end(), [](auto it) { it->name == name; });
}
user find_by_name(map<string, user> users, string name) {
    return map.find(name);
}

(如果你没有c++ 11 lambda, find_if就更糟了)

至于"线性搜索……是否足够有效",这实际上取决于集合的大小。如果在100个用户中每隔几秒钟搜索一次,那么几乎任何事情都足够高效。如果你要在数百万用户中进行成千上万的搜索,那么它可能不是。如果你知道的不足以估计,那就试一试。分析几乎总是任何优化问题的第一步。然而,在这种情况下,考虑到mapunordered_map首先比vectorlist更简单,更容易阅读,更自然,我认为您不需要为此烦恼。