1. 程式人生 > 實用技巧 >2017_優先佇列之最小優先佇列

2017_優先佇列之最小優先佇列

此作業的要求參見:https://edu.cnblogs.com/campus/nenu/2020Fall/homework/11207

此次作業首先要感謝李思源同學對我在使用vs過程中的細心幫助。
作業0(5分)
修改create.cpp檔案,改成由命令列引數確定生成的資料的資料量。修改readme.md的對應部分。(要求貼出修改之後的程式碼和read.md。)
修改後的程式碼,查找了atoi()函式的用法

//create.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>

using namespace std;

int main(int argc, char* argv[])
{
    int num = atoi(argv[1]);
    //atoi()函式將數字格式的字串轉換為整數型別
    srand((unsigned)time(NULL));
    for (int i = 0; i < num; i++)
    {
        cout << rand()<< "\n";
    }
    cout << endl;

    return 0;
}

作業1(10分)

對上面兩段老楊寫的程式碼任選其一進行profile,觀察現象(要求有截圖記錄)。

你是一個好人,為了讓老楊知道為什麼要對程式碼進行profile,於是你在原來的題目的基礎上做出了修改,修改之後的題要求如下:
1) 讀入兩個檔案,一個用控制檯,一個用命令列引數指出檔名。
檔案 biggerwhitelist,包含1列整數1M個,隨機生成(要求老楊自己想辦法),通過命令列引數指出檔名。
檔案 biggerq,包含1列整數10M個,隨機生成(也要求老楊自己想辦法),通過控制檯讀入。
2) 在檔案biggerq中查詢所有不在biggerwhitelist中的整數,重定向輸出到一個檔案中。
3) 寫一份如何部署執行程式碼的readme。

我是用的是vs2019版本 選擇對C++程式碼進行profile

執行完成的結果如下圖

由於上幾個部分的佔比幾乎相差不多無法做出判斷,所以我得出的結論是main函式所佔用的時間比較多,並點開程式碼行發現是對於資料的輸出部分佔的百分比最大。
1) 讀入兩個檔案,一個用控制檯,一個用命令列引數指出檔名。

檔案 biggerwhitelist,包含1列整數1M個,隨機生成(要求老楊自己想辦法),通過命令列引數指出檔名。

檔案 biggerq,包含1列整數10M個,隨機生成(也要求老楊自己想辦法),通過控制檯讀入

2) 在檔案biggerq中查詢所有不在biggerwhitelist中的整數,重定向輸出到一個檔案中。

3) 寫一份如何部署執行程式碼的readme。

作業2(10分)

以biggerwhitelist和biggerq作為輸入,對作業1中選擇的程式碼再次進行profile,找到程式碼執行最“慢”的地方,截圖為證並文字說明。

profile大的資料以後發現了問題的所在不是輸出的問題,而是ismatch的複雜度太高,導致佔用了大量的空間。

作業3(10分)

根據作業2找到的最慢的地方,優化作業1中你選擇的程式碼,在保證輸出結果正確的前提下,減少老楊程式執行的時間。(優化後的程式碼需要你提交到git上,作為教師的判斷依據。優化後的程式的名字應該是better.cpp或者better.cs。)

//better.cpp
#include <algorithm>
#include <fstream>
#include <iostream>
#include <cstring>
using namespace std;

const int w_1m = 1000000;
int w[w_1m];

bool binarysearch(int t, int low,int high)
{
    int  mid;
    mid = (high + low) / 2;
    //對排序後的有序資料進行二分查詢
    if (w[mid] == t)
    {
        return false;
    }
    else if (low >= high)
    {
        return 1;
    }
    else if (w[mid] > t)
    {
        return binarysearch(t,low, mid - 1);
    }
    else if (w[mid] < t)
    {
        return binarysearch(t,mid + 1, high);
    }
    return true;
}

// brute -w whitelist < T
int main(int argc, char* argv[])
{
    if (argc != 3 || strcmp(argv[1], "-w"))
    {
        return 1;
    }

    // init w
    ////    for(int i=0;i<w_1m)
    ////    {
    ////        w[i]=-1; //填充非法資料
    ////    }
    ifstream infile;
    infile.open(argv[2]);
    int i = 0;
    cout << argv[2] << endl;
    while (infile >> w[i++])
    {
    }
    int w_length = i - 1;
    cout << w_length << endl;
    // check t
    int t = 0;

    sort (w, w + w_length);
    //對w中的資料進行排序
    while (cin >> t)
    {
        if (binarysearch(t, 0, w_length))
        {
            cout << t << endl;
        }
    }
}

程式碼地址:https://mochi0828.coding.net/public/profile/better/git/files

作業4(5分)

對作業3優化後的程式碼進行profile,結果與作業2的結果做對比。畫表格並文字說明。

優化後的程式碼再次進行了profile 通過排序後遞迴的進行二分查詢 降低複雜度至log n也加快了時間。


做業5(5分)

你覺得老楊的文件(readme),註釋和程式碼風格又哪些問題,該如何改進?

首先我覺得readme的內容需要寫的更加詳細,比如功能的用途,操作的方式等
其次操作步驟也應該寫得更為詳細,像是create和brute是否需要重新再新建一個解決方案?還是在同一個解決方案裡就可以完成?如果新建需要在新的專案目錄下新增什麼檔案資訊?
在進行whitelist和q的操作後應該會生成什麼樣的檔案,在什麼地方生成?這些都是會產生疑問的地方,也是我遇到的問題。
在這次給出的程式碼中,也產生了對於ismatch()函式的邏輯的疑問,我依然保持我和師兄討論的觀點。對於這個邏輯的疑問,我在優化後的程式碼中進行了改正。因為如果是判斷!=的邏輯然後返回了true值,那麼等於並沒有進行判斷的邏輯。

應改為