【问题标题】:Why is this merge sort implementation not working properly?为什么这个合并排序实现不能正常工作?
【发布时间】:2020-10-11 13:08:03
【问题描述】:

以下是我的合并排序实现,它的作用是接受整数对数组并根据对中的第二个元素对它们进行排序(平局被对中的第一个元素打破,所有元素都是不同的)

void mer(vector<pair<int, int>> a, int l, int m, int r, vector<pair<int, int>> res) {
    int i = l;
    int j = m;
    int k = l;
    while (i < m && j < r) {
        if (a[i].second < a[j].second) {
            res[k] = a[i];
            i++;
            k++;
        } else
        if (a[i].second > a[j].second) {
            res[k] = a[j];
            j++;
            k++;
        } else {
            if (a[i].first > a[j].first) {
                res[k] = a[j];
                k++;
                j++;
            } else {
                res[k] = a[i];
                i++;
                k++;
            }
        }
    }
    while (i < m) {
        res[k] = a[i];
        k++;
        i++;
    }
    while (j < r) {
        res[k] = a[j];
        k++;
        j++;
    }
    for (int i = l; i < r; i++) {
        a[i] = res[i];
    }
}
    
void solve(vector<pair<int, int>> a, int l, int r, vector<pair<int, int>> res) {
    if (l < r) {
        int m = (l + r) / 2;
        solve(a, l, m, res);
        solve(a, m + 1, r, res);
        mer(a, l, m, r, res);
    }
}

但是当我使用main 运行我的代码时:

int main() {
    int n;
    cin >> n;
    map<int, int> a;

    for (int i = 0; i < n; i++) {
        int u;
        cin >> u;
        a[u]++;
    }
    vector<pair<int, int>> b;
    for (auto i : a) {
        b.push_back(i);
    }
    vector<pair<int, int>> res(b.size());
    solve(b, 0, b.size(), res);
}

考虑我的输入是:

10
1 1 1 1 1 1 2 2 3 3
it outputs 
1 6
2 2
3 2

这就是输入是什么,输出是一样的。 我花了很多时间寻找问题。我无法修复它。

【问题讨论】:

  • 首先,请统一格式化您的代码。能够阅读它,识别它的结构对于理解它很重要,这反过来又有助于发现和纠正错误。此外,将您的代码减少到minimal reproducible example。作为这里的新用户,也请带上tour并阅读How to Ask

标签: c++ sorting mergesort


【解决方案1】:

您的代码中存在多个问题:

  • vector 对象应该通过引用传递。

  • res 不是solve() 函数的目的地,而是作为mer 的临时存储的辅助向量。称它为tmp 会更容易混淆。

  • solve() 中的 r 索引被排除在外,因此对少于 2 个元素的切片的测试和递归调用应该是:

    void mer(vector<pair<int, int>>& a, int l, int m, int r, vector<pair<int, int>>& res) {
        int i = l;
        int j = m;
        int k = l;
        while (i < m && j < r) {
            if (a[i].second < a[j].second) {
                res[k] = a[i];
                i++;
                k++;
            } else
            if (a[i].second > a[j].second) {
                res[k] = a[j];
                j++;
                k++;
            } else {
                if (a[i].first > a[j].first) {
                    res[k] = a[j];
                    k++;
                    j++;
                } else {
                    res[k] = a[i];
                    i++;
                    k++;
                }
            }
        }
        while (i < m) {
            res[k] = a[i];
            k++;
            i++;
        }
        while (j < r) {
            res[k] = a[j];
            k++;
            j++;
        }
        for (int i = l; i < r; i++) {
            a[i] = res[i];
        }
    }
    
    void solve(vector<pair<int, int>>& a, int l, int r, vector<pair<int, int>>& tmp) {
        if (r - l >= 2) {
            int m = (l + r) / 2;
            solve(a, l, m, tmp);
            solve(a, m, r, tmp);
            mer(a, l, m, r, tmp);
        }
    }
    
  • main() 函数中,您不会将输入值存储到对的向量中,您还应该打印已排序的对:

    int main() {
        int n;
        cin >> n;
    
        vector<pair<int, int>> a(n);
    
        for (int i = 0; i < n; i++) {
            a[i].first = i + 1;
            cin >> a[i].second;
        }
        vector<pair<int, int>> tmp(n);
        solve(a, 0, n, tmp);
        for (int i = 0; i < n; i++) {
            printf("%d %d\n", a[i].first, a[i].second);
        }
        return 0
    }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 2020-09-19
    • 1970-01-01
    • 2021-01-18
    相关资源
    最近更新 更多