HW4 problem4
unknown
plain_text
2 years ago
7.9 kB
12
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...