# HW4 problem4

unknown
plain_text
7 months ago
7.9 kB
2
Indexable
Never
```#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;
}```