【发布时间】:2017-04-26 06:04:53
【问题描述】:
给定两个或多个数组,我如何选择对一个数组进行排序并相应地对其他数组进行排序?这类似于按一列对表格进行排序。
int main()
{
int values1[] = {5, 4, 3, 2, 1};
double values2[] = {1.0, 2.0, 3.0, 4.0, 5.0};
std::string values3[] = {"h", "e", "l", "l", "o"};
// sort by values1
// values1 = {1, 2, 3, 4, 5};
// values2 = {5.0, 4.0, 3.0, 2.0, 1.0};
// values3 = {"o", "l", "l", "e", "h"};
// sort by values3
// values1 = {4, 5, 3, 2, 1};
// values2 = {2.0, 1.0, 3.0, 4.0, 5.0};
// values3 = {"e", "h", "l", "l", "o"};
}
以下是我想出的一些策略。我希望你能给我一些正确方向的提示。谢谢!
策略一:
- 创建一个结构
struct sortstruct{int i; double d; std::string s}; - 在里面创建向量和复制值
- 编写谓词函数并使用 std::sort
- 将值复制回原始结构。
这似乎很容易,但这也涉及将所有数据复制两次,并且如果数组很大,还会创建很多小对象。此外,如果数组数量不同,这也不灵活。
策略 2:
- 复制要排序的数组。
- 使用 std::sort 对副本进行排序。
- 遍历排序后的副本,对于每个值,找到原始数组中的值,然后交换所有值数组中的索引位置。
也很容易实现,但是在未排序的数组中查找值需要二次时间(每个值的线性时间)。
策略 3:
- 实现自定义排序算法,该算法采用“键”数组并将所有交换应用到其他数组。
我不喜欢我必须自己进行排序。但如果这是最好的策略,这当然没问题。
【问题讨论】:
-
策略1如何涉及数据复制?
-
@CinCout:见步骤 2 和 4。
-
如果这三个数组是相互关联的,为什么不把它们包装成一个类,所以隐藏实现细节。
-
选项 4:创建第四个索引数组并根据用作键的任何数组重新排序该数组。最小的交换,没有副本,也没有机会破坏行之间的逻辑链接,但是为后续查找添加了一个额外的层 (
values1[indexes[i]]) 并且不适用于std::sort。 -
@Fabian 你可以创建一个结构体向量,并在向量中不断插入结构体对象,然后调用谓词 sort(),最后访问排序后的向量。副本在哪里?