HW4 problem4

mail@pastecode.io avatar
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;
}