C++结构体数组排序:按atitikme降序,相等时按Vardas字典序
解决结构体数组排序问题:补充字典序排序逻辑
你的问题出在当atitikme值相等时,没有按Vardas的字典序升序排序。我们需要修改冒泡排序的判断条件,在atitikme相等时比较两个Vardas的字符串大小,把字典序更小的元素排到前面。
核心逻辑说明
当两个Sheep元素的atitikme相等时,我们要判断A[p].Vardas是否小于A[o].Vardas——C++里std::string可以直接用<运算符比较字典序,遵循ASCII字符规则。如果满足这个条件,就交换两个元素的位置,这样字典序更小的Vardas会被放到更靠前的位置,刚好匹配你的目标输出。
更简洁的修改方案:直接交换结构体对象
你原来的代码是逐个交换结构体成员,其实可以直接交换整个Sheep对象,这样既简洁又不容易出错,还能保证所有成员的对应关系不变:
// 假设n是数组元素个数,你给出的n=4(实际有效元素为3个) int n = 4; Sheep A[n]; // 已从U2.txt读取数据 for (int o = 0; o < n - 1; o++) { // 修正原代码的循环条件:p < n才能遍历到最后一个元素 for (int p = o + 1; p < n; p++) { // 排序条件:要么atitikme更大,要么atitikme相等但Vardas字典序更小 if (A[p].atitikme > A[o].atitikme || (A[p].atitikme == A[o].atitikme && A[p].Vardas < A[o].Vardas)) { // 直接交换整个结构体对象,无需手动逐个成员交换 Sheep temp = A[o]; A[o] = A[p]; A[p] = temp; } } }
如果你想保留原有的逐个成员交换方式
可以在原代码的if块之后添加else if逻辑,补充字典序判断:
string q; char w[20]; int e; int n = 4; int m = 6; for (int o = 0; o < n-1; o++) { // 修正循环条件为p < n,避免漏掉最后一个元素 for (int p = o+1; p < n; p++) { if (A[p].atitikme > A[o].atitikme) { // 原有的成员交换代码 q = A[o].Vardas; A[o].Vardas = A[p].Vardas; A[p].Vardas = q; e = A[o].atitikme; A[o].atitikme = A[p].atitikme; A[p].atitikme = e; for (int r = 0; r < m; r++) { w[r] = A[o].Fragmentas[r]; A[o].Fragmentas[r] = A[p].Fragmentas[r]; A[p].Fragmentas[r] = w[r]; } } // 添加atitikme相等时的字典序判断逻辑 else if (A[p].atitikme == A[o].atitikme && A[p].Vardas < A[o].Vardas) { // 执行相同的成员交换操作 q = A[o].Vardas; A[o].Vardas = A[p].Vardas; A[p].Vardas = q; e = A[o].atitikme; A[o].atitikme = A[p].atitikme; A[p].atitikme = e; for (int r = 0; r < m; r++) { w[r] = A[o].Fragmentas[r]; A[o].Fragmentas[r] = A[p].Fragmentas[r]; A[p].Fragmentas[r] = w[r]; } } } }
为什么这样修改能生效?
- C++的
std::string重载了<运算符,直接比较就能得到字典序结果:比如"Bailioji" < "Baltukas"会返回true,因为第二个字符a之后,i的ASCII码小于l。 - 交换整个结构体对象的方式更高效,也避免了手动交换成员时可能出现的遗漏问题(比如你原来需要单独处理
Fragmentas的循环交换,很容易出错)。
修改后,排序结果就会符合你的目标输出:
Bailioji 3 Baltukas 3 Smarkuolis 1
内容的提问来源于stack exchange,提问作者Lith
相关产品推荐
相关产品推荐

