力扣 根據數字二進位制下1的數目排序

leihao-lester發表於2020-11-06

力扣 根據數字二進位制下1的數目排序

題目描述

給你一個整數陣列 arr 。請你將陣列中的元素按照其二進位制表示中數字 1 的數目升序排序。

如果存在多個數字二進位制中 1 的數目相同,則必須將它們按照數值大小升序排列。

請你返回排序後的陣列。

示例 1:

輸入:arr = [0,1,2,3,4,5,6,7,8]
輸出:[0,1,2,4,8,3,5,6,7]
解釋:[0] 是唯一一個有 0 個 1 的數。
[1,2,4,8] 都有 1 個 1 。
[3,5,6] 有 2 個 1 。
[7] 有 3 個 1 。
按照 1 的個數排序得到的結果陣列為 [0,1,2,4,8,3,5,6,7]
示例 2:

輸入:arr = [1024,512,256,128,64,32,16,8,4,2,1]
輸出:[1,2,4,8,16,32,64,128,256,512,1024]
解釋:陣列中所有整數二進位制下都只有 1 個 1 ,所以你需要按照數值大小將它們排序。
示例 3:

輸入:arr = [10000,10000]
輸出:[10000,10000]
示例 4:

輸入:arr = [2,3,5,7,11,13,17,19]
輸出:[2,3,5,17,7,11,13,19]
示例 5:

輸入:arr = [10,100,1000,10000]
輸出:[10,100,10000,1000]

提示:

1 <= arr.length <= 500
0 <= arr[i] <= 10^4

要點分析

用pair結構(pair<a,b>)儲存陣列中的數字二進位制數中1的數目a和陣列中的數字b, 然後根據a和b的大小對陣列進行排序, 最後將排序後的陣列存入結果並輸出

AC程式碼:

class Solution {
public:
    
    static bool cmp1(pair<int,int>a,pair<int,int>b)//定義排序規則
    {
        return (a.first != b.first)?(a.first < b.first):(a.second<b.second);
    }

    int cal(int n)//找出某個數的二進位制數中1的個數
    {
        int tmp=n;
        int ans=0;
        while(n)
        {
            if(n%2==1) ans++;//每次取餘若為1則計數+1
            n/=2;
        }
        return ans;
    }
    vector<int> sortByBits(vector<int>& arr) {
        vector<pair<int ,int>> _arr;//儲存1的個數以及原數
        vector<int>ans;
        for(auto i:arr)
        {
            _arr.push_back({cal(i),i});//pair用大括號表示,如{a,b}
        }
        sort(_arr.begin(),_arr.end(),cmp1);//關於pair型別用sort排序的方法
        for(auto i:_arr)
        {
            ans.push_back(i.second);//將答案存入陣列
        }
        return ans;
    }
};

報錯資訊:reference to non-static member function must be called(必須呼叫對非靜態成員函式的引用)的處理

class Solution {
public:
    
    bool cmp1(pair<int,int>a,pair<int,int>b)//錯誤位置
    {
        return (a.first != b.first)?(a.first < b.first):(a.second<b.second);
    }

    int cal(int n)
    {
        int tmp=n;
        int ans=0;
        while(n)
        {
            if(n%2==1) ans++;
            n/=2;
        }
        return ans;
    }
    vector<int> sortByBits(vector<int>& arr) {
        vector<pair<int ,int>> _arr;
        vector<int>ans;
        for(auto i:arr)
        {
            _arr.push_back({cal(i),i});
        }
        sort(_arr.begin(),_arr.end(),cmp1);//報錯資訊位置
        for(auto i:_arr)
        {
            ans.push_back(i.second);
        }
        return ans;
    }
};

sort(a,b,cmp1)sort函式中第三個引數是一個普通函式指標

  1. 如果將cmp1函式放入類中, 則其為非靜態成員函式, 而非靜態成員函式指標和普通函式指標是有區別的, 非靜態成員函式擁有一個隱式引數(具體如下), 而普通函式顯然沒有這個隱式引數( implicit parameter), 兩者指向的函式的引數列表都不同, 因而兩者不同

    bool cmp(Solution* this, pair<int,int>a,pair<int,int>b) 
    
  2. 如果將cmp1函式放入類中, 且用static修飾, 則cmp1表示靜態成員函式, 靜態成員函式指標和普通函式指標沒有區別. 類的靜態成員和普通成員函式的區別在於,他們是不依賴於具體物件的,所有例項化的物件都共享同一個靜態成員,所以靜態成員也沒有this指標的概念。

    所以,指向類的靜態成員的指標就是普通的指標。

  3. 如果將cmp1函式放在類的外面宣告為全域性函式,則其指標也為普通函式指標

相關文章