You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于冒泡排序的Vector日期排序异常问题排查求助

问题排查:家庭预算APP中Income向量日期排序错误

我是编程新手,正在开发一款家庭预算管理APP,所有数据存储在XML文件中。我尝试用冒泡排序对income类型的Vector按日期排序,但结果不符合预期,求帮忙排查错误。

代码实现

#include <iostream>
#include <vector>
#include <string>
#include "Markup.h"

using namespace std;

class income{
    int userId;
    int amount;
    int itemId;
    string item;
    string date;
    public:
    void setUserId(int i) {userId = i;}
    void setAmount(int a) {amount = a;}
    void setItemId(int i ) {itemId = i;}
    void setDate(string d) {date = d;}
    void setItem(string i) {item = i;}

    int getUserId()   {return userId;}
    int getAmount()   {return amount;}
    int getItemId()  {return itemId;}
    string getItem() {return item;}
    string getDate()  {return date;}
};

bool returnOlderDate(string date1,string date2) {

    int year1 = stoi(date1.substr(0,2));
    int month1 = stoi(date1.substr(3,2));
    int day1 = stoi(date1.substr(6,2));

    int year2 = stoi(date2.substr(0,2));
    int month2 = stoi(date2.substr(3,2));
    int day2 = stoi(date2.substr(6,2));

    if (year1 != year2) {
        return year1 < year2;
    }
    if (month1 != month2) {
        return month1 < month2;
    }
    return day1 < day2;
}
void sortVector(vector <income> &incomes) {

    int n = incomes.size();

    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            if (returnOlderDate(incomes[j].getDate(), incomes[j + 1].getDate())) {

                swap(incomes[j], incomes[j + 1]);
            } else {

            }
        }
    }
}

vector <income> LoadIncome() {

    CMarkup xml;

    vector <income> incomes;
    bool fileExists = xml.Load("income.xml");

    if(!fileExists) {
        cout << "Empty File" << endl;
        return incomes;
    }

    xml.ResetPos();
    xml.FindElem();
    xml.IntoElem();

    while(xml.FindElem()) {
        income newIncome;
        xml.FindChildElem("userId");
        newIncome.setUserId(stoi(xml.GetChildData()));
        xml.FindChildElem("itemId");
        newIncome.setItemId(stoi(xml.GetChildData()));
        xml.FindChildElem("amount");
        newIncome.setAmount(stoi(xml.GetChildData()));
        xml.FindChildElem("item");
        newIncome.setItem(xml.GetChildData());
        xml.FindChildElem("date");
        newIncome.setDate(xml.GetChildData());
        incomes.push_back(newIncome);
    }

    return incomes;
}

void showIncomes(vector <income>& incomes) {

    for(auto i : incomes) {
        cout << "date: " << i.getDate() << endl;
    }
}

int main()
{
    vector <income> incomes;
    incomes = LoadIncome();

    sortVector(incomes);
    showIncomes(incomes);

    return 0;
}

XML文件内容

<Income>
<income>
<userId>1878039312</userId>
<incomeId>1877999744</incomeId>
<amount>23</amount>
<item>23</item>
<date>02-05-2024</date>
</income>
<income>
<userId>1878039312</userId>
<incomeId>1877999744</incomeId>
<amount>1243</amount>
<item>1243</item>
<date>01-06-2024</date>
</income>
<income>
<userId>1878039312</userId>
<incomeId>1877999744</incomeId>
<amount>1243</amount>
<item>1243</item>
<date>02-03-2023</date>
</income>
<income>
<userId>1878039312</userId>
<incomeId>1877999744</incomeId>
<amount>1243</amount>
<item>1243</item>
<date>28-05-2024</date>
</income>

错误原因及修正方案

1. 日期解析逻辑完全错误

你的日期格式是DD-MM-YYYY(例如02-05-2024代表2024年5月2日),但returnOlderDate函数的子串截取完全搞反了:

  • 原代码取substr(0,2)作为年份,实际这是日
  • 原代码取substr(6,2)作为日,实际这是年份的后两位,正确年份应该取substr(6,4)

修正后的returnOlderDate函数:

bool returnOlderDate(string date1, string date2) {
    // 适配 DD-MM-YYYY 格式
    int day1 = stoi(date1.substr(0,2));
    int month1 = stoi(date1.substr(3,2));
    int year1 = stoi(date1.substr(6,4));

    int day2 = stoi(date2.substr(0,2));
    int month2 = stoi(date2.substr(3,2));
    int year2 = stoi(date2.substr(6,4));

    if (year1 != year2) {
        return year1 < year2;
    }
    if (month1 != month2) {
        return month1 < month2;
    }
    return day1 < day2;
}

2. 冒泡排序的排序方向不符合预期

原代码中,当incomes[j]的日期比incomes[j+1]旧时,会交换两者,最终得到的是降序排列(最新日期在前)。如果需要升序排列(最旧日期在前),需要调整判断条件:

void sortVector(vector <income> &incomes) {
    int n = incomes.size();
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            // 前一个日期比后一个新,就交换,最终得到升序(旧→新)
            if (!returnOlderDate(incomes[j].getDate(), incomes[j + 1].getDate())) {
                swap(incomes[j], incomes[j + 1]);
            }
        }
    }
}

如果需要降序,保持原判断即可。

3. XML节点匹配错误(次要bug)

XML中存储ID的节点是<incomeId>,但LoadIncome函数里查找的是<itemId>,导致itemId无法正确赋值,修正如下:

// 在LoadIncome函数中
xml.FindChildElem("incomeId"); // 替换原有的"itemId"
newIncome.setItemId(stoi(xml.GetChildData()));

修正后预期结果

升序排列时,输出的日期顺序为:

date: 02-03-2023
date: 02-05-2024
date: 28-05-2024
date: 01-06-2024

内容的提问来源于stack exchange,提问作者Bartosz Kowalski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:50:56