HW4 problem4
unknown
plain_text
a year ago
7.9 kB
7
Indexable
#include <iostream> #include <cmath> using namespace std; void calaulate1D(int movieNum, int scoreTime, int recommendMovie, int memberNum, int highestScore, int selectedmember, int* movieListSize, int** movieLists, int** scoreLists, int* compareMovie); void recommend(int movieNum, int memberNum, int selectedmember, int recommedMovie, int highestScore, int scoreTime, int* movieListSize, int** movieLists, int** scoreLists); int main() { int memberNum = 0; //number of members int movieNum = 0; //number of movies int selectedmember = 0; //the number of selected member int recommendMovie = 0; //the number of recommended movie int highestScore = 0; int scoreTime = 0; cin >> memberNum >> movieNum >> selectedmember ; int* movieListSize = new int[memberNum]; int** movieLists = new int*[memberNum]; int** scoreLists = new int*[memberNum]; int* compareMovie = new int[movieNum]; for(int i = 0; i < memberNum; i++) { cin >> movieListSize [i]; movieLists[i] = new int[movieListSize[i] + 1]; //多開一格陣列輸入0 scoreLists[i] = new int[movieListSize[i] + 1]; for(int j = 0; j < movieListSize[i] + 1; j++) //初始化兩個陣列 { movieLists[i][j] = scoreLists[i][j] = 0; } for(int j = 0; j < movieListSize[i]; j++) //輸入每個人看過的電影編號及評分,最後留一格0 { cin >> movieLists[i][j] >> scoreLists[i][j]; } } for(int i = 0; i < movieNum; i++) //初始化 { compareMovie[i] = 0; } calaulate1D(movieNum, scoreTime, recommendMovie, memberNum, highestScore, selectedmember, movieListSize, movieLists, scoreLists, compareMovie); //delete delete[] movieListSize; delete[] compareMovie; movieListSize = compareMovie = nullptr; for(int i = 0; i < memberNum; i++) { delete[] movieLists[i]; delete[] scoreLists[i]; } delete[] movieLists; delete[] scoreLists; movieLists = scoreLists = nullptr; return 0; } void calaulate1D(int movieNum, int scoreTime, int recommendMovie, int memberNum, int highestScore, int selectedmember, int* movieListSize, int** movieLists, int** scoreLists, int* compareMovie) { int selectedMemMovie = 0; int recommendMember = -1; int* firstD = new int[memberNum+1]; //計算第一種距離 int* secondD = new int[memberNum+1]; //計算第二種距離 for(int i = 0; i < memberNum+1; i++) { firstD[i] = secondD[i] = 2000; //初始化時加到極大 } for(int i = 0; i < movieNum; i++) //每部電影都算到 { if(i + 1 == movieLists[selectedmember - 1][selectedMemMovie]) //把選到的會員看電影的評分寫進compareMovie,沒看過則為0分 { compareMovie[i] = scoreLists[selectedmember - 1][selectedMemMovie]; selectedMemMovie++; } } int g = 0; int k = 0; int h = 0; for(int i = 0; i < memberNum; i++) { if(i + 1 != selectedmember) //如果遇到非所選會員時開始運算 { for(int j = 0; j < movieNum; j++) //檢查每一部電影 { if(movieLists[i][g] == j + 1) //遇到 i 會員有看的電影時運算 { k += abs(compareMovie[j] - scoreLists[i][g]); //把第一種距離算出後先存入代數k,等等每一部電影都考慮完再存入firstD[i] if(compareMovie[j] == 0) //同理如果遇到一個會員,另一個沒有看的電影,h + 1,考慮完每一部電影後再存入secondD[i] { h++; } g++; } else //遇到 i 會員沒看的電影時 { if(compareMovie[j] != 0) //且選定會員有看時,計算第一種及第二種距離 { k += compareMovie[j]; h++; } } } firstD[i] = k; //存入陣列 secondD[i] = h; k = g = h = 0; //歸零後再重新迴圈 } } int MinfirstD = 3000; //把最小值設極大 for(int i = 0; i < memberNum; i++) { if(i + 1 != selectedmember && firstD[i] < MinfirstD) //若遇到非所選會員,並且兩者的第一種距離比最小值小時,計算 { MinfirstD = firstD[i]; //最小值變第一種距離 recommendMember = i + 1; // 存入推薦電影的會員 } if(i + 1 != selectedmember && firstD[i] == MinfirstD && secondD[i] < secondD[recommendMember - 1]) //若遇到非所選會員,並且第一種距離和最小值一樣小,且第二種距離更小 { recommendMember = i + 1; //推薦電影的會員變成第二種距離更小的會員 } } int maxvalue = -1; //用來存要推薦的電影裡評分最高的分數 int p = 0; //用來讓該會員的評分往下一格比較大小 for(int i = 0; i < movieNum; i++) { if(movieLists[recommendMember - 1][p] == i + 1) // 在要推薦的會員看過的電影,且被推薦的會員沒看過的電影中,選最高分的 { if(compareMovie[i] == 0 && scoreLists[recommendMember - 1][p] > maxvalue) { recommendMovie = i + 1; maxvalue = scoreLists[recommendMember -1][p]; } p++; } } if(recommendMovie != 0) //如果有推薦的電影編號 { for(int i = 0; i < memberNum; i++) //計算幾個會員看過,且總分多少 { for(int j = 0; j < movieNum; j++) { if(movieLists[i][j] == recommendMovie) //如果遇到有會員看過 { scoreTime++; //計算次數 + 1 highestScore += scoreLists[i][j]; //累積總分 } } } } if(recommendMovie == 0) //如果要推薦的會員沒辦法推薦的話 , 用第三題的解法 { recommend(movieNum, memberNum, selectedmember, recommendMovie, highestScore, scoreTime, movieListSize, movieLists, scoreLists); delete [] firstD; delete [] secondD; firstD = secondD = nullptr; return ; } cout << recommendMovie << "," << scoreTime << "," << highestScore; delete[] firstD; delete[] secondD; firstD = secondD = nullptr; } void recommend(int movieNum, int memberNum, int selectedmember, int recommendMovie, int highestScore, int scoreTime, int* movieListSize, int** movieLists, int** scoreLists) { int* notyetSelected = new int[movieNum]; //用來計算被推薦的會員有哪些電影還沒看過 for(int i = 0; i < movieNum; i++) { notyetSelected[i] = 0; //初始化為 0 , 遇到有看過的再變成 1 } int Totalscore = 0; //用來計算總分最高分的電影 int TotalscoreTime = 0; //用來計算總次數最多的電影 highestScore = -1; for(int i = 0; i < movieListSize[selectedmember - 1]; i++) //被推薦的會員看過的電影,從 0 變成 1 { notyetSelected[movieLists[selectedmember - 1][i] - 1] = 1; } for(int i = 0; i < movieNum; i++) //計算到每一部電影 { if(notyetSelected[i] == 0) //遇到被推薦的會員沒看過的電影時 { for(int k = 0; k < memberNum; k++) //計算每個會員對它的評分,並在計算次數加 1 { for(int h = 0; h < movieListSize[k]; h++) { if(movieLists[k][h] == i + 1) { Totalscore += scoreLists[k][h]; TotalscoreTime ++; } } } if(Totalscore > highestScore) //若總分比最高分高,存入最高分,存入總計算次數,及推薦的電影編號 { highestScore = Totalscore; scoreTime = TotalscoreTime; recommendMovie = i + 1; } else if(Totalscore == highestScore && TotalscoreTime > scoreTime) //遇到總分相同而總計算次數更大的電影時,存入總計次數,及推薦的電影編號 { scoreTime = TotalscoreTime; recommendMovie = i + 1; } Totalscore = TotalscoreTime = 0; //總分及總次數歸零 } } cout << recommendMovie << "," << scoreTime << "," << highestScore; delete[] notyetSelected; notyetSelected = nullptr; }
Editor is loading...