2

クラス オブジェクトの配列を検索しようとして助けが必要です。users というクラスがあり、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 << "\n\n\n" ;
    }

    /*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()  << "\n\n";
    }

    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()  << "\n\n";
    }

    cin.get() ;

    menu() ;

}
4

2 に答える 2

1

データセットが大きくなる可能性がある場合は、ハッシュテーブルが頭に浮かぶソリューションです。タスクの衝突が少ないハッシュ アルゴリズムを選択してください。ちなみに、 「完全なハッシュアルゴリズム」があります-「常に0の衝突」が重要な場合は、それを検討する必要があります-衝突のない高速ハッシュテーブルにより、処理が大幅に高速化されます

于 2013-01-22T20:04:56.840 に答える
0

キー (ユーザー名など) を何らかのレコードにマッピングするための標準的なソリューションは、map.

ストックstd::mapはバランスの取れたツリーを使用します。これにより、O(log N) 検索が可能になります。通常、これで十分です (線形よりもはるかに優れています)。また、並べ替えられた順序で名前を反復処理することもできます。これには順序付けられた型が必要です。意味user1 < user2は理にかなっています。

または、std::unordered_mapO(1) 検索を提供するハッシュ テーブルを使用しますが、順序はありません。これにはハッシュ可能な型が必要です。意味hash(user1)は理にかなっています。tr1また、C++11、または 、またはの一部としてそれを含む C++03 実装も必要boostです。

どちらが適切かはニーズによって異なりますが、多くの場合、どちらも問題なく、自然な順序付けと自然なハッシュ関数のどちらを使用しているかの問題です。

vectorlist、または線形検索を必要とするその他のコレクションよりも検索と途中からの削除の両方が効率的であるだけでなく、はるかに単純で自然でもあります。たとえば、次の 2 つを比較します。

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 ラムダがない場合は、find_ifさらに悪いことになります。)

「線形検索が…十分に効率的」かどうかについては、コレクションの大きさに大きく依存します。100 人のユーザーに対して数秒ごとに 1 回の検索を行う場合、ほとんど何でも十分に効率的です。何百万ものユーザーから何千もの検索を行っている場合、おそらくそうではありません。推定するのに十分な知識がない場合は、試してみてください。プロファイリングは、ほとんどの場合、最適化に関する質問の最初のステップです。ただし、この場合、maporはそもそも or よりもシンプルで読みやすく、自然なので、気にする必要はないと思いますunordered_mapvectorlist

于 2013-01-22T20:14:40.507 に答える