C++代码无法正确排序带冠词的德语单词求助
德语带定冠词单词排序问题排查
我尝试用C++对带有定冠词(das/der/die)的德语单词进行排序,但代码运行后无法完美实现排序功能,尤其das类单词的排序不符合预期。以下是代码及测试文本:
原代码
#include <iostream> #include <fstream> #include <cstring> #include <stdio.h> using namespace std; struct asd { string ne; string fn; }; int main() { asd szavak[50]; ifstream be("nemet.txt"); int db=0; while (!be.eof()) { be>>szavak[db].ne; be>>szavak[db].fn; cout<<szavak[db].ne<< " "<<szavak[db].fn<<endl; db++; } be.close(); cout<< "\n\n"<< "Rendezve:\n"; for (int i=0; i<db-1; i++) { for (int j=i+1; j<db; j++) { if (szavak[j].ne<szavak[i].ne) { swap(szavak[j].ne,szavak[i].ne); swap(szavak[j].fn,szavak[i].fn); } } } int sv1=0; int sv2=0; int sv3=0; for (int i=0; i<db; i++) { if (szavak[i].ne=="das") { sv1++; } if (szavak[i].ne=="der") { sv2++; } if (szavak[i].ne=="die") { sv3++; } } for (int j=0; j<sv1-1; j++) { for (int k=j+1; k<sv1; k++) { if (szavak[k].fn<szavak[j].fn) { swap(szavak[k].fn,szavak[j].fn); } } } for (int h=sv1; h<sv1+sv2-1; h++) { for (int f=h+1; f<sv2; f++) { if (szavak[f].fn<szavak[h].fn) { swap(szavak[f].fn,szavak[h].fn); } } } for (int s=sv1+sv2; s<sv1+sv2+sv3-1; s++) { for (int l=s+1; l<sv3; l++) { if (szavak[l].fn<szavak[s].fn) { swap(szavak[l].fn,szavak[s].fn); } } } for (int i=0; i<db; i++) { cout<<szavak[i].ne<< " "<<szavak[i].fn<<endl; } return 0; }
测试文本(nemet.txt)
der Hafen die Anzeige das Einfamilienhaus das Mehrfmilienhaus der Mitbewohner die Miete die Badewanne das Badezimmer das Wohnzimmer die Aussicht das Arbeitszimmer die Decke der Plattenbau der Altbau der Neubau der Hund das Zimmer das Bild der Spiegel die Kindern die Waschmaschine
问题排查及修复
1. 文件读取逻辑错误
原代码用while (!be.eof())读取文件,会导致最后一行被重复读取一次。因为eof()只有在尝试读取超出文件末尾时才会置位,正确的读取方式应该直接判断输入操作是否成功:
while (be >> szavak[db].ne >> szavak[db].fn) { cout << szavak[db].ne << " " << szavak[db].fn << endl; db++; }
2. 分组后内部排序的范围错误
原代码在对der和die组排序时,内层循环的范围完全错误:
- 处理der组时,
f的范围应该是从h+1到sv1+sv2(der组的结束位置),而不是f<sv2 - 处理die组时,
l的范围应该是从s+1到sv1+sv2+sv3(die组的结束位置),而不是l<sv3
这直接导致das组之后的der、die组只有部分元素被排序,甚至完全没排序。
3. 更简洁的排序方案(推荐)
不需要先按定冠词分组再内部排序,直接自定义排序规则,一次完成排序:
- 先按定冠词排序(das < der < die,按字符串自然序)
- 同一定冠词的单词,按后面的名词排序
可以用std::sort结合自定义比较函数,代码更简洁且不易出错:
#include <iostream> #include <fstream> #include <algorithm> using namespace std; struct Word { string article; string noun; }; // 自定义比较函数 bool compareWords(const Word& a, const Word& b) { if (a.article != b.article) { return a.article < b.article; // 先按定冠词排序 } return a.noun < b.noun; // 同冠词按名词排序 } int main() { Word words[50]; ifstream inFile("nemet.txt"); int count = 0; // 正确读取文件 while (inFile >> words[count].article >> words[count].noun) { cout << words[count].article << " " << words[count].noun << endl; count++; } inFile.close(); cout << "\n\n排序后:\n"; // 使用自定义规则排序 sort(words, words + count, compareWords); // 输出结果 for (int i = 0; i < count; i++) { cout << words[i].article << " " << words[i].noun << endl; } return 0; }
修复后效果
排序后的结果会先按das、der、die分组,每组内的名词按字母顺序排列,比如das组的单词会按Arbeitszimmer、Badezimmer、Bild、Einfamilienhaus、Mehrfmilienhaus、Wohnzimmer、Zimmer的顺序排列,完全符合预期。
内容的提问来源于stack exchange,提问作者GamePlayers_Krissz
相关产品推荐
相关产品推荐

