2011-05-10 54 views
1

由於某種原因,check_sort函數只能在主函數中調用一次,否則工作流會在首次執行後凍結。函數只能在主函數中調用一次

例如。輸出結束於:

How many elements for container? 5000 
Check: list is sorted 
Elapsed time: 0.32 seconds 

而不是繼續像:

下面

全部程序:

#include <cmath> 
#include <iterator> 
#include <iostream> 
#include <iomanip> 
#include <vector> 
#include <ctime> 
#include <list> 
#include <set> 
#include <algorithm> 
#include <cstdlib> 

using namespace std; 

typedef void Inserter(vector<double>); 

vector<double> gen_data(int num_elts); 
void insert_list(vector<double> data); 
void insert_set(vector<double> data); 
void insert_vector(vector<double> data); 

void time_insert(Inserter inserter, vector<double> data); 

template <class Iter> bool is_sorted(Iter first, Iter last); 
template <class Iter> void check_sort(Iter first, Iter last, string cont_kind); 

list<double> l; 
set<double> s; 
vector<double> v; 

int main() { 
    srand(time(0));// initialize random number generator 
    cout << "How many elements for container? "; 
    int num_elts = 0; 

    while (cin >> num_elts) { 
    if (num_elts <= 0) 
     cout << "Error, should be > 1"; 
    else { 
     vector<double> data = gen_data(num_elts); 

     check_sort(l.begin(), l.end(), "list"); 
     time_insert(insert_list, data); 
     check_sort(s.begin(), s.end(), "set"); 
     time_insert(insert_set, data); 
     check_sort(v.begin(), v.end(), "vector"); 
     time_insert(insert_vector, data); 

    } 
    cout << "\nHow many elements for next container? "; 

    } 
    return 0; 

} 
void time_insert(Inserter inserter, vector<double> data) { 
    clock_t t1 = clock(); 
    if (t1 == clock_t(-1)) { //if clock() doesn’t work 
    cerr << "sorry, no clock\n"; 
    exit(1); 
    } 

    inserter(data); 
    clock_t t2 = clock(); 
    if (t2 == clock_t(-1)) { 
    cerr << "sorry, clock overflow\n"; 

    exit(2); 
    } 

    cout << "Elapsed time: " << fixed << setprecision(2) 
    << double(t2-t1)/CLOCKS_PER_SEC << " seconds\n"; 

} 

class Larger_than { 
    double v; 
public: 
    Larger_than(double vv) : v(vv){} 
    bool operator()(double x) const {return x>v;} 
}; 

// Sorts and then inserts data into a list 
void insert_list(vector<double> data) 
{ 
    list<double> l; 
    for(int i=0; i < data.size(); i++){ 
    list<double>::iterator p = find_if(l.begin(),l.end(), Larger_than(data[i])); 
    l.insert(p, data[i]); 
    } 
} 
// Sorts and then inserts data into a list 
void insert_set(vector<double> data) 
{ 
    set<double> s; 
    for(int i=0; i < data.size(); i++){ 
    set<double>::iterator p = find_if(s.begin(),s.end(), Larger_than(data[i] 
         )); 
    s.insert(p, data[i]); 
    } 
} 
// Sorts and then inserts data into a list 
void insert_vector(vector<double> data) 
{ 
    vector<double> v; 
    for(int i=0; i < data.size(); i++){ 
    vector<double>::iterator p = find_if(v.begin(),v.end(), Larger_than(data 
             [i])); 
    v.insert(p, data[i]); 
    } 
} 

// generate num_elts random numbers in the range [0.0, 1.0), 
// which are returned in a vector 

vector<double> gen_data (int num_elts) 
{ 
    vector<double> result; 
    for (int i = 0; i < num_elts; i++) { 
    double datum = 1.0*rand()/RAND_MAX; 
    result.push_back(datum); 
    } 
    return result; 
} 

// is container spanned by [from, last) sorted? 
template <class Iter> bool is_sorted(Iter first, Iter last) 
{ 
    Iter next = first;     // next element 
    for (next++; next != last; next++, first++) { 
    if (*first > *next) 
     return false; 
    } 
    return true; 
} 

// prints a msg describing container kind, as well as whether container 
// spanned by [from, last) is sorted 
template <class Iter> void check_sort(Iter first, Iter last, string cont_kind) 
{ 
    cout << "Check: " << cont_kind << " is "; 
    if (!is_sorted(first, last)) cout << "not "; 
    cout << "sorted\n"; 
} 
+1

您的錯誤信息與您檢查的條件不符:'if(num_elts <= 0) cout <<「錯誤,應該> 1」; '。 – 2011-05-10 02:32:34

+2

您應該可以通過(const)引用傳遞數據向量,而不是按值傳遞它。 – 2011-05-10 02:35:10

+0

'is_sorted'在VS 2010上給我一個模糊的匹配錯誤,因爲有一個'std :: is_sorted',並且你導入了整個名字空間。把它改成':: is_sorted'就可以解決它。 – 2011-05-10 02:46:22

回答

4

我不知道,如果這是你的問題的一部分,但is_sorted如果first是容器的末端,則不起作用。 next會增加過去end並遇到未定義的行爲。

編輯:其實這是絕對的:你不要在向它們調用檢查函數之前填充vector/list/set容器。即使您調用之前的插入函數調用檢查函數它仍然不會工作,因爲每個insert_*函數聲明一個本地填充哪個陰影您要填充的全局變量。

EDIT2:在insert_setfind_if實際上使您的代碼性能低於應有的程度。您應該只使用std::set::insert並讓它使用內置排序,因爲它知道底層set的實現,所以它將比find_if更高效。

+0

+1,很好找。但是這也意味着他不幸能夠與名單一起工作。 – Xeo 2011-05-10 02:35:31

+1

我得到了一個調試斷言,第二次它嘗試增加列表中的迭代器,如果我選擇忽略斷言,我立即得到第二個,所以我猜「不幸」是這個詞。答案+1,因爲它是正確的。 – 2011-05-10 02:52:50

2

你的模板函數is_sorted()不正確檢查是否first等於last遞增next這是first一個副本之前:

template <class Iter> bool is_sorted(Iter first, Iter last) 
{ 
    Iter next = first;     // next element 
    for (next++; next != last; next++, first++) { 
     if (*first > *next) 
      return false; 
    } 
    return true; 
} 

如果你遍歷一個空的範圍內這可能會導致問題, 我相信。

template <class Iter> bool is_sorted(Iter first, Iter last) 
{ 
    if (first == last) 
     return false; 
    for (Iter next = first+1; next != last; next++, first++) 
    { 
     if (*first > *next) 
      return false; 
    } 
    return true; 
} 

我不確定你得到空的範圍......所以這可能是一個紅色的鯡魚。

由於在檢查排序之前沒有設置列表(並且在插入數據後沒有檢查它是否排序),所以您會遇到空白範圍的問題。你需要扭轉你的插入和檢查操作的順序:

vector<double> data = gen_data(num_elts); 
    time_insert(insert_list, data); 
    check_sort(l.begin(), l.end(), "list"); 
    time_insert(insert_set, data); 
    check_sort(s.begin(), s.end(), "set"); 
    time_insert(insert_vector, data); 
    check_sort(v.begin(), v.end(), "vector"); 

你應該通過調用一個函數來獲取元素來處理的數量避免你的主循環重複的代碼。此外,傳統上在cerr上報告錯誤。

static int get_num_elts() 
{ 
    int num_elts; 
    cout << "How many elements for container? "; 
    cin >> num_elts; 
    if (num_elts < 1) 
     cerr << "Error: number should be >= 1" << endl; 
    return num_elts; 
} 


... 
int num_elts; 

while ((num_elts = get_num_elts()) > 0) 
{ 
    vector<double> data = gen_data(num_elts); 
    time_insert(insert_list, data); 
    check_sort(l.begin(), l.end(), "list"); 
    time_insert(insert_set, data); 
    check_sort(s.begin(), s.end(), "set"); 
    time_insert(insert_vector, data); 
    check_sort(v.begin(), v.end(), "vector"); 
} 
+0

不,我調試它,你釘了它。除矢量以外的所有東西都未被填充。 – 2011-05-10 02:51:38

+0

@Merlyn:謝謝! – 2011-05-10 02:54:27

1

您的代碼不會在is_sorted功能

進入循環體,而不是for (next++; next != last; next++, first++)for (next; next != last; next++, first++)。因爲如果第一次==最後,那麼這將是一個問題,那就是你面臨的問題。但是不增加下一個指針將不會造成任何傷害,因爲第一個比較將比較第一個元素和它本身,這個元素總是被評估爲false,並且與其自身的比較大。