2015-11-23 85 views
0

這樣的價值,我想實現線索結構,到目前爲止一切正常,除了以下:C++返回值從函數不一樣的功能

當使用count_words功能,我打印出結果就在返回它之前,並且結果是正確的,但是當我在main中打印它時,它會變成一些未知的奇怪整數值。

typedef struct trie { 
    int words; 
    int prefixes; 
    struct trie *characters[26]; 
} node; 

int find_character_location(int ascii) { 
    return ascii-97; 
} 

node * initialize() { 
    node * new_node = (node*)malloc(sizeof(node)); 
    new_node->words = 0; 
    new_node->prefixes = 0; 

    //all english alphabet characters 
    for(int i=0; i<26; i++) { 
     new_node->characters[i] = NULL; 
    } 

    return new_node; 
} 

//when adding string use only english lowercase letters 
//a=97 b=98 ... z=122 
void add_string(node * root, string str) { 
    int str_size = str.size(); 

    if(str_size == 0) { 
     root->words++; 
     return; 
    } 
    else { 
     int position = find_character_location(str[0]); 
     root->prefixes++; //character doesnt exists 
     if(root->characters[position] == NULL) { 
      root->characters[position] = initialize(); 
    } 
    add_string(root->characters[position], 
    str_size==1?"": str.substr(1)); 
    } 
} 

int count_prefixes(node *root, string prefix) { 
    int str_size = prefix.size(); 

    if(prefix == "") { 
     cout<<"number of prefixes: "<<(root->prefixes)<<endl; 
     return (*root).prefixes; 
    } 

    int position = find_character_location(prefix[0]); 

//character exists 
if(root->characters[position] != NULL) { 
    count_prefixes(
    root->characters[position],str_size==1?"":prefix.substr(1)); 

    } 
    else { 
     cout<<"no prefixes, returning 0"<<endl; 
     return 0; 
    } 
} 


int count_words(node *root, string str) { 
    int str_size = str.size(); 

    if(str == "") { 
     cout<<"Number of words: "<<root->words<<endl; 
     int ret = root->words; 
     return (int)ret; 
} 

int position = find_character_location(str[0]); 

//that character exists 
if(root->characters[position] != NULL) { 
    count_words(root->characters[position], 
    str_size==1 ? "" : str.substr(1)); 

    } 
    else { 
     cout<<"no words, returning 0"<<endl; 
     return 0; 
    } 
} 


int main() { 

    node * root; 
    root = initialize(); 

    add_string(root, "tomislav"); 
    add_string(root, "tomislav"); 
    add_string(root, "tomislav"); 
    add_string(root, "todoric"); 
    add_string(root, "tomahawk"); 
    add_string(root, "tosad"); 
    add_string(root, "tomo"); 

    cout<<"Counting words"<<count_words(root, "tomislav"); 
    return 0; 
} 

因此,例如,對於count_words(根,「托米斯拉夫」)在功能count_words它印3,但主要是印刷9872106

能否請你告訴我,我要去哪裏錯了?

+0

首先正確縮進此代碼。 –

+2

不確定是否與您的問題相關,但如果'str'不是空的,並且列表中有單詞,則實際上不會返回任何內容。 if(root-> characters [position]!= NULL)的'then'子句不包含'return'語句。 –

回答

1

你有多個count_words激活的調用(這就是遞歸如何工作),但只有最後一個實際返回一個值。

假設我們正在搜索「to」。 main將用「to」和根節點調用count_words。這將通過「o」和「t」節點呼叫count_words。這將使用「」和「to」節點呼叫count_words

上次調用打印「字數:7」,然後返回7到倒數第二次調用。中間調用忽略這個返回值,並且不返回一個值,所以它的返回值是垃圾。第一次調用忽略這個垃圾返回值,並且不返回值,所以它的返回值也是垃圾(可能不同的垃圾)。然後main打印來自第一次調用的返回值,這是垃圾。

你的中間調用需要返回一些東西。可能你只是想返回下一個返回的電話,所以請在count_words(root->characters[position],str_size==1?"":prefix.substr(1));前添加return。 (和count_prefixes類似)

+0

謝謝大家的回覆,你們都指出同樣的事情是正確的,這實際上是一個愚蠢的錯誤,但你會怎麼做。 @immibis你的答案是最具描述性的,所以這就是爲什麼我將它標記爲接受的答案 – Zorkan

1
int count_words(node *root, string str) { 
    int str_size = str.size(); 

    if(str == "") { 
     cout<<"Number of words: "<<root->words<<endl; 
     int ret = root->words; 
     return (int)ret; 
    } 

    int position = find_character_location(str[0]); 

    if(root->characters[position] != NULL) { 
     count_words(root->characters[position], 
     str_size==1 ? "" : str.substr(1)); 
     //********* 
    } 
    else { 
     cout<<"no words, returning 0"<<endl; 
     return 0; 
    } 
} 

我在哪裏用***標記,你沒有返回任何東西。
這導致未定義的行爲。

1

count_words並不總是返回一個值,這意味着,有時候,最終會給調用方提供任何廢話。該代碼是有點困難,因爲你的壓痕閱讀,但我懷疑你的意思是用於

if(root->characters[position] != NULL) { 
    count_words(root->characters[position], 
    str_size==1 ? "" : str.substr(1)); 

    } 

if(root->characters[position] != NULL) { 
    return count_words(root->characters[position], 
    str_size==1 ? "" : str.substr(1)); 

    } 
1

務必將你的編譯器的警告和錯誤的最大值。在兩個函數(count_prefixes()count_words())中,您有控制路徑終止,而不是返回一個值。修復這些,你的程序將正常工作。