对以不同方式排序的数组进行排序

时间:2015-08-31 10:10:41

标签: algorithm sorting

我有一个类型为(int,char)的元组数组。它按字典顺序排序:

[(0, 'a'), (0, 'b'), (0, 'c'), (1, 'a'), (1, 'b'), (1, 'c') ...]

我需要先按第二个元素排序,然后按第一个元素排序:

[(0, 'a'), (1, 'a'), ..., (0, 'b'), (1, 'b'), ..., (0, 'c'), (1, 'c'), ...]

哪种排序算法最适合这种情况?

3 个答案:

答案 0 :(得分:3)

简短回答:>>> import shlex, subprocess >>> filesystems = ['/dev/mapper/VolGroup00-LogVol00', '/dev/vda1', 'tmpfs'] >>> for fs in filesystems: ... command = '/sbin/dumpe2fs ' + fs ... p = subprocess.Popen(shlex.split(command),stdout=subprocess.PIPE,stderr=subprocess.STDOUT) ... output = p.communicate()[0] ... if 'superblock at' in output: ... print "{fs} has superblock".format(fs=fs) ... else: ... print "No superblock found for {fs}".format(fs=fs) ... /dev/mapper/VolGroup00-LogVol00 has superblock /dev/vda1 has superblock No superblock found for tmpfs 只需stable-sort,就可以了。

更长的回答:
使用second element排序算法,首先按stable排序,然后按first element排序。

A stable sorting保证相同的元素保持相同的顺序。

但是,如果您的输入已按second element排序,则无需再次对其进行排序。只需稳定 - 按first element对其进行排序即可。

最着名的稳定排序alg很可能是second element

答案 1 :(得分:2)

渐近地,无论是以不同方式排序还是根本不排序,它都没有区别。因此,如果您不关心常数因素,您可以使用您喜欢的任何排序算法。这项任务的重点不在于您使用的 算法,而在于如何应用它。因此,为了示例(在C ++中,其他语言将提供类似的内容)我们将使用sort()中提供的<algorithm>

要明确说明:

//the tuple
struct intChar{
    int i;
    char c;
};

//define how our struct evaluates under '<'
bool operator<(const intChar &lhs, const intChar &rhs){
    if(lhs.c == rhs.c){
        return lhs.i < rhs.i;
    }
    return lhs.c < rhs.c;
}

这里我们说如果字符相同,我们只想根据int进行排序。另外按char排序。

然后你可以使用常规排序算法:http://www.cplusplus.com/reference/algorithm/sort/,即:

#include <algorithm>

vector<intChar> toSort;

/*... fill vector ...*/
sort(toSort.begin(), toSort.end());

注意:您实际上可以定义其他比较并传递要用于sort方法的比较方法。这里我们刚刚重载了<

现在,如果你关心性能并希望挤出最后一点,那么就像其他解决方案中所建议的那样,你应该在第二个条目上使用stable-sort。但是,上述解决方案的好处是它也适用于完全无序的阵列。如果您不需要通用解决方案并希望减少开销并从您获得的有关输入的信息中获利,则可以删除该部分:

if(lhs.c == rhs.c){
    return lhs.i < rhs.i;
}

然后使用stable_sort()代替sort()。这将为您节省一个常数因子,正如我在一开始所说的那样,在任何情况下渐近运行时都不会产生任何差异,即O(n * log(n))。

答案 2 :(得分:0)

一个简单的方法是:

  1. 创建一个集合,您可以将元组元素拼凑在一起,但“反转”:{1,'a'} =&gt; “A1” (根据情况,您可能需要允许插入合适的空格和/或零,例如{1,'a'} =&gt;“a01”如果字符始终是单个但数字可能有两位数。)< / p>

  2. 排序

  3. 再次打开包装。

  4. 打包/解包步骤为O(n),排序是确定性能的步骤:O(nLogn)