0
    #include "UserUserSim.h"
UserUserSim::UserUserSim(string &query_url):
    _query_url(query_url)
{

}

void UserUserSim::calculate(){
    ifstream infile(_query_url.c_str());
    string line;
    while(infile){
        int movie_id;
        int user_id;
        infile>>line;
        if (line[line.length()-1]==':'){
            movie_id=atoi(line.c_str());
            cout<<line<<endl;
        }
        else{
            user_id=atoi(line.c_str());
            if (_set.find(user_id)==_set.end())
                getTop(user_id);
            float score=getScore(user_id,movie_id);
            cout<<score<<endl;
        }
    }
}
float UserUserSim::getScore(int &user_id, int &movie_id){
    vector<USim>* p=_map[user_id];
    MovieList* ml=MovieDictionary::getInstance().getMovie(movie_id);
    ml->sortList();
    vector<UserScore>::iterator it;
    vector<USim>::iterator sim_it=p->begin();
    float score=0;
    float total_weight=0;
    for (it=ml->begin();it<ml->end();it++){
        while ((*it).user_id>(*sim_it).user_id){  // the user did not rate in ths movie
            sim_it++;
        }

        if ((*it).user_id==(*sim_it).user_id){
            score+=(*sim_it).score * (*it).rating;  // score of similarity * rating
            total_weight+=(*sim_it).score;
            sim_it++;   // move on to the next user
        }
    }
    score=score/total_weight;
    return score;
}
typedef pair<int, float> mapPair;
bool compareSim(mapPair p1, mapPair p2){
    return p1.second>p2.second;
}
bool compareID(mapPair p1, mapPair p2){
    return p1.first<p2.first;
}
void UserUserSim::getTop(int &user_id){
    vector<USim> list;
    vector<USim>* p=&list;
    _map.insert(pair<int,vector<USim>*>(user_id,p));
    _set.insert(user_id);

    UserList* ul=UserDictionary::getInstance().getUser(user_id);
    map<int,float> user_score_map;
    vector<MovieScore>::iterator it;
    vector<UserScore>::iterator it_movie; // the iterator for the movielist
    for (it=ul->begin();it<ul->end();it++){ // for each movie rating in the Vector
        int movie_id=(*it).movie_id;
        MovieList* ml=MovieDictionary::getInstance().getMovie(movie_id);
        for(it_movie=ml->begin();it_movie<ml->end();it_movie++){
            int user_id=(*it_movie).user_id;
            if (user_score_map.find(user_id)==user_score_map.end()){
                user_score_map.insert(pair<int,float>(user_id,0));
            }else{
                user_score_map[user_id]+=(*it).rating*(*it_movie).rating;// the vector's user rating x the rating of the movie,user
            }
        }
    }
    //vector< pair<int,float> > user_score_v;
    map<int,float>::iterator it_map;
    for (it_map=user_score_map.begin();it_map<user_score_map.end();it_map++){} //<=============where error happens
}

最後の行を含めると、次のようなエラーが発生することに注意してください。

g++ src/main.cpp src/CorpusExp.cpp src/MovieList.cpp src/MovieDictionary.cpp src/UserDictionary.cpp src/UserList.cpp src/UserUserSim.cpp -o recommend
src/UserUserSim.cpp: In member function ‘void UserUserSim::getTop(int&)’:
src/UserUserSim.cpp:81: error: no match for ‘operator<’ in ‘it_map < user_score_map. std::map<_Key, _Tp, _Compare, _Alloc>::end [with _Key = int, _Tp = float, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, float> >]()’
make: *** [recommend] Error 1

C ++はほとんど初めてで、いくつかの参照を確認しました。マップを反復しても問題ないと思いました。そうでない場合、マップからいくつかの要素(トップkなど)をベクトルにコピーするにはどうすればよいですか?

4

4 に答える 4

5

<operatorなどの関係比較は、ランダム アクセス反復子で>のみ使用できます。

std::mapイテレータは双方向イテレータであり、ランダム アクセスよりもはるかに弱い仕様です。双方向反復子で関係比較を使用することはできません。Map イテレータは、等価性についてのみ比較できます。!=の代わりにループ条件で比較を使用します<

さらに、できる限り等値比較を使用し、関係比較は本当に必要な場合にのみ使用することをお勧めします。つまり、可能な限り弱い要件セットに依存します。

于 2012-11-24T00:13:49.553 に答える
1

問題を最小量のコードに減らす必要があります! ほとんどのコードは、問題とはまったく関係がないようです!

問題は、双方向イテレータがより小の関係を定義していないことです。それらを比較するのは、等しいかどうかだけです。使うだけ

it != map.end()

それ以外の

it < map.end()
于 2012-11-24T00:12:53.207 に答える