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

C++从文件读取姓名并按字母序冒泡排序:sortData函数两处待完善部分求解

解决你的C++冒泡排序与姓名排序问题

首先,先帮你搞定sortData函数里的两处疑问,顺便梳理下代码里其他影响运行的小问题,让整个程序能正常跑起来~

1. 完善sortData函数的两处关键优化

你的冒泡排序框架是对的,但这两处补充能让排序更高效,也符合你标记的待完善点:

优化1:减少内层循环的无效比较

冒泡排序每完成一轮外层循环,都会把当前最大的元素“推”到数组末尾,所以后续循环不需要再碰已经排好序的末尾元素。因此内层循环的终止条件应该改成b < counter - 1 - a,而不是固定的counter-1,这样能避免重复比较有序元素。

优化2:添加有序标记提前终止循环

如果某一轮内层循环里没有发生任何交换,说明整个数组已经是有序的了,没必要继续后续循环。我们可以加一个bool swapped标志来实现这个逻辑,提升排序效率。

修改后的sortData函数:

void sortData(string text[], int counter)
{
    string temp;
    bool swapped; // 新增:标记本轮是否发生交换
    for (int a = 0; a < counter; a++) {
        swapped = false; // 每轮开始前重置标记
        // 内层循环优化:只比较未排序的部分
        for (int b = 0; b < counter - 1 - a; b++) {
            if (text[b] > text[b + 1]) {
                temp = text[b + 1];
                text[b + 1] = text[b];
                text[b] = temp;
                swapped = true; // 发生交换则标记为true
            }
        }
        // 如果本轮无交换,说明数组已完全有序,直接退出循环
        if (!swapped) {
            break;
        }
    }
}

2. 修复主函数中的核心错误

你的main函数里有两个影响程序运行的问题:

  • 你尝试打开不存在的"fName.txt",实际应该把读取到的fName和lName合并成完整姓名数组,再传入sortData排序。
  • getData用!zFile.eof()作为循环条件会导致多读一行(因为eof标志是读取失败后才会触发),改成直接用getline的返回值判断更可靠。

修改后的getData函数

int getData(ifstream& zFile, string txt[]) {
    int counter = 0;
    // 直接用getline的返回值判断是否读取成功
    while (getline(zFile, txt[counter])) {
        counter++;
    }
    return counter;
}

修改后的main函数

int main() {
    ifstream zFile1;
    ifstream zFile2;
    zFile1.open("firstname.txt");
    zFile2.open("lastname.txt");
    fileCheck(zFile1,"firstname.txt");
    fileCheck(zFile2,"lastname.txt");
    
    string fName[100], lName[100];
    int fcounter = getData(zFile1, fName);
    int lcounter = getData(zFile2, lName);
    
    // 确保名和姓的数量一致(简单容错)
    int totalNames = min(fcounter, lcounter);
    string fullNames[100];
    // 合并名和姓为完整姓名
    for (int a = 0; a < totalNames; a++) {
        fullNames[a] = fName[a] + " " + lName[a];
        cout << "Original Name: " << fullNames[a] << endl;
    }
    cout << endl << "After sorting alphabetically:" << endl;
    
    // 对完整姓名数组排序
    sortData(fullNames, totalNames);
    
    // 输出排序结果
    for (int a = 0; a < totalNames; a++) {
        cout << fullNames[a] << endl;
    }
    
    zFile1.close();
    zFile2.close();
    return 0;
}

3. 完整修正后的代码

整合所有修改后的完整代码:

#include<iostream>
#include<string>
#include<fstream>
#include<algorithm> // 用于min函数
using namespace std;

void fileCheck(ifstream& zFile, string filen);
int getData(ifstream& zFile, string txt[]);
void sortData(string text[], int counter);

int main() {
    ifstream zFile1;
    ifstream zFile2;
    zFile1.open("firstname.txt");
    zFile2.open("lastname.txt");
    fileCheck(zFile1,"firstname.txt");
    fileCheck(zFile2,"lastname.txt");
    
    string fName[100], lName[100];
    int fcounter = getData(zFile1, fName);
    int lcounter = getData(zFile2, lName);
    
    int totalNames = min(fcounter, lcounter);
    string fullNames[100];
    for (int a = 0; a < totalNames; a++) {
        fullNames[a] = fName[a] + " " + lName[a];
        cout << "Original Name: " << fullNames[a] << endl;
    }
    cout << endl << "After sorting alphabetically:" << endl;
    
    sortData(fullNames, totalNames);
    
    for (int a = 0; a < totalNames; a++) {
        cout << fullNames[a] << endl;
    }
    
    zFile1.close();
    zFile2.close();
    return 0;
}

void fileCheck(ifstream& zFile, string filen) {
    if (!zFile.is_open()) {
        cout << filen << " not found" << endl;
        exit(1);
    }
}

int getData(ifstream& zFile, string txt[]) {
    int counter = 0;
    while (getline(zFile, txt[counter])) {
        counter++;
    }
    return counter;
}

void sortData(string text[], int counter)
{
    string temp;
    bool swapped;
    for (int a = 0; a < counter; a++) {
        swapped = false;
        for (int b = 0; b < counter - 1 - a; b++) {
            if (text[b] > text[b + 1]) {
                temp = text[b + 1];
                text[b + 1] = text[b];
                text[b] = temp;
                swapped = true;
            }
        }
        if (!swapped) {
            break;
        }
    }
}

额外小建议

  • 新手阶段用using namespace std;没问题,但大型项目里尽量避免,防止命名冲突。
  • 固定大小的数组可以换成vector<string>,这样能灵活处理任意数量的姓名,不会因为超过100条而出错。
  • 合并姓名时可以加个判断,避免名或姓为空时出现多余空格。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 13:29:07