2013-09-27 22 views
0

我遇到了這個程序的麻煩。該程序應該告訴用戶在給定輸入中有多少行,單詞,字符,唯一行和唯一字。到目前爲止,文字和字符都可以。但是,如果用戶想要輸入多行,我該怎麼做?這些函數一次只輸出一行的結果,而不是將兩行的結果相加。另外,我無法使獨特線條和獨特詞語正常工作。我剛剛進入C++,所以我沒有太多經驗。有人可以幫幫我嗎?獨特的線條和單詞?如何實現它?

問題:

  1. 程序讀取在每次一行,所以當用戶輸入多次,程序分別生成結果,而不是增加其一起作爲一個實體。
  2. 唯一線條和唯一字詞不起作用。任何想法如何使用該程序中使用的庫來實現它。

    #include <iostream> 
    using std::cin; 
    using std::cout; 
    using std::endl; 
    #include <string> 
    using std::string; 
    #include <set> 
    using std::set; 
    
    
    // write this function to help you out with the computation. 
    
    
    unsigned long countLines() 
    { 
        return 1; 
    } 
    
    
    
    unsigned long countWords(const string& s) 
    { 
        int nw =1; 
        for (size_t i = 0; i < s.size(); i++) 
        { 
         if (s[i] == ' ') //everytime the function encounters a whitespace, count  increases by 1)// 
         { 
          nw++; 
         } 
        } 
    return nw; 
    } 
    
    unsigned long countChars(const string& s) 
    { 
        int nc = 0; 
        for (size_t i = 0; i < s.size(); i++) 
        { 
         if (s[i] != ' ') //everytime the function encounters a character other than a whitespace, count increases// 
         { 
          nc++; 
         } 
        } 
    
        return nc; 
    } 
    
    
    unsigned long countUnLines(const string& s, set<string>& wl) 
    { 
        wl.insert(s); 
        return wl.size(); 
    } 
    
    
    
    unsigned long countUnWords(const string& s, set<string>& wl) 
    { 
        int m1 = 0; 
        int m2 = 0; 
        string substring; 
    
        for(m2 = 0; m2 <= s.size(); m2++){ 
         if (m2 != ' ') 
    
         substring = s.substr(m1,m2); 
         wl.insert(substring); 
    
         m1 = m2 + 2;} 
        } 
    
        return wl.size(); 
    
        int unw = 0; 
        wl.insert(s); 
        unw++; 
        return unw; 
    } 
    
    int main() 
    { 
        //stores string 
        string s; 
    
        //stores stats 
        unsigned long Lines = 0; 
        unsigned long Words = 0; 
        unsigned long Chars = 0; 
        unsigned long ULines = 0; 
        unsigned long UWords = 0; 
    
        //delcare sets 
        set<string> wl; 
    
        while(getline(cin,s)) 
        { 
    
         Lines += countLines(); 
         Words += countWords(s); 
         Chars += countChars(s); 
         ULines += countUnLines(s,wl); 
         UWords += countUnWords(s); 
    
         cout << Lines << endl; 
         cout << Words<< endl; 
         cout << Chars << endl; 
         cout << ULines << endl; 
         cout << UWords << endl; 
    
    
         Words = 0; 
         Chars = 0; 
         ULines = 0; 
         UWords = 0; 
    
        } 
    
        return 0; 
    } 
    
+0

您顯示了很多註釋行,其中很多回答了您所問的問題。你現在發佈的內容不會運行,因爲'main'被註釋掉了,但是在那裏,它正確地讀取了行。將你的'cout'移到while循環的外部,並在循環結束時刪除所有的東西到0。此外,檢查行中單詞的代碼有一個錯誤:「一個單詞[6個空格]和一個」'將導致8個單詞。 –

回答

0

你在你的函數getline while循環結束重置計數變量爲零。這就是爲什麼你只能得到一行的結果。用戶可以在程序中輸入多行,因爲它現在只是重置計數。

+0

或將每行/字轉儲到std :: set或std :: unordered_set,然後輸出.size()。 – bstamour

+0

但是,當我刪除這些重置計數器時,每次輸入行時,計數器都會從停止的位置繼續。例如我輸入一行,它輸出1.然後,當我輸入另一行時,它應該說1輸出2. – user2816003

+0

嗯,我想這取決於你。這聽起來像是你想通過換行符累積它們。 – spartacus

0

我認爲你正朝着正確的方向前進。爲了計算獨特的行和單詞,你必須將每行和每一行存儲在某種數據結構中,我建議使用unordered_map。地圖中的每個元素都會有一個計數器,用於每行/每個詞的出現次數。

0

我不想讓批發的答案,但這裏有一些想法讓你開始。

  1. 函數getline()可以在整行輸入中讀取。做到這一點,直到沒有更多的輸入。
  2. 您可以使用像std :: set(或更好,std :: unordered_set)這樣的容器來存儲讀入的行。不是最高效的,但它會跟蹤所有行,並且只存儲唯一行。
  3. 然後每條線可以分解成單詞。考慮使用像std :: stringstream這樣的東西。
  4. 將單詞存儲在不同的std :: unordered_set中。
  5. 唯一行(單詞)的數量就是存儲在容器中的行數(單詞)。使用.size()方法來獲取它。

在讀取數據時,可以計算行數,字數和字符總數,所以我不會在那裏詳細討論。

每個項目都是Googleable的,您可以選擇以不同的方式實現不同的部分(例如,如果您不想使用字符串流,則可以遍歷整個讀取行)。這應該讓您在右側跟蹤。

+0

我明白你在說什麼。我嘗試將字符串轉儲到集合中,並讓程序返回集合的大小。然而,櫃檯只是隨着每條線路不斷增加而沒有任何變化。 – user2816003

+0

例如,我輸入一行,輸出表示唯一行。然後,當我再次做到這一點時,計數應該只有一個,最多兩個。 – user2816003

+0

這聽起來像是你沒有正確地計算事物。對於在一行中讀取的每一次迭代,您應該a)更新「總計行數」計數器,以及b)將該行放入一個集合中。在循環結束時,您將有一個計數器,用於存儲所讀取的總行數,以及一個包含每條唯一行的集合。做相同的語言邏輯,你完成了很多。 – bstamour

0

很容易得到相當於準確的計數,但可能令人驚訝地難以得到所有這些的正確計數。

最大的問題是字符數量。如果您在文本模式下打開文件(如通常那樣),則您計算的字符數可能與操作系統認爲的字符數不匹配。對於顯而易見的例子,在Windows下,一個CR/LF對將被轉換成一個單行換行符,所以通常你會將每一行計算爲比實際短的一個字符。

從技術上說,沒有辦法完全正確地處理這個問題 - 當文件在文本模式下打開時,從外部到內部表示的轉換在理論上是任意的。至少在理論上,以二進制模式打開並不會有很大幫助;在二進制模式下,在寫入文件的數據結束後,可以有任意數量的NUL字符。

但是,後者,這些天是非常理論(主要是因爲CP/M,大多數人早已被遺忘)。

要讀取行,但保留行末端分隔符完好無損,可以使用std::cin.get()而不是std::getline(),然後分別從行本身讀取分隔符。

這爲我們提供了這樣的事情:

#include <iostream> 
#include <set> 
#include <string> 
#include <iterator> 
#include <sstream> 
#include <fstream> 

int main(int argc, char **argv) { 
    static char line[4096]; 
    unsigned long chars = 0; 
    unsigned long words = 0; 
    unsigned long lines = 0; 
    std::set<std::string> unique_words; 

    std::ifstream in(argv[1], std::ios::binary); 

    while (in.get(line, sizeof(line), '\n')) { 
     ++lines; 
     chars += strlen(line); 

     std::istringstream buffer(line); 
     std::string word; 
     while (buffer >> word) { 
      ++words; 
      unique_words.insert(word); 
     } 
     while (in.peek() == '\n' || in.peek() == '\r') { 
      ++chars; 
      in.ignore(1); 
     }  
    } 
    std::cout << "words: " << words << "\n" 
       << "lines: " << lines << "\n" 
       << "chars: " << chars << "\n" 
       << "unique words: " << unique_words.size() << "\n"; 
} 

注意的是,雖然這確實答案是,OP至少居然問了最典型的操作系統(Linux操作系統,* BSD,MacOS的,Windows)中,它可能不是他真正想要的。我的猜測是,他的老師並沒有真正要求這種關心的水平來嘗試獲得準確的字符數。

另請注意,如果您應該遇到比緩衝區更長的行,這仍然會給出不準確的行數 - 它會將每個緩衝區計數爲全部數據作爲單獨的行,即使它沒有找不到行分隔符。這也可以得到解決,但它增加了一個程序的複雜性,這個程序幾乎可以肯定比預期的要複雜得多。