使用位移操作排序数字

C++ Sort number using bitshifting operations

本文关键字:排序 数字 操作      更新时间:2023-10-16

我想问如何使用位移位操作按大小对整数进行排序。下面是一个例子:

Input : 12823745
Output : 87543221

基本上是将数字从高位数排序到小位数我听说可以不使用冒泡排序/快速排序算法,但通过使用一些位移操作。

有人知道这是怎么做到的吗?

快速排序和冒泡排序是通用算法。因此,对要排序的数据不做任何假设。然而,每当我们有额外的数据信息时,我们可以使用它来获得不同的东西(我不是说更好/更快或类似的东西,因为很难比像快速/冒泡排序这样简单而强大的东西更好,这真的取决于你需要的具体情况)。

如果要排序的元素数量有限(只有10个不同的数字),可以这样使用:

#include <iostream>
#include <vector>
using namespace std;
typedef std::vector<int> ivec; 
void sort(std::vector<int>& vec){
    ivec count(10,0);
    for (int i=0;i<vec.size();++i){count[vec[i]]++;}
    ivec out;
    for (int i=9;i>-1;--i){
        for (int j=0;j<count[i];j++){
            out.push_back(i);
        }
    }
    vec = out;
}
void print(const ivec& vec){
    for (int i=0;i<vec.size();++i){std::cout << vec[i];}
    std::cout << std::endl;
}
int main() {
    ivec vec {1,2,8,2,3,7,4,5};
    sort1(vec);
    print(vec);
    return 0;
}

注意复杂度为0 (N)。此外,当一组可能的元素具有有限的大小时(不仅适用于数字,也适用于浮点数),这总是有效的。不幸的是,它只适用于非常小的尺寸。

有时候仅仅计算元素是不够的。除了要排序的值,它们可能还有别的标识。然而,在这种情况下,可以很容易地修改上述内容(需要相当多的副本,但仍然是O(n))。

实际上,我不知道如何通过使用位移操作来解决您的问题。然而,我只是想指出,当你的数据有很好的属性时,总有一种方法可以不使用通用算法(有时它甚至可以更有效)。

这是一个解决方案-实现循环和按位操作的冒泡排序。

std::string unsorted = "37980965";
for(int i = 1; i < unsorted.size(); ++i)
    for(int j = 0; j < i; ++j) {
        auto &a = unsorted[i];
        auto &b = unsorted[j];
        (((a) >= (b)) || (((a) ^= (b)), ((b) ^= (a)), ((a) ^= (b))));
    }
std::cout << unsorted ;

注意,比较和交换没有进行任何分支和算术操作。只有比较和位操作。

这个怎么样?

#include <iostream>
int main()
{
    int digit[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    unsigned int input = 12823745;
    unsigned int output = 0;
    while(input > 0) {
        digit[input % 10]++;
        input /= 10;
    }
    for(int i = 9; i >= 0; --i) {
        while(digit[i] > 0) {
            output = output * 10 + i;
            digit[i]--;
        }
    }
    std::cout << output;
}