2009-10-14 95 views
1

下面的程序似乎每次崩潰在最後,我假設這是因爲一旦我到達i =(size-1),那麼wordList [我+ 1]不會返回任何東西,返回null或其他等價物。任何方式在這個?我糾正這是我問題的根源嗎?簡單'for'循環崩潰程序最後迭代

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <iomanip> 

using std::cin; 
using std::cout;   using std::endl; 
using std::sort; 
using std::string;   using std::vector; 

// Obtain a list of words and return the de-duped list 
// with an accompanying word count 
int main() 
{ 
    cout << "Enter a series of words separated by spaces, " 
      "followed by end-of-file: "; 

    vector<string> wordList; 
    string x; 
    while (cin >> x) 
      wordList.push_back(x); 

    typedef vector<string>::size_type vec_sz; 
    vec_sz size = wordList.size(); 
    if (size == 0) { 
     cout << endl << "This list appears empty. " 
         "Please try again." << endl; 
     return 1; 
    } 

    sort(wordList.begin(), wordList.end()); 

    cout << "Your word count is as follows:" << endl; 
    int wordCount = 1; 
    for (int i = 0; i != size; i++) { 
     if (wordList[i] == wordList[i+1]) { 
      wordCount++; 
      } 
     else { 
      cout << wordList[i] << " " << wordCount << endl; 
      wordCount = 1; 
      } 
     } 
    return 0; 
} 

回答

3

您需要兩個更改。正如前面的評論所述,您的結束條件應爲< size-1,以防止讀出界限。您還需要打印最後一個項目的計數,這將是wordCount,因爲如果它是唯一的,則wordCount爲1,如果不是,則它已被添加。更正後的代碼:

for (int i = 0; i < size-1; i++) { 
    if (wordList[i] == wordList[i+1]) { 
     wordCount++; 
     } 
    else { 
     cout << wordList[i] << " " << wordCount << endl; 
     wordCount = 1; 
     } 
    } 
cout << wordList[size-1] << " " << wordCount << endl; 
+0

令人敬畏的machielo。看起來你遇到了我的兩個問題 - 出界問題以及如何捕捉列表中的最後一個單詞。只是改變'我<大小-1'並不能解決後者,但添加最終的結果。 – IanWhalen 2009-10-14 16:46:53

+0

我很高興你發現它有幫助:) – AntonioMO 2009-10-14 16:59:51

-1

你可能想嘗試

for (int i = 0; i < size; i++) 

這將試圖解決的指數是出界停止循環。

+0

雖然<比!=好,但實際上這不是問題 – Herms 2009-10-14 16:12:02

+2

錯誤。他正在訪問wordList [i + 1],這會在i == size-1時失敗。 – 2009-10-14 16:12:34

1

是的。邊界條件失敗。 vector[size()]是未定義的值。

if (wordList[i] == wordList[i+1]) ---> out of bounds 

解決方法可能是迭代size()-1

0

這正是問題。您的矢量包含「大小」項目,但您嘗試訪問矢量的末尾。

你需要做的是在最後一項之前停止for循環,以便i + 1只訪問最後一項。

例如:

for (int i = 0; i < (size - 1); i++) { 
0

變化

for (int i = 0; i != size; i++) { 

for (int i = 0; i != size-1; i++) { 
+0

我推薦<而非!=。這是更安全的,因爲如果我以某種方式增長大小-1,循​​環將仍然終止。當然,在這段代碼中「不應該發生」,但「不應該發生」+不可避免的錯誤==「可能遲早會發生」。 – 2009-10-14 22:17:47

0

那是因爲我==大小-1,I + 1 ==大小。而wordList [size]不在列表的末尾。您可能需要將您的for循環條件更改爲「i < size - 1」。

2

您應該將您的代碼更改爲for (int i = 0; i < size-1; i++) {,因爲wordList[i+1]的值必須小於size。結果意味着i < size -1

C/C++數組的索引是否可以從0size-1

0

它不是NULL,它超出範圍。在進行比較之前,您至少應該檢查一下我的尺寸是否爲<。

無論如何,我不確定你想要做什麼,但這是一個更廣泛的問題。

7

兩個問題。

首先,它通常會更好地循環,直到您的索引爲<您的大小,而不是使用!=。你有什麼應該仍然在這裏工作。

的問題是這一行:

if (wordList[i] == wordList[i+1]) 

您需要可以停止你的一環前面(我<大小 - 1)或者改變你的if語句,使其只檢查單詞表[I] ==詞表[i + 1]當數組中至少有一個條目時。

更簡單的方法可能是循環從i = 1到i <大小,檢查單詞列表[I-1] ==單詞表[我]:

for(int i = 1; i < size; i++) { 
    if(wordList[i - 1] == wordList[i]) { 
    /* same as before */ 
    } 
    /* everything else the same */ 
} 

這將阻止你需要額外的if語句,但仍會保護您不受數組限制。

編輯:

正如評論所說,如果你使用的所有原代碼,只是改變循環就像我提到會有關閉的情況-1的錯誤,但它很容易修復。

開始在1而不是0的字數。你知道你永遠至少有一個獨特的詞。每次看到新單詞時,循環都會增加計數,所以最終會得到適當的計數。

當wordList爲空時,您需要的唯一額外處理是。因此,您需要快速檢查單詞列表是否爲空,並且在這種情況下計數爲0.

+0

迄今爲止最好的答案。 +1。 – 2009-10-14 16:26:27

+0

但是,這不僅僅意味着wordList [0]沒有被計數,因爲else語句下的cout命令從wordList [1]開始,並從那裏增加? – IanWhalen 2009-10-14 16:32:44

+0

同樣在一系列詞語中,例如「a b b c c d」,它將以第一個'b'開始並且發現b!= a然後打印「b 1」,不是嗎?當正確的輸出將以「a 1」開始,然後是「b 2」? – IanWhalen 2009-10-14 16:36:55

0

您可以檢查i == wordList的長度並退出/跳過if。

0

有時只是代碼可以更簡單...如果你使用了別的東西。

問題描述:返回一個重複的單詞列表,每個單詞都有一個計數爲的關聯

就我個人而言,我會去爲這樣一個聲明的std :: map。

// Yeah it feels stupid, but I want default construction to initialize... 
struct MyCount 
{ 
    MyCount() : _count(0) {} 
    size_t _count; 
}; 

std::ostream& operator<<(std::ostream& out, const MyCount& rhs) 
{ 
    return out << rhs._count; 
} 

int main() 
{ 
    cout << "Enter a series of words separated by spaces, " 
      "followed by end-of-file: "; 

    typedef std::map<std::string, MyCount> map_type; 
    map_type wordList; 
    std::string x; 
    while (std::cin >> x) 
    wordList[x] += 1; // This is why I have a struct instead of a plain size_t 

    if (wordList.empty()) { 
    cout << endl << "This list appears empty. " 
        "Please try again." << endl; 
    return 1; 
    } 

    cout << "Your word count is as follows:" << endl; 
    for (map_type::const_iterator it = wordList.begin(), end = wordList.end(); it != end; ++ it) { 
    std::cout << it->first << " " << it->second << std::endl; 
    } 
    return 0; 
} 

我知道的std ::向量是默認的容器,但如果你是「關聯」兩個實體(在這裏一個詞,它的發生次數)時,你會好起來的思維關聯容器。

+0

如果我在python中做它,我肯定會使用一個字典,我認爲它是一個關聯容器的python等價物。到目前爲止,雖然我正在使用的文本只引入了矢量,所以我被卡住了,用相當黑客的方式得到答案。 – IanWhalen 2009-10-15 23:16:30

+0

那麼,我希望你們不要在地圖上留下太久的地圖! – 2009-10-16 07:47:19