2011-05-10 4 views
1

어떤 이유로 check_sort 함수는 main 함수 내에서 한 번만 호출 할 수 있습니다. 그렇지 않으면 워크 플로가 처음 실행 된 후 멈 춥니 다.함수는 메인 내에서 한 번만 호출 할 수 있습니다.

예를 들면.

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보다 커야합니다."; '. –

+2

값으로 전달하지 않고 데이터 벡터를 (const) 참조로 전달해야합니다. –

+0

'is_sorted'는 VS 2010에서 모호한 일치 오류를줍니다. 왜냐하면'std :: is_sorted'가 있고 전체 네임 스페이스를 가져 왔기 때문입니다. ':: is_sorted'로 변경하면 해결됩니다. –

답변

4

이 문제의 일부인지 모르겠지만, is_sortedfirst이 컨테이너의 끝인 경우 올바르게 작동하지 않습니다. next이 (가) end 이전에 증가하고 정의되지 않은 동작이 발생합니다.

편집 : 사실 이것은 확실히 다음과 같습니다. 벡터/목록/집합 컨테이너에 체크 기능을 호출하기 전에 채우지 마십시오. 삽입 기능을 이라고 부르더라도은 확인 기능을 호출하기 전에 각 insert_* 함수가 채우기를 시도하는 전역 변수를 채우는 로컬을 선언하기 때문에 여전히 작동하지 않습니다.

EDIT2 : insert_set에서 find_if은 실제로 코드가 성능이 떨어지게 만듭니다. std::set::insert을 사용하고 기본 정렬 인 set의 구현을 알고 있기 때문에 find_if보다 효율적입니다. 당신이 빈 범위를 반복 얻을 경우

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; 
} 

이 문제가 발생할 수 :

+0

+1, 좋은 찾기. 그러나 그것은 또한 그가리스트 1과 함께 일하기에 충분히 불운하다는 것을 의미한다. – Xeo

+1

디버그 어설 션이 두 번째로 목록의 반복기를 증가 시키려고 시도했는데 어설 션을 무시하기로 결정한 경우 즉시 두 번째가 발생하므로 "불운 한"단어라고 생각합니다. 올바른 것이기 때문에 대답에 +1하십시오. –

2

템플릿 기능 is_sorted()first의 사본 인 next를 증가하기 전에 last에 동일 first 여부를 제대로 확인하지 않습니다 , 나는 믿는다. 난 당신이 빈 범위를 얻을 확실하지 않다

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

아니, 나는 그것을 디버깅하고 당신은 그것을 못 박는 다. 벡터 이외의 모든 것은 채워지지 않습니다. –

+0

@Merlyn : 감사합니다! –

1

귀하의 코드는 is_sorted 기능

에서 루프의 본문을 입력하지 않는 대신 for (next++; next != last; next++, first++)for (next; next != last; next++, first++)을한다. 왜냐하면 처음 == 마지막이라면 문제가 될 것이고 그것은 당신이 직면 한 것입니다.그러나 첫 번째 비교가 첫 번째 요소를 자체 요소와 비교할 것이므로 다음 포인터를 증가시키지 않아도 아무런 해를 입지 않습니다.

관련 문제