2012-04-27 88 views
2

有一個向量的迭代器。我想知道迭代器指向哪個索引。所以我做了以下,但我不確定。迭代器指向哪個索引

int temp = -1; 
std::vector <int> ::iterator f; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    if (*f == face) 
{ 
    switch (f-eFace[e].begin()) 
    { 
     case 0: 
     temp = 5;         
     break; 
     case 1: 
     temp = 3; 
     break; 
     case 2: 
     temp = 4; 
     break; 
     case 3: 
     temp = 1; 
     break; 
     case 4: 
     temp = 2; 
     break; 
     case 5: 
     temp = 0; 
     break; 
      default: 
     throw; 
    } 

    break; 
    } 
} 
+1

你更大的目標是什麼?你確定你同時需要迭代器和索引嗎? – 2012-04-27 10:53:22

+0

@ phresnel,我覺得這對輸出最有用。我會冒險猜測目標可能是一樣的。 – chris 2012-04-27 10:55:22

回答

2

爲什麼不能是這樣的:

std::vector <int> ::iterator f; 

int index = 0; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    // do sth 

    index++; 
} 
+1

@larsmans:增量是一個恆定的時間操作。 – 2012-04-27 10:51:21

+1

而在較大的循環中,與每次減去/調用距離相比,這會在時間上產生相當大的差異。 – chris 2012-04-27 10:52:28

+2

爲什麼不把'index'的增量與'f'的增量並置以避免它們不同步? – 2012-04-27 11:13:49

4
std::vector<int>::size_type index = std::distance (eFace [e].begin(), f); 

請注意,如果你雖然執行它的每一個循環會很慢。爲載體另一種選擇是:

std::vector<int>::size_type index = f - eFace [e].begin(); 

這工作,因爲矢量使用隨機訪問迭代器,這是需要有減法定義,如下面史蒂夫·傑索普指出。

+0

我不確定標準是否真的需要它,但是如果'std :: distance'對於標記爲隨機訪問的迭代器(哪些向量迭代器)沒有恆定的時間複雜度,那麼這是很糟糕的QoI,即使它符合。請注意,隨機訪問迭代器的減法定義爲'b - a ==(a 2012-04-27 11:41:59

+0

@SteveJessop,這是一個有趣的觀點。我不知道減法是這樣執行的。我的回答指出,比建立索引變量和遞增索引變量的兩個不同部分更單線。在更大的循環中它效率相當低。 – chris 2012-04-27 11:44:36

+0

在實踐中,我期望減法*不是這樣實現的,它只是在標準中將結果定義爲該值。因此,如果我們猜測「距離」的實施速度非常慢,我們可以推測減法也是愚蠢的。事實上,它們在任何適合實際使用的實現中都會很快。順便說一句,減法工作的向量不是存儲是連續的,而是迭代器是隨機訪問,因此必須有減法定義。例如,'deque'使用非連續存儲,但迭代器減法也適用於此。 – 2012-04-27 11:46:39

0

對於你的問題:「我想知道哪些指標呢迭代器,指向。」通過說std::vector<int>::iterator f = eFace.begin();您正在創建一個類似於索引std::vector<int>::size_type i = 0;的interator。

你們用eFace.begin()!= eFace.end()通過向量與for循環行走時要使用i = 0!= eFace.size()以同樣的方式迭代器。

至少我認爲這就是你的原始問題。

2

獲得更清晰的代碼會容易得多。

首先,在向量找到一個值:

// Returns the index of `face` in `vec`. 
// If `face` is not present in `vec`, returns `vec.size()`. 
size_t findFaceIndex(int const face, std::vector<int> const& vec) { 
    std::vector<int>::const_iterator const it = 
     std::find(vec.begin(), vec.end(), face); 

    return it - vec.begin(); 
} 

現在映射:

static int const FaceMap[] = { 5, 3, 4, 1, 2, 0 }; 
static size_t const FaceMapSize = sizeof(FaceMap)/sizeof(int); 

// Translate face index into ... 
int faceIndexToX(size_t const index) { 
    if (index >= FaceMapSize) { throw std::runtime_error("out of bounds"); } 
    return FaceMap[index]; 
} 
+0

其中的第一個當然可以模板化。一般來說,如果任何人使用std :: find,因爲它使用線性搜索,所以會出現警告標誌。在極少數情況下,這種情況已經足夠好了,小的收集很少被調用。 你的第二個解決方案是更好,儘管沒有像std :: runtime_exception這樣的異常(有runtime_error但std :: out_of_range可能是更好的像vector :: at那樣拋出,儘管我更喜歡context或an assert。 – CashCow 2012-04-27 11:48:15

+0

@CashCow:我考慮過一個'std :: array',但我不確定OP是否是C++ 11精明的。當然這會更容易。 – 2012-04-27 12:26:44

0

我不知道爲什麼你時,你有迭代反正需要一個數組的索引?如果迭代器是隨機訪問你可以begin()減去它,但如果索引是如此重要,我不知道你最好只使用它而不是迭代器 - 當然這取決於你是否有權訪問代碼重構它。

我不確定你試圖用你的開關實現什麼,但如果它是映射值,那麼推測稀疏向量會更合適?