C ++按字母顺序对结构向量进行排序

Posted

技术标签:

【中文标题】C ++按字母顺序对结构向量进行排序【英文标题】:C++ Sorting a struct vector alphabetically 【发布时间】:2013-11-07 12:25:17 【问题描述】:

我有一个任务,我被困住了。我需要创建一个程序来读取输入文件,将每个单词以及读取该单词的次数(因此是结构)存储到一个向量中。然后这些值需要按字母顺序打印出来。

我想出了一些我认为正确的方法:

struct WordInfo 
string text;
int count; 
 uwords, temp;

string word;
int count = 0; //ignore this. For a different part of the task
vector<WordInfo> uwords;

while (cin >> word) 
    bool flag = false;
    count += 1;
    for (int i = 0; i < uwords.size(); i++) 
        if (uwords[i].text == word) 
            flag = true;
            uwords[i].count += 1;
        
    
    if (flag == false) 
        if (count == 1)  //stores first word into vector
            uwords.push_back(WordInfo());
            uwords[0].count = 1;
            uwords[0].text = word;
         else 
            for (int i = 0; i < uwords.size(); i++) 
                if (word < uwords[i].text) 
                    uwords.push_back(WordInfo());
                    WordInfo temp = word, 1;
                    uwords.insert(uwords.begin() + i, temp);
                
            
        
    

现在我遇到的问题是,当我运行程序时,它似乎陷入了无限循环,我不明白为什么。尽管我已经进行了足够的测试以意识到它可能在最后一个 if 语句中,但我尝试修复它并不好。任何帮助表示赞赏。干杯。

编辑:我忘了说,我们必须使用向量类,我们可以使用的东西有限,排序不是一个选项:(

【问题讨论】:

看看标题&lt;algorithm&gt;,尤其是std::sort 我猜你不能使用std::sort,对吧? cplusplus.com/reference/algorithm/sort 一种方法:使用以单词为键的映射并将其出现次数计为值。 无限循环会不会是while(cin &gt;&gt; word)造成的?通常,这意味着程序正在等待用户输入。 查看此讨论以获取示例***.com/questions/1380463/… 【参考方案1】:
            if (word < uwords[i].text) 
                uwords.push_back(WordInfo());
                WordInfo temp = word, 1;
                uwords.insert(uwords.begin() + i, temp);
            

好好看看这段代码:

首先,它实际上会在您的列表中插入 2 个单词;一次是“空”的,一次是push_back,一次是insert。只要当前单词小于i 位置的单词,它就会这样做。

一旦插入,就会有 2 个新元素可以通过;一个实际上在i 的当前位置,所以在下一次迭代中,我们将再次比较同一个词 - 所以你的循环卡住了,因为索引i 每次迭代增加1,但i 的增加仅跨过刚刚插入的元素!

为了快速解决,您希望 (1) 搜索前一个单词比当前单词“小”但下一个单词更大的位置。类似的东西

if (uwords[i-1].text < word && word < uwords[i].text) 

(2) 并且您想摆脱push_back 调用。

此外,(3) 您可以在 if 条件为真后中断循环 - 您已经插入 then,无需进一步迭代。并且 (4),通过一些条件调整,count == 1 实际上可以合并到循环中。修改的代码部分(将替换您的整个 if (code == false) 块 - 警告,尚未测试):

if (!flag) 
    for (int i = 0; i <= uwords.size(); ++i) 
        if ((i == 0 || uwords[i-1].text < word) &&
            (i == uwords.size() || word < uwords[i].text)) 
            WordInfo temp = word, 1;
            uwords.insert(uwords.begin() + i, temp);
            break;
        
    

【讨论】:

这就是我乍一看的想法,但我不认为它是无限的,因为if 在每次迭代时都不会满足。然而,它是指数级的。 @paddy 它是,只要遇到一个单词小于任何 uwords 条目的单词。当插入新词,然后增加 i 时,这意味着在随后的循环中,我们实际上是在一遍又一遍地比较同一个词 啊,真的。有一个迹象表明我应该去睡觉而不是浏览 SO =) 出于绝望,我在其中添加了 push_back。不幸的是,只有插入函数仍然会产生无限循环。 您是否阅读了我的全部答案并按照我写的方式进行操作?还是您只是删除了 push_back?【参考方案2】:

你不应该在向量中推你的话,而是在地图中

std::map<std::string,int>

由于 map 在 map 上具有可比较的键迭代器,因此会自动返回排序范围,以后可以根据需要将其推入向量中。

【讨论】:

谢谢,但遗憾的是我们仅限于使用矢量类

以上是关于C ++按字母顺序对结构向量进行排序的主要内容,如果未能解决你的问题,请参考以下文章

按字母顺序对字符串数组进行排序 C++

按字母顺序对 c 字符串数组进行排序

按字典顺序对c ++中的多维向量进行排序

C ++:从文本文件中读取单行,按字母顺序对单词进行排序

如何在C中按顺序对带有数字和字母的文件名进行排序?

如何在pyspark中按字母顺序对嵌套结构的列进行排序?