【问题标题】:Sorting and keeping track of indexes in struct排序和跟踪结构中的索引
【发布时间】:2021-03-23 13:22:13
【问题描述】:

假设我们有n 的房屋数量。这是一所房子:

struct Casa {
    int id;
    int membri;
};

我正在从 txt 文件中读取结构的大小和每个结构的 membri。第一个值是结构的大小 (n)。

5

2
8
6
10
4

从文件中读取时,我会增加 ID:

void citire(Casa house[], int n, std::ifstream & file) {

    for (int i = 0; i < n; i++)
    {
        file >> house[i].membri;
        house[i].id = i + 1;
    }
}

如何根据membri升序输出房屋ID?

例如:

id: 1 - membri: 2
id: 2 - membri: 8
id: 3 - membri: 6
id: 4 - membri: 10
id: 5 - membri: 4

应该输出:

id: 1 - membri: 2
id: 5 - membri: 4
id: 3 - membri: 6
id: 2 - membri: 8
id: 4 - membri: 10

这是我尝试过的,但它不起作用,我不明白为什么:

void sortareSelectie(int v[], int n) {
    int i, j, min, temp;
    for (i = 0; i < n - 1; i++) {
        min = i;
        for (j = i + 1; j < n; j++) {
            if (v[j] < v[min]) min = j;
        }
        // swap
        temp = v[min];
        v[min] = v[i];
        v[i] = temp;
    }
}

void sort(Casa house[], int n) {
    int v[10], key[10];
    for (int i = 0; i < n; i++) {
        v[i] = house[i].membri;
    }

    sortareSelectie(v, n);

    for (int i = 0; i < n; i++) {
        std::cout << "Membri: " << v[i] << " - ID: " << house[i].id << std::endl;
    }
    
}

我见过带有向量、结构和数组的示例。
How to obtain the index permutation after the sorting
keeping track of the original indices of an array after sorting in C
Sorting array and saving the old index in C++
Get the indices of an array after sorting?
https://www.geeksforgeeks.org/keep-track-of-previous-indexes-after-sorting-a-vector-in-c-stl/

我仍然不明白如何在我的示例中应用它。
问题是我不想也不能使用向量、lambda 或任何预定义的 sort 函数编程语言可以有。
是的,这是给学校的。

很抱歉,我不知道这是如何工作的。

【问题讨论】:

  • 您将使用std::sort 并编写简短的comp() 函数来告诉std::sort 对结构的membri 字段进行排序。
  • 如我所说,我不能使用std::sort
  • 那看看它是怎么排序的,复制一下。不要重新发明轮子。
  • 抱歉,这是否包括 C qsort()?这是另一个快速稳健的选择。否则,选择排序或插入排序 /t 与气泡短排序一样糟糕。如果您要排序的结构少于 10,000 个——它们真的没关系,冒泡排序等就可以了。
  • 我不知道怎么做。这就是这个问题的重点!即使在查找后我也不知道如何实现它。

标签: c++ arrays sorting struct


【解决方案1】:

您可以选择多种类型中的一种。像冒泡排序这样的简单排序效率最差,然后是各种选择排序,直到到达更长的分区排序,效率最终得到提高。

这里有一个简单的选择排序示例,可以对示例结构进行升序排序。选择如此简单:

void insertion_sort (struct Casa *arr, size_t size)
{
    int i, j;

    for (i = 0; i < (int)size; i++) {
        for (j = i - 1; j >= 0; j--) {
            if (arr[j].membri > arr[j + 1].membri) {
                struct Casa tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            } else
                break;
        }
    }
}

对于基于membri降序排序,您只需将&gt; 更改为&lt; in:

            if (arr[j].membri < arr[j + 1].membri) {

使用您的示例数据将其放在一个简短的示例中,您将拥有:

#include <iostream>
#include <iomanip>

struct Casa {
    int id;
    int membri;
};

void insertion_sort (struct Casa *arr, size_t size)
{
    int i, j;

    for (i = 0; i < (int)size; i++) {
        for (j = i - 1; j >= 0; j--) {
            if (arr[j].membri > arr[j + 1].membri) {
                struct Casa tmp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = tmp;
            } else
                break;
        }
    }
}

int main (void) {
    
    struct Casa houses[] = { {1,2}, {5,4}, {3,6}, {2,8}, {4,10} };
    size_t n = sizeof houses / sizeof *houses;
    insertion_sort (houses, n);
    std::cout << n << " houses sorted by membri\n\n";
    for (size_t i = 0; i < n; i++)
        std::cout << "id: " << houses[i].id << 
                    "  mdmbri: " << std::setw(2) << houses[i].membri << '\n';
}

使用/输出示例

$ ./bin/struct_casa
5 houses sorted by membri

id: 1  mdmbri:  2
id: 5  mdmbri:  4
id: 3  mdmbri:  6
id: 2  mdmbri:  8
id: 4  mdmbri: 10

或对降序进行更改:

$ ./bin/struct_casa
5 houses sorted by membri

id: 4  mdmbri: 10
id: 2  mdmbri:  8
id: 3  mdmbri:  6
id: 5  mdmbri:  4
id: 1  mdmbri:  2

检查一下,如果您有任何其他问题,请告诉我。

【讨论】:

    【解决方案2】:

    我建议您使用哈希表。以下是您提出的问题的代码。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        map<int,int> mymap;
        int n;
        cin >>n;
        for(int i=0;i<n;i++){
            int temp;
            cin >> temp;
            mymap.insert({temp,i+1});
        }
        auto itr= mymap.begin();
        while(itr!=mymap.end()){
            cout << "id: "<<(*itr).second<< " - membri: "<<(*itr).first<<endl;
            itr++;
        }
    }
    

    【讨论】:

    • 很遗憾,我不能使用地图、向量等,只能使用简单的数组和手动编写的函数。
    • 也许你可以尝试为合并排序编写整个代码并使用它。
    【解决方案3】:

    将您的选择排序更改为通用排序:

    template <typename T, typename Less>
    void sortareSelectie(T v[], std::size_t n, Less less) {
        for (std::size_t i = 0; i + 1 < n; i++) {
            std::size_t min = i;
            for (std::size_t j = i + 1; j < n; j++) {
                if (less(v[j], v[min])) min = j;
            }
            std::swap(v[min], v[i]);
        }
    }
    

    然后

    bool LessByMembri(const Casa& lhs, const Casa& rhs) { return lhs.membri < rhs.membri; } 
    
    void sortAndPrint(Casa houses[], int n) {
        sortareSelectie(houses, n, LessByMembri);
    
        for (int i = 0; i < n; i++) {
            std::cout << "Membri: " << houses[i].membri << " - ID: " << houses[i].id << std::endl;
        }
        
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-07
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 2014-08-26
      相关资源
      最近更新 更多