2015-09-23 78 views
0
bool isContainedSameForm(AG ag1, AG ag2){ 
    if(isEmpty(ag2)) return false; 
    return isContainedSameForm(ag1->pH,ag2->pH) && isContainedSameForm(ag1->sH,ag2->sH); 
}; 
int sameFormOcurrences(AG ag1,AG ag2,bool (*isContainedSameForm)(AG,AG)){ 
    if(isEmpty(ag2)) return 0; 
    int ret=0; 
    if(isContainedSameForm(ag1,ag2)) ret=1; 
    return ret + sameFormOcurrences(ag1,ag2->pH,isContainedSameForm) + sameFormOcurrences(ag1,ag2->sH,isContainedSameForm); 
}; 

int sameFormOcurrences(AG ag1, AG ag2){ 
    return sameFormOcurrences(ag1,ag2,isContainedSameForm); 
} 

AG是一个普通的树,这计数相同形式的树有多少次出现在第二树C/C++函数的参数

enter image description here

我不明白的是第一个目的sameFormOcurrences函数接收isContainedSameForm参数。

仅仅是改变签名而不改变它的名字的一种方法? 如果它试图避免未定义的方法,那么它是否与上面已经声明的函数重复?

+0

是的,在这种情况下它有什么用途? –

+2

这是一个谓词。这意味着您可以传递不同的算法来检查它是否包含在同一个表单中,而不会更改sameFormOcurrences。 –

+6

它可以让你使用你自己的函数,而不是硬编码到'isContainedSameForm'中,就像使用普通的函数调用一样。参数具有相同名称的事实是无关紧要的。 –

回答

2

此代码不是以最佳风格,函数指针参数和实现该函数的函数编写的,实际上应该具有不同的名称。现在,如果参数声明中存在拼写错误,那么函数内的代码将直接引用另一个函数,并且该参数将默默无用。

这会好得多:

int countMatchingDescendants(AG ag1,AG ag2,bool (*matchCondition)(AG,AG)) 
{ 
    if(isEmpty(ag2)) return 0; 
    int ret=0; 
    if(matchCondition(ag1,ag2)) ret=1; 
    return ret + countMatchingDescendants(ag1,ag2->pH,matchCondition) + countMatchingDescendants(ag1,ag2->sH,matchCondition); 
} 

bool isContainedSameForm(AG ag1, AG ag2) 
{ 
    if(isEmpty(ag2)) return false; 
    return isContainedSameForm(ag1->pH,ag2->pH) && isContainedSameForm(ag1->sH,ag2->sH); 
} 

int sameFormOcurrences(AG ag1, AG ag2) 
{ 
    return countMatchingDescendants(ag1,ag2,isContainedSameForm); 
} 

请注意,我只是改变了标识的名称,而不是代码的结构(函数体之外我也删除多余的分号)。但是现在计数代码有一个通用名称,表明它实际上有多灵活。

通过更改顺序,我防止了泛型计数代码意外引用具体实现的任何可能性。

+0

这个问题的答案如何? – YePhIcK