2014-10-03 104 views
1

我正在編程一個雙向鏈表,其中我從給定文件中讀取字符串。 因此,我編寫了一個名爲Node的類,其中存儲了一個字符串(讀取字)以及字長和其他參數的一些整數。計數列表元素

當我讀取所有字符串形成文件後,我打開第二個文件,並再次讀出每個單詞,並將該單詞與鏈接列表中的字符串進行比較。之後,我將每個找到的單詞存儲在結果文件中。

現在我想顯示找到的詞有它的文本位置的用戶,例如:

「上找到在thext文件中的200處字」

因此我創建了一個計數器,每創建一個新節點就增加一個計數器。我現在的問題是,我的計數器只是統計了整個創建了多少個節點。所以我只看到創建了大約56000個節點,但我無法存儲節點的編號。

我在做什麼錯?

編輯:我沒有嘗試減少計數器,因爲我從不刪除一個節點。 這裏是我完整的代碼

#include <iostream> 
#include <string> 
#include <stdio.h> 
#include <fstream> 
#include <cstring> 

using namespace std; 
class Word 
{ 
    public: 
    Word (string inputstring = 0, int b = 0, int c = 0, int l = 0, Word *n = 0, Word *p = 0) : word (inputstring), book (b), chapter (c), length (l), next (n), prev (p) 
    { 
     ++counter; 
    } 
    int book; 
    int chapter; 
    int length; 
    string word; 
    Word *next; 
    Word *prev; 

    static size_t howMany() 
    { 
     return counter; 
    } 

    private: 
     static size_t counter; 
}; 

size_t Word::counter; 

int main() 
{ 
    string inputstring = "empty"; 
    string compare = "empty"; 
    int l1 = 0; 
    int book = 0; 
    int chapter = 0; 
    int count = 0; 
    Word *p = 0; 
    Word *x = 0; 
    Word *start = 0; 

    ifstream file; 
    file.open("Beispieltext.txt"); 

    ofstream outfile; 

    if (!file) cout << ("can't open input file"); 
    else   cout << "File: Beispieltext.txt open\n"; 

    // create nodes 
    while (file >> inputstring) 
    { 
     l1 = (int)inputstring.length(); 

     if ((!(inputstring[0] >= 'A' && inputstring[0] <= 'Z')) && (!(inputstring[0] >= 'a' && inputstring[0] <= 'z'))) inputstring = inputstring.substr(1,l1--); // l1-- reduce length 
     while ((!(inputstring[l1-1] >= 'A' && inputstring[l1-1] <= 'Z')) && (!(inputstring[l1-1] >= 'a' && inputstring[l1-1] <= 'z'))) inputstring = inputstring.substr(0,--l1); // --l1 go till n-1 

     // book? 
     if (std::strncmp(inputstring.data(), "BOOK", 4) == 0) ++book, chapter = 0/*, cout << "\nBook Nr.: " << book << "\n"*/; 

     // Chapter? 
     if (std::strncmp(inputstring.data(), "CHAPTER", 7) == 0) ++chapter/*, cout << "chapter: " << chapter << "\n"*/; 

     if (p == NULL) 
     { 
      p = new Word (inputstring); 
     } else 
     { 
      x = new Word (inputstring, book, chapter, l1, 0, p); 
      p->next = x; 
      p = x; 
     } 
    } 
    file.close(); 
    cout << "File: Beispieltext.txt closed!\n"; 

    // n...0 
    for (; p; p = p->prev) start = p; // go to start 

    // Open compare file 1 
    file.open("Suchbegriffe_1.txt"); 
    if (!file) cout << "Can't open compare file!\n"; 
    else  cout << "File: Suchbegriffe.txt open!\n"; 

    // Open result file 1 
    outfile.open("Result_1.txt"); 
    if(!outfile) cout << "Can't open Result_1.txt file!\n"; 
    else  cout << "File: Result_1.txt open!\n"; 

    while (file >> compare) 
    { 
     l1 = (int)compare.length(); 
     // Search 
     x = start; 
     // 0...n go to end 
     for (; x; x = x->next) 
     { 
      if (l1 == x->length) 
      { 
       if (compare == x->word) 
       { 
        outfile << "Word: " << compare << " found in book Nr.: " << x->book << ", chapter: " << x->chapter << "!\n"; 
        outfile << "Word: " << compare << " is the " << x->howMany() << " Word in the book.\n"; 
        count++; 
       } 
      } 
     } 
     outfile << "Word: " << compare << ", " << count << "x found!\n"; 
     count = 0; 
    } 
    file.close(); 
    cout << "File: Suchbegriffe_1.txt closed!\n"; 
    outfile.close(); 
    cout << "File: Result.txt closed!\n"; 

    // Open compare file 2 
    file.open("Suchbegriffe_2.txt"); 
    if (!file) cout << "Can't open compare file!\n"; 
    else  cout << "File: Suchbegriffe.txt open!\n"; 

    // Open result file 2 
    outfile.open("Result_2.txt"); 
    if (!outfile) cout << "Can't open Result_2 file!\n"; 
    else  cout << "File: Result_2.txt open!\n"; 

    while (file >> compare) 
    { 
     l1 = (int)compare.length(); 

     // Search 
     x = start; 
     // 0...n go to end 
     for (; x; x = x->next) 
     { 
      if (l1 == x->length) 
      { 
       if (compare == x->word) 
       { 
        outfile << "Word: " << compare << " found in book Nr.: " << x->book << ", chapter: " << x->chapter << "!\n"; 
        count++; 
       } 
      } 
     } 
     outfile << "Word: " << compare << ", " << count << "x found!\n"; 
     count = 0; 
    } 
    file.close(); 
    cout << "File: Suchbegriffe_2.txt closed!\n"; 

    outfile.close(); 
    cout << "File: Result_2.txt closed!\n"; 
} 
+0

請提供其餘的代碼(並正確格式化),而不是指望人們填寫空格。 – 2014-10-03 10:49:16

+0

你是否試圖在析構函數中減少計數器? – Jepessen 2014-10-03 10:49:16

+0

@Jepessen,這不會改變每個節點共享單個全局計數器的事實,因此不可能爲每個節點返回不同的ID – 2014-10-03 10:51:42

回答

2

我現在的問題是我的計數器只是計算多少節點在整個創建。

是的,因爲您有一個單一的全局計數器來計算創建的節點。

所以我只看到有大約56000個節點的創建,但我不能存儲節點的數量。

如果你想爲每個節點指定一個不同的數字,那麼你不能在一個地方存儲一個數字,並期望它有幾個不同的值!

您需要

  • 要麼商店中的每個節點作爲成員變量,而不是一個靜態變量的數字(但要確保你讓他們正確的,如果節點被添加或從一開始就刪除或列表的中間,如果你打算在程序中一次有兩個列表,請確保列表中的第一個節點具有數字0,即它必須是該列表中的數字不只是全局計數器)

  • ,要簡單得多,只要保留一個計數器,就可以遍歷列表併爲每個看到的節點增加一個計數器。你已經在計算匹配詞的數量,爲什麼你不能只保留所有檢查詞的總數,包括不匹配?

例如:

​​

注意,我宣佈環路(而不是在函數的頂部),內部變量和不打擾檢查字長,因爲比較std::string已經這樣做是。爲什麼你甚至將這個長度存儲在Word類中? x->word.length()告訴你的長度,你不需要明確地存儲它。

而且,這太瘋狂了:

for (; p; p = p->prev) start = p; // go to start 

這向後穿過一個大名單,找到開始......剛剛成立開始,當你分配的第一個節點,並保持它!

x = new Word (inputstring, book, chapter, l1, 0, p); 
    if (!start) 
     start = x; // remember the start 
    p->next = x; 
    p = x; 
0

我建議你在結果文件中存儲一個整數值和你找到的單詞。並在打印結果時顯示它。

或者您可以使用節點類中的位置變量來確定它的位置。

0

快速修復:

class Word 
{ 
    public: 
    Word (string inputstring = 0, int b = 0, int c = 0, int l = 0, Word *n = 0, Word *p = 0) 
     : word (inputstring), book (b), chapter (c), length (l), next (n), prev (p) 
    { 
     currCont = ++counter; 
    } 
    int book; 
    int chapter; 
    int length; 
    string word; 
    Word *next; 
    Word *prev; 
    int currCont; 

    size_t howMany() 
    { 
     return currCont; 
    } 

    private: 
    static size_t counter; 
}; 

// ...later... 

    x = start; 
    // 0...n go to end 
    for (; x; x = x->next) 
    { 
     if (l1 == x->length) 
     { 
      if (compare == x->word) 
      { 
       outfile << "Word: " << compare << " is the " << x->howMany() << " Word in the book.\n"; 
       count++; 
      } 
     } 
    } 
    outfile << "Word: " << compare << ", " << count << "x found!\n"; 
    count = 0; 
} 
+0

我試圖應用您的更改,但在'int curcounter'這一行中。我收到錯誤信息:\t \t 32 9 main.cpp [錯誤]靜態成員函數中成員'Word :: curcounter'的無效使用 – user3794592 2014-10-03 11:19:42

+0

'howMany'不應該是'靜態' – 2014-10-03 11:21:51

+0

您對錯誤表示抱歉。我編輯我的代碼。 – Logman 2014-10-03 13:20:52

1

變量counter是靜態的,這意味着它是班上唯一的一個。

所以說我正在用三個字讀:「a」,「b」和「c」。當我呼籲howMany「一」,它會返回3,「B」和「C」的howMany也將返回3.

我建議讓您的所有Word S IN一個std::vector,只是呼籲std::vector.size()得到Word計數。我將從counterhowMany中刪除static,並將字數作爲參數傳遞給Word構造函數,以便您可以將其存儲在您的counter成員變量中。

+0

+1,雖然我懷疑OP被告知要寫一個鏈表類,所以雖然你的建議是一個更好的主意,但它不會被允許:)不需要在Word中存儲一個計數,你可以通過減去矢量中第一個元素的地址,在矢量中找到它的位置。這樣做的好處是,當你在矢量 – 2014-10-03 11:17:54

+0

@JonathanWakely的中間添加/刪除元素時,你不需要更新每個元素的計數,這會更加理想。我只是想改造,而不是去大修,因爲我不知道哪裏會結束:) – 2014-10-03 11:34:54