DS博客做業07--查找

1.1思惟導圖

1.2談談你對查找運算的認識及學習體會

本週學習了查找,學習了效率較好的平衡二叉樹、b樹、折半查找等算法。不論是設計程序,仍是打造產品,一個高性能的算法都極爲重要,好比STL中的map和set使用了紅黑樹,高效的查找效率廣受好評。
可是查找算法各自有着優缺點,選擇合適的纔是最好的,好比搜索引擎使用的倒排索引,很是適合在大量數據中快速找到目標。這些算法從誕生到如今,經受住了無數考驗,已經很是成熟。深刻了解這些算法,對提升本身的內功頗有幫助(俗話說算法是內功)。

2.PTA實驗做業

2.1.題目1:7-1 QQ賬戶的申請與登錄

2.1.1設計思路

使用STL中的map關鍵字爲帳號,值爲密碼。
int main()
{
    輸出數據 
    for (i = 0 to T)
    {
        輸入數據
        cin >> order >> account >> password;
        if (order == 'N')
        {
            調用註冊函數Register(account, password);
        }
        else
        {
            調用登陸函數Login(account, password);
            
        }
    }
    return 0;
}
void Register(string &account, string &password)
{
        if(已經註冊)
        cout << "ERROR: Exist\n";
        
        else(沒有註冊)
        mymap[account] = password;
        cout << "New: OK\n";
}
void Login(string &account, string &password)
{
    if (帳號不存在)
    {
        cout << "ERROR: Not Exist\n";
    }
    else if(密碼正確)
    {
        cout << "Login: OK\n";
    }
    else 密碼錯誤 
    {
        cout << "ERROR: Wrong PW\n";
    }
}

2.1.2代碼截圖



2.1.3本題PTA提交列表說明


A:使用map思路清晰通常不會有什麼問題ios

2.2.題目2:7-2 航空公司VIP客戶查詢


2.2.1設計思路

仍是強大的map,關鍵字爲身份證,值爲里程
取消流同步,加快讀寫速度,具體能夠百度 
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    for (i = 0 to T)
    {
        讀入數據 
        cin >> id >> dist;
        if (dist < k)dist = k;
        mymap[id] += dist;
    }
    for (i = 0 to n)
    {
        if (若是是vip) 
        {
            輸出里程 
            cout <<it->second<<"\n";
        }
        else 若是不是 
        {
            cout << "No Info\n";
        }
    }

2.2.2代碼截圖


2.2.3本題PTA提交列表說明


A:讀寫太慢,運行超時,經過std::ios::sync_with_stdio(false)加快讀寫算法

  • 原理數組

    std::ios::sync_with_stdio(false)
    這句語句是用來取消cin的同步,
    什麼叫同步呢?就是iostream的緩衝跟stdio的同步。若是你已經在頭文件上用了using namespace std;那麼就能夠去掉前面的std::了。
    取消後就cin就不能和scanf,sscanf, getchar, fgets之類同時用了,不然就可能會致使輸出和預期的不同。 取消同步的目的,是爲了讓cin不超時,另外cout的時候儘可能少用endl,換用」\n」,也是防止超時的方法。固然,儘可能用scanf,printf就不用考慮這種由於緩衝的超時了。函數

原文:https://blog.csdn.net/lv1224/article/details/80084840性能

2.3.題目3:7-3(選作) 基於詞頻的文件類似度


2.3.1設計思路

  • 1.數據讀取?
    solution:使用getline直接讀入一行存到一個string類型變量str中(我的不喜歡頻繁讀入),在結尾加上\n(這也是一個單詞結束的標誌),而後str進行操做,而後大寫統一轉換爲小寫(我的愛好),
  • 2.怎麼獲得文件的類似度?
    solution:此問題的關鍵在於選什麼方式存放數據,發現文件的數量很少,能夠直接定義一個map數組,爲何使用map ?該題測試點的數據量比較大,容易超時,而map能夠經過count函數,查找時間複雜度能夠達到o(1),若是使用鏈式會達到o(n)。(主要是哈希思想,不限於map)(小聲:以前用set要遍歷就超時了,因此想到map)

初始數據讀入學習

for (i = 0 to N)文件數 
    {
        讀入數據 
        while (str[0] != '#')//開始處理 
        {
            把單詞放到string類型的temp中 
            for (遍歷str)
            {
                if (str[j]是小寫字母)
                {
                    temp += str[j];
                }
                else if (str[j]是大寫字母)
                {
                    temp += str[j] - 'A' + 'a';
                }
                else str[j]不是字母,是單詞結束標誌 
                {
                    int len = temp.size();
                    if (len > 0)
                    {
                        if (len> 2)長度不小於三、且不超過10的英文單詞,長度超過10的只考慮前10個字母 
                        {
                            if (len > 10) temp = temp.substr(0, 10);
                            mymap[i][temp] = 1;
                        }
                        temp.clear();temp每次要清空 
                    }
                }
            }
            讀入數據 
        }
    }

類似度計算測試

for (i = 0 to T)T對比較數據 
    {
        for (; it != mymap[a].end(); it++)對其中一個遍歷 
        {
            if (mymap[b].count(it->first) == 1)在另外一箇中查找是否有相同單詞 
            {
                sum++;
            }
        }
        輸出結果 
        num -= sum;
        cout << setiosflags(ios::fixed) << setprecision(1);
        cout << (sum * 100 / num)<<"%\n";
    }

2.3.2代碼截圖



2.3.3本題PTA提交列表說明


A:開始是用set,查找須要遍歷,最後一個測試點超時。(下面貼出遍歷部分代碼做爲對比)
搜索引擎

3.閱讀代碼

3.1 題目

3.2 解題思路

使用二分查找,用a記錄目標值開始位置,b記錄結束位置

3.3 代碼截圖

3.4 學習體會

熟悉算法的原理,再加以改造就能夠解決不少算法問題,每每效果還不錯。
相關文章
相關標籤/搜索