为什么我从GNU g ++和VC ++中得到不同的结果

时间:2017-07-02 11:35:33

标签: c++ visual-c++ g++ c++14

我正在尝试用C ++解决这个问题:

“给定一个整数序列S,找到一些递增的序列I,使得I中的每两个连续元素出现在S中,但是在I的第一个元素的相对侧。”

这是我开发的代码:

#include<iostream>
#include<set>
#include<vector>

using namespace std;

struct Element {
long long height;
long long acc;
long long con;
};

bool fncomp(Element* lhs, Element* rhs) {
    return lhs->height < rhs->height;
}

int solution(vector<int> &H) {
    // set up
    int N = (int)H.size();
    if (N == 0 || N == 1) return N;
    long long sol = 0;
    // build trees
    bool(*fn_pt)(Element*, Element*) = fncomp;
    set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt),   leftTree(fn_pt);
    set<Element*, bool(*)(Element*, Element*)>::iterator ri, li;
    for (int i = 0; i < N; i++) {
        Element* e = new Element;
        e->acc = 0;
        e->con = 0;
        e->height = H[i];
        rightTree.insert(e);
    }
    //tree elements set up
    ri = --rightTree.end();
    Element* elem = *ri;
    elem->con = 1;
    elem->acc = 1;
    while (elem->height > H[0]) {
        Element* succ = elem;
        ri--;
        elem = *ri;
        elem->con = 1;
        elem->acc = succ->acc + 1;
    }
    rightTree.erase(ri);
    elem->con = elem->acc;
    leftTree.insert(elem);
    sol += elem->acc;
    // main loop
    Element* pE = new Element;
    for (int j = 1; j < (N - 1); j++) {
        // bad case
        if (H[j] < H[j - 1]) {
            ///////
            Element* nE = new Element;
            nE->height = H[j];
            pE->height = H[j - 1];
            rightTree.erase(nE);
            leftTree.insert(nE);
            ///////
            li = leftTree.lower_bound(pE);
            long ltAcc = (*li)->acc;
            li--;
            ///////
            ri = rightTree.lower_bound(pE);
            long rtAcc = 0;
            if (ri != rightTree.end()) rtAcc = (*ri)->acc;
            ri--;
            ///////
            while (ri != (--rightTree.begin()) && (*ri)->height > H[j]) {
                if (fncomp(*ri, *li)) {
                    (*li)->con = rtAcc + 1;
                    (*li)->acc = rtAcc + 1 + ltAcc;
                    ltAcc = (*li)->acc;
                    --li;
                }
                else {
                    (*ri)->con = ltAcc + 1;
                    (*ri)->acc = ltAcc + 1 + rtAcc;
                    rtAcc = (*ri)->acc;
                    --ri;
                }
            }
            while ((*li)->height > H[j]) {
                (*li)->con = rtAcc + 1;
                (*li)->acc = rtAcc + 1 + ltAcc;
                ltAcc = (*li)->acc;
                --li;
            }
            (*li)->con = rtAcc + 1;
            (*li)->acc = rtAcc + 1 + ltAcc;
            sol += (*li)->acc;
        }
        // good case
        else {
            Element* nE = new Element;
            nE->height = H[j];
            ri = rightTree.upper_bound(nE);
            li = leftTree.upper_bound(nE);
            rightTree.erase(nE);
            if (li == leftTree.end() && ri == rightTree.end()) {
                nE->con = 1;
                nE->acc = 1;
            }
            else if (li != leftTree.end() && ri == rightTree.end()) {
                nE->con = 1;
                nE->acc = 1 + (*li)->acc;
            }
            else if (li == leftTree.end() && ri != rightTree.end()) {
                nE->con = (*ri)->acc + 1;
                nE->acc = nE->con;
            }
            else {
                nE->con = (*ri)->acc + 1;
                nE->acc = nE->con + (*li)->acc;
            }
            leftTree.insert(nE);
            sol += nE->acc;
        }
    }
    // final step
    li = leftTree.upper_bound(*rightTree.begin());
    while (li != leftTree.end()) {
        sol++;
        li++;
    }
    sol++;
    return (int)(sol % 1000000007);
}

int main(int argc, char* argv[]) {
    vector<int> H = { 13, 2, 5 };
    cout << "sol: " << solution(H) << endl;
    system("pause");
}

main函数调用solution(vector<int> H)。关键是,当参数具有特定值H = {13, 2, 5} 时,VC ++编译的程序给出输出值7 (这是正确的),但是GNU g ++编译程序给出的输出值为5 (同样clang编译的程序就像这样)。

我正在使用这个网站来测试不同的编译器 http://rextester.com/l/cpp_online_compiler_gcc

我试图弄清楚这种奇怪行为的原因,但没有找到任何相关信息。只有一个帖子处理类似的问题: Different results VS C++ and GNU g++ 这就是我在代码中使用long long类型的原因,但问题仍然存在。

1 个答案:

答案 0 :(得分:0)

问题是减少了序列开始--rightTree.begin()

正如我发现VC ++和GNU g ++在上述操作中的行为方式不同。以下是显示差异的代码,改编自http://www.cplusplus.com/forum/general/84609/

#include<iostream>
#include<set>

using namespace std;

struct Element {
long long height;
long long acc;
long long con;
};

bool fncomp(Element* lhs, Element* rhs) {
    return lhs->height < rhs->height;
}

int main(){

    bool(*fn_pt)(Element*, Element*) = fncomp;
    set<Element*, bool(*)(Element*, Element*)> rightTree(fn_pt);
    set<Element*, bool(*)(Element*, Element*)>::iterator ri;

    ri = rightTree.begin();
    --ri;
    ++ri;
    if(ri == rightTree.begin()) cout << "it works!" << endl;
}