组合算法的迭代实现

应用场景:通信中,报文采用TLV格式。Tag类问题频发,包括Tag少发、Tag多发以及Tag乱序,从而产生异常生效、异常失效、异常告警、异常挂死等问题。

测试人员想要触发以上异常情况,采用组合的方式针对Tag少发进行遍历。 实际场景中必须采取迭代的方式实现,故记录以下代码。

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int Combine(const int arr[], const unsigned int n, const unsigned int m)
{
#define MAX_COMBINE_M 10
#define MAX_COMBINE_N 10

    if (m > MAX_COMBINE_M || n > MAX_COMBINE_N) {
        printf("OverSize!\n");
        return 0;
    }
    unsigned int i;
    bool printFlag = false;
    unsigned int curPos = 0; /* 指示pick数组的当前下标 */
    unsigned int cnt = 0;
    unsigned int *pick = (unsigned int *)malloc(sizeof(unsigned int) * m); /* 保存从arr中选取的元素下标 */

    for (i = 0; i < m; i++) {
        pick[i] = 0;
    }

    while (pick[0] + m <= n + 1) { /* C(m,n)全部组合选取完毕判断条件 */
        if (printFlag) {
            for (i = 0; i < m; i++) {
                printf("%d ", arr[pick[i] - 1]);
            }
            printf("\n");
            printFlag = false;
            cnt++;
        }

        pick[curPos]++; /* 选取arr中下一个元素, 值为1对应arr数组下标0 */
        if (pick[curPos] == n + 1) { /* 当前位置无元素可选,回溯 */
            pick[curPos] = 0;
            curPos--;
            continue;
        }

        if (curPos < m - 1) { /* 还有剩余位置未选取,选取下一个元素 */
            curPos++;
            pick[curPos] = pick[curPos - 1]; /* 防止重复,当前位置的元素选取从上一个位置的元素的开始 */
            continue;
        }

        if (curPos == m - 1) { /* m个元素选取完毕 */
            printFlag = true;
        }
    }
    free(pick);
    return cnt;
}

int main()
{
#define N  5
#define M  3
    int a[] = {0, 1, 2, 3, 4};

    printf("cnt = %d\n", Combine(a, N, M));

    return 0;
}

/*
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
cnt = 10*/
posted @ 2021-09-29 11:26  一只学习路上的菜鸡  阅读(73)  评论(0)    收藏  举报