打印矢量的所有排列

时间:2017-07-31 01:25:57

标签: algorithm sorting permutation

让我们设计一个时钟。此时钟的格式为(小时:小时)。让我们使用位来表示它。

例如,

10:15表示为1010:1111。

问题:给定n为1的总位数,打印所有可能的时钟时间。 (例如,在10:15示例中,n = 6,但我要求您打印所有其他可能的配置,也有6位1)。

我的尝试:我将小时存储到5个元素的向量中(最多24个)。分钟成6元素矢量(最多60)。然后我将n分为两个数字:n = n-i, ii in the [0, n]

前一个n-i表示要为小时向量打开的1位数,后一个i表示要为分钟向量打开的1位数。然后你可以使用next_permutation来获得向量的下一个排序(假设它们具有相同数量的1)。

然而,这更像是一个强力解决方案。我想知道你们是否有更好的算法?

class Solution5 {
public:
    void print_clock (int n) {
        if (n == 0) {cout<<"0"<<endl; return;}
        vector<vector<int>> res;
        vector<int> hour (5, 0);
        vector<int> min (6, 0);
        for (int i=0; i< n; i++)
            rec_print(n - i, i, res, hour, min);
        cout<<endl<<"completed"<<endl;
    }

    void rec_print (int h, int m, vector<vector<int>> & res, vector<int>  hour, vector<int>  min) {
        if (h > 5 || m > 6) return;
        int z = hour.size() -1;
        while (h-- > 0) hour[z--] = 1;
        z = min.size() -1;
        //vector<int> hour = {0,0,1,1,1};
        while (m-- > 0) min[z--] = 1;
        //while(next_permutation(hour.begin(), hour.end()) )
        //    cout<<"he";

        while (get_vector(h, hour, 24) ) {
            vector<int> tmp = min;
            while (get_vector(m, tmp, 60)) {
                cout<<"hour : ";
                for (int i=0 ; i<hour.size(); i++)
                    cout<<hour[i];
                cout<<endl<<"miniutes : ";
                for (int i=0; i<min.size(); i++)
                    cout<<min[i];
                cout<<endl<<"---------------"<<endl;
                if(next_permutation(tmp.begin(), tmp.end()) == 0 ) break;
            }
            if (next_permutation(hour.begin(), hour.end())== 0) break;

        }
        //cout<<endl<<"completed"<<endl;
    }

bool get_vector (int n, vector<int> & tmp, int maxi) {
    int sum = 0;
    for (int i = tmp.size() - 1; i >=0; i--) {
        sum += tmp[i] * pow(2,tmp.size() -1 - i);
        if (sum > maxi)
            return false;
    }
    return true;

}

1 个答案:

答案 0 :(得分:0)

使用一个计算整数二进制表示中1的数量的函数(参见例如this question),你可以迭代数字0 - 59,测量它们的数量(也就是流行计数或汉明重量) )并将它们存储在如下表格中:

0: [0]  
1: [1,2,4,8,16,32]  
2: [3,5,6,9,10,12,17,18,20,24,33,34,36,40,48]  
...  
5: [31,47,55,59]  

然后你迭代数字0 - 23,得到他们的流行计数c,并将它们与表格行n-c中的数字结合起来,例如:

0: c=0, n-c=6 -> none  
1: c=1, n-c=5 -> 1:31, 1:47, 1:55, 1:59  
...  
23: c=4, n-c=2 -> 23:03, 23:05 ... 23:40, 23:48  

这按时间顺序给你时间。我认为代码比现在的代码更短,更容易理解。

这是一个快速的代码示例(请原谅我的业余C ++)。您可以使用any popcount function,就像GNU编译器内置的那样,或者将整数转换为bitset并使用bitset::count函数。

int popcount(int i) {
    return __builtin_popcount(i); // GNU compiler built-in
}
int pop_count_times(int count) {
    std::vector<std::vector<int>> minutes(6);
    for (int m = 0; m < 60; m++) {
        minutes[popcount(m)].push_back(m);
    }
    for (int h = 0; h < 24; h++) {
        int ones = count - popcount(h);
        if (ones < 0 || ones > 5) continue;
        for (int m = 0; m < minutes[ones].size(); m++) {
            std::cout << h << ':' << minutes[ones][m] << ' ';
        }
    }
}

如果要使用前导零填充数字,则应在打印每个整数之前添加cout.fill('0')cout.width(2)。在这种情况下,count = 6的输出是:

01:31 01:47 01:55 01:59 02:31 02:47 02:55 02:59 03:15 03:23 03:27 03:29 03:30 03:39 03:43 03:45 03:46 03:51 03:53 03:54 03:57 03:58 04:31 04:47 04:55 04:59 05:15 05:23 05:27 05:29 05:30 05:39 05:43 05:45 05:46 05:51 05:53 05:54 05:57 05:58 06:15 06:23 06:27 06:29 06:30 06:39 06:43 06:45 06:46 06:51 06:53 06:54 06:57 06:58 07:07 07:11 07:13 07:14 07:19 07:21 07:22 07:25 07:26 07:28 07:35 07:37 07:38 07:41 07:42 07:44 07:49 07:50 07:52 07:56 08:31 08:47 08:55 08:59 09:15 09:23 09:27 09:29 09:30 09:39 09:43 09:45 09:46 09:51 09:53 09:54 09:57 09:58 10:15 10:23 10:27 10:29 10:30 10:39 10:43 10:45 10:46 10:51 10:53 10:54 10:57 10:58 11:07 11:11 11:13 11:14 11:19 11:21 11:22 11:25 11:26 11:28 11:35 11:37 11:38 11:41 11:42 11:44 11:49 11:50 11:52 11:56 12:15 12:23 12:27 12:29 12:30 12:39 12:43 12:45 12:46 12:51 12:53 12:54 12:57 12:58 13:07 13:11 13:13 13:14 13:19 13:21 13:22 13:25 13:26 13:28 13:35 13:37 13:38 13:41 13:42 13:44 13:49 13:50 13:52 13:56 14:07 14:11 14:13 14:14 14:19 14:21 14:22 14:25 14:26 14:28 14:35 14:37 14:38 14:41 14:42 14:44 14:49 14:50 14:52 14:56 15:03 15:05 15:06 15:09 15:10 15:12 15:17 15:18 15:20 15:24 15:33 15:34 15:36 15:40 15:48 16:31 16:47 16:55 16:59 17:15 17:23 17:27 17:29 17:30 17:39 17:43 17:45 17:46 17:51 17:53 17:54 17:57 17:58 18:15 18:23 18:27 18:29 18:30 18:39 18:43 18:45 18:46 18:51 18:53 18:54 18:57 18:58 19:07 19:11 19:13 19:14 19:19 19:21 19:22 19:25 19:26 19:28 19:35 19:37 19:38 19:41 19:42 19:44 19:49 19:50 19:52 19:56 20:15 20:23 20:27 20:29 20:30 20:39 20:43 20:45 20:46 20:51 20:53 20:54 20:57 20:58 21:07 21:11 21:13 21:14 21:19 21:21 21:22 21:25 21:26 21:28 21:35 21:37 21:38 21:41 21:42 21:44 21:49 21:50 21:52 21:56 22:07 22:11 22:13 22:14 22:19 22:21 22:22 22:25 22:26 22:28 22:35 22:37 22:38 22:41 22:42 22:44 22:49 22:50 22:52 22:56 23:03 23:05 23:06 23:09 23:10 23:12 23:17 23:18 23:20 23:24 23:33 23:34 23:36 23:40 23:48