算法題之好友推薦

 

題目要求:ios

有n我的,每一個人都有各自的好友列表。給定一個閾值p,當A和B的共同好友數超過p則推薦A和B爲好友。請實現自動推薦直到沒有好友能夠推薦(每次推薦默認贊成,即必定成爲好友),而後進行一些查詢。函數

查詢1:A的好友數有幾個?若是A不在這n個裏面,輸出-1,不然輸出好友數;測試

查詢2:A和B是好友嗎?若是是則輸出0,不然輸出-1。spa

輸入:p n m x y指針

p爲閾值,n爲人數,m爲初始時的好友,x爲查詢1的個數,y爲查詢2的個數code

注: - 若是A是B的好友,B必定是A的好友; - 每一個人的人名用不超過20個字符的字符串表示,沒有重名的人; - 人數不超過100.blog

輸入示例:
2 3 3 3 3
A
B
C
A B
B C
A C
A
B
C
A B
C A
B C
應輸出:
2
2
2
0
0
0ci

個人思路:字符串

1.根據輸入的好友數量N,創建一個N*N的關係矩陣,1表示爲好友,0表示非好友關係。這樣作的好處是便於保存和修改好友關係。注意點:每次修改時要對m,n和n,m兩個位置的元素進行修改;對第i行遍歷時從第i+列開始便可。string

2.好友推薦處理過程就是對關係矩陣的處理,遍歷矩陣每一行,當爲非好友時,經過矩陣算出共同好友數;爲好友時,跳過;當共同好友數超過閾值時將值設爲1。直到關係矩陣再也不被改變爲止,此時已無可推薦好友了。

3.基於處理後的關係矩陣,根據輸入的查詢進行計算便可。

#include<string>
#include<iostream>
#include<vector>
#include<algorithm>//用到其中的find()函數,返回迭代器或指針
using namespace std;

int friendnum(vector<int> &R,vector<string> &namelist, string name,int N)
{
    int loc=find(namelist.begin(),namelist.end(),name)-namelist.begin();
    int count=0;
    if(loc>N-1)
        count=-1;
    else
    {
    for(int i=0;i<N;i++)
        if(R[loc*N+i]==1)
            count++;
    }
    return count;
}

int isfriend(vector<int> &R,vector<string> &namelist, string name1,string name2,int N)
{
    int loc1=find(namelist.begin(),namelist.end(),name1)-namelist.begin();
    int loc2=find(namelist.begin(),namelist.end(),name2)-namelist.begin();
    int count=-1;
    if(loc1>N-1||loc2>N-1)
        count=-1;
    else
    {
        if(R[loc1*N+loc2]==1)
            count=0;
    }
    return count;
}

void main()
{
    while(1)
    {
        vector<string> namelist;
        string nametemp;
        int P,N,M,X,Y;
        cin.clear();
        cin.sync();
        cin>>P>>N>>M>>X>>Y;
        vector<int> R(N*N,0);//創建關係矩陣,默認爲0,非好友
        int n=N;//人數
        while(n--)//創建姓名列表
        {
            cin>>nametemp;
            namelist.push_back(nametemp);
        }
        int m=M;
        string name1,name2;
        int name1_it,name2_it;
        while(m--)//填充關係矩陣
        {
            cin>>name1>>name2;
            name1_it=find(namelist.begin(),namelist.end(),name1)-namelist.begin();//注意string.find()返回的是下標,而find()返回的是迭代器,用find()函數在容器中得到下標方法find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin();沒有找到時返回值超過邊界。
            name2_it=find(namelist.begin(),namelist.end(),name2)-namelist.begin();//彷佛string不須要用到迭代器,可返回下標,也可以使用下標。string.back()是什麼鬼?
            R[name1_it*N+name2_it]=1;
            R[name2_it*N+name1_it]=1;
        }
        //顯示初始好友關係矩陣。1:好友;2:非好友
        //for(int i=0;i<N;i++)
        //{
        //    for(int j=0;j<N;j++)
        //        cout<<R[N*i+j]<<' ';
        //    cout<<endl;
        //}

        //好友推薦過程
        int flag=1;
        while(flag)
        {
            flag=0;//用於判斷是否結束推薦
            for(int i=0;i<N;i++)
            {
                for(int j=i+1;j<N;j++)
                {
                    if(R[N*i+j]!=1)//不是好友
                    {//判斷是否符合推薦閾值
                        int count=0;
                        for(int k=0;k<N;k++)
                            if(R[N*i+k]==R[N*j+k])//k爲其共同好友
                                count++;
                        if(count>=P)//達到閾值
                        {
                            R[N*i+j]=1;//成爲相互間的好友
                            R[N*j+i]=1;//修改關係矩陣
                        }
                        flag=1;//有推薦改動,繼續推薦循環
                    }
                }
            }
        }
        //顯示好友推薦完成後的好友關係矩陣。1:好友;2:非好友
        //for(int i=0;i<N;i++)
        //{
        //    for(int j=0;j<N;j++)
        //        cout<<R[N*i+j]<<' ';
        //    cout<<endl;
        //}
        //cout<<"x y="<<X<<' '<<Y<<endl;

        //推薦結束,響應查詢
        vector<int> qury1; //查詢1答案記錄
        int x=X;
        int y=Y;
        while(x--)
        {
            string tempqury;
            cin>>tempqury;
            int tempans=friendnum(R, namelist, tempqury, N);
            qury1.push_back(tempans);
        }

        vector<int> qury2; //查詢2記錄
        while(y--)
        {
            string name1;
            string name2;
            cin.sync();
            cin.clear();
            cin>>name1>>name2;
            int tempans=isfriend(R, namelist, name1, name2, N);
            qury2.push_back(tempans);
        }
        //輸出結果
        for(int i=0;i<X;i++)
            cout<<qury1[i]<<endl;
        for(int i=0;i<Y;i++)
            cout<<qury2[i]<<endl;

    }

    //int aa[]={1,2,3,4};
    //vector<int> vec_aa(aa,aa+4);
    ////string a=str(str.find("a"));
    ////string::iterator it=str.find("a");
    ////vector<int>::iterator loc=find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin();
    //int loc=find(vec_aa.begin(),vec_aa.end(),2)-vec_aa.begin();
    //cout<<vec_aa[loc];

}
//測試集
//輸入:
//2 3 3 3 3 
//A 
//B 
//C 
//A B 
//B C 
//A C 
//A 
//B 
//C 
//A B 
//C A 
//B C

//應輸出: 
//2 
//2 
//2 
//0 
//0 
//0

1.find()和string.find()區別:algorithm庫中的find()返回的是迭代器,輸入三個參數,開始和結束的迭代器,待尋找值。得到下標值得方式是find(.begin(),.end(),xx)-.begin();string.find()返回的是下標值。

相關文章
相關標籤/搜索