算法问题杂集(持续更新)

1、整数划分问题

#define _CRT_SECURE_NO_WARNINGS
#include
int p(int n, int m)
{
    if (m == 1 || n == 1)
        return 1;
    if (m > n)
        return p(n, n);
    if (m == n)
        return 1 + p(n, m - 1);
    return p(n, m - 1) + p(n - m, m);
}
int main(void)
{
    int n, s;
    scanf("%d", &n);
    s = p(n, n);
    printf("the number of division of %d is %d\n",n,s);
    getchar();
}

2、递归折半查找

#define _CRT_SECURE_NO_WARNINGS
#include
int bin_search(int key[], int low, int high, int k)
{
    int mid;
    if (low > high)
        return -1;
    else
    {
        mid = (low + high) / 2;
        if (key[mid] == k)
            return mid;
        if (k > key[mid])
            return bin_search(key, mid + 1, high, k);
        else
            return bin_search(key, low, mid - 1, k);
    }
}
int main(void)
{
    int n, i, addr;
    int A[10] = { 5,6,7,8,15,19,28,98,104,109 };
    printf("the contents of the Array A[10] are\n");
    for (i = 0; i < 10; i++)
    {
        printf("%d\n", A[i]);
    }
    printf("please input:\n");
    scanf("%d", &n);
    addr = bin_search(A, 0, 9, n);
    if (-1 != addr)
        printf("%d is at the %dth unit in array A\n", n, addr+1);
    else
        printf("error!");
        getchar();
}

3、查找指定范围素数

#define _CRT_SECURE_NO_WARNINGS
#include
//判断n是否是素数
int isPrime(int n)
{
   int i;
   for (i = 2; i < n; i++)
   {
       if (n%i == 0)
           return 0;
   }
   return 1;
}
//寻找[low,high]之间的素数
getPrime(int low, int high)
{
   int i;
   for (i = low; i <= high; i++)
       if (isPrime(i))
           printf("%d\n", i);
}
int main(void)
{
   int low, high;
   printf("please input the domain for searching prime\n");
   printf("low limitation:");
   scanf("%d", &low);
   printf("high limitation:");
   scanf("%d", &high);
   printf("The whole primes in this domain are\n");
   getPrime(low, high);
   getche();
}

4、简化版桶排序

4.1 考试成绩十分制 输入成绩 从小到大排序

#include
int main(void)
//此算法的核心思想是元素序号即代表实际对应值,
//元素储存的值为实际出现次数
{
    int a[11], i, j, t;
    for (i = 0; i <= 10; i++)
    {
        a[i] = 0;//数组每个元素初始化为0
    }

    //循环读入10个数
    for (i = 1; i <= 10; i++)
    {
        scanf("%d", &t);
        a[t]++;//进行计数
    }
    for (i = 0; i < 11; i++)//依次判断a[0]~a[10]
    {
        for (j = 1; j <= a[i]; j++)
            printf("%d\n", i);
    }
    getchar();
    return 0;
}

改进后可以输入自定义个数的成绩

#include
int main(void)
//此算法的核心思想是元素序号即代表实际对应值,
//元素储存的值为实际出现次数
{
    int a[11], i, j, t,n;
    for (i = 0; i <= 10; i++)
    {
        a[i] = 0;//数组每个元素初始化为0
    }
    scanf("%d", &n);
    //循环读入n个数
    for (i = 1; i <= n; i++)
    {
        scanf("%d", &t);
        a[t]++;//进行计数
    }
    for (i = 0; i < 11; i++)//依次判断a[0]~a[10]
    {
        for (j = 1; j <= a[i]; j++)
            printf("%d\n", i);
    }
    getchar();
    return 0;
}
  • 上述桶排序的时间复杂度为O(M+N) M为桶的个数 N为待排序的数的个数

5、指针实现冒泡排序(从小到大)

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include

void bubble(int *p, int len)
{
    for (int i = 0; i < len - 1; i++)
    {
        for (int j = 0; j < len - 1 - i; j++)
        {
            if (*(p + j) > *(p + j + 1))
            {
                int temp = *(p + j);
                *(p + j) = *(p + j + 1);
                *(p + j + 1) = temp;
            }

        }
    }
}
int main(void)
{
    int arr[] = { 3,14,1,49,20,0,18,22,98,30 };
    int *p = arr;
    int len = sizeof(arr) / sizeof(int);
    bubble(p, len);
    for (int i = 0; i < 10; i++)
    {
        printf("%d\n", *(p+i));
    }

    system("pause");
    return EXIT_SUCCESS;
}

6.矩阵连乘问题

#include 
#include 
#include 
using namespace std;
const int msize = 100;
int p[msize];
int m[msize][msize], s[msize][msize];
int n;
void matrixchain()
{
    int i, j, r, k;
    memset(m, 0, sizeof(m));
    memset(s, 0, sizeof(s));
    for (r = 2; r <= n; r++) //不同规模的子问题
    {
        for (i = 1; i <= n - r + 1; i++)
        {
            j = i + r - 1;
            m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j]; //决策为 k=i 的乘法次数
            s[i][j] = i; //子问题的最优策略是 i; 
            for (k = i + 1; k < j; k++) //对从 i 到 j 的所有决策,求最优值,记录最优策略
            {
                int t = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
                if (t < m[i][j])
                {
                    m[i][j] = t;
                    s[i][j] = k;
                }
            }
        }
    }
}
void print(int i, int j)
{
    if (i == j)
    {
        cout << "A[" << i << "]";
        return;
    }
    cout << "(";
    print(i, s[i][j]);
    print(s[i][j] + 1, j);
    cout << ")";
}
int main()
{
    cout << "请输入矩阵的个数 n:";
    cin >> n;
    int i, j;
    cout << "请依次输入每个矩阵的行数和最后一个矩阵的列数:";
    for (i = 0; i <= n; i++)
        cin >> p[i];
    matrixchain();
    print(1, n);
    cout << endl;
    cout << "最小计算量的值为:" << m[1][n] << endl;
}

7.电路布线问题

#include
#include
#include 
using namespace std;
void mnset(int C[], int n, int* size)
{
    int i, j;
    // 当i = 1时
    for (j = 0; j < C[1]; j++)
    {
        size[n + j] = 0;
    }
    for (j = C[1]; j <= n; j++)
    {
        size[n + j] = 1;
    }
    // 当i >=2时
    for (i = 2; i < n; i++)
    {
        for (j = 0; j < C[i]; j++)
        {
            size[i * n + j] = size[(i - 1) * n + j];
        }
        for (j = C[i]; j <= n; j++)
        {
            size[i * n + j] = max(size[(i - 1) * n + j], size[(i - 1) * n + C[i] - 1] + 1);
        }
    }
    size[n * n] = max(size[(n - 1) * n], size[(n - 1) * n + C[n - 1] - 1] + 1);
}
void traceBack(int C[], int* size, int n, int Net[], int& m)
{
    int i, j = n;
    m = 0;
    for (i = n; i > 1; i--)
    {
        if (size[i * (n + 1) + j] != size[(i - 1) * (n + 1) + j])
        {
            Net[m++] = i;
            j = C[i] - 1;
        }
    }
    if (j >= C[1])
    {
        Net[m++] = 1;
    }
}
int main()
{
    int n;       // 接线数目
    int num;     // 最大子集数
    int* l;      // 接线方式
    int* p;      // 子集数
    int* size;   // 二维表数组
    cout << "请输入电路的接线柱数:";
    cin >> n;
    // 动态创建热线方式数组
    l = new int[n + 1];
    // 动态创建子集数组
    p = new int[n + 1];
    // 临时动态创建二维数组
    int** temp;
    temp = new int* [n + 1];
    for (int i = 0; i < n + 1; i++)
    {
        temp[i] = new int[i + 1];
    }
    // 将二维表二维数组以一维指针赋给size
    size = &temp[0][0];
    cout << "请依次输入连接数:" << endl;
    for (int i = 1; i <= n; i++)
        cin >> l[i];
    // 调用计算最优值函数
    mnset(l, n + 1, size);
    // 调用构造最优值函数
    traceBack(l, size, n, p, num);
    // 打印子集数
    cout << "最大不想交子集数:" << num << endl << endl;
    //打印出子集
    cout << "最大不想交子集" << endl;
    for (int i = 0; i < num; i++)
        cout << p[i] << " --> " << l[p[i]] << endl;
    system("pause");
    return 0;
}

8.最长公共子序列问题

#include  
#include 
#include 

using namespace std;
const int N = 1002;
int c[N][N];
int b[N][N];
char s1[N], s2[N];
int len1, len2;
void LCSL()
{
    int i, j;
    for (i = 1; i <= len1; i++)//控制 s1 序列
        for (j = 1; j <= len2; j++)//控制 s2 序列
        {
            if (s1[i - 1] == s2[j - 1])
            {//如果当前字符相同,则公共子序列的长度为该字符前的最长公共序列+1 
                c[i][j] = c[i - 1][j - 1] + 1;
                b[i][j] = 1;
            }
            else
            {
                if (c[i][j - 1] >= c[i - 1][j])
                {
                    c[i][j] = c[i][j - 1];
                    b[i][j] = 2;
                }
                else
                {
                    c[i][j] = c[i - 1][j];
                    b[i][j] = 3;
                }
            }
        }
}
void print(int i, int j)//根据记录下来的信息构造最长公共子序列(从 b[i][j]开始递推)
{
    if (i == 0 || j == 0) return;
    if (b[i][j] == 1)
    {
        print(i - 1, j - 1);
        cout << s1[i - 1];
    }
    else if (b[i][j] == 2)
        print(i, j - 1);
    else
        print(i - 1, j);
}
int main()
{
    int i, j;
    cout << "输入字符串 s1:" << endl;
    cin >> s1;
    cout << "输入字符串 s2:" << endl;
    cin >> s2;
    len1 = strlen(s1);//计算两个字符串的长度
    len2 = strlen(s2);
    for (i = 0; i <= len1; i++)
    {
        c[i][0] = 0;//初始化第一列为 0 
    }
    for (j = 0; j <= len2; j++)
    {
        c[0][j] = 0;//初始化第一行为 0 
    }
    LCSL(); //求解最长公共子序列
    cout << "s1 和 s2 的最长公共子序列长度是:" << c[len1][len2] << endl;
    cout << "s1 和 s2 的最长公共子序列是:";
    print(len1, len2); //递归构造最长公共子序列最优解
    return 0;
}

9.快速排序

def quick_sort(array):
    if len(array) < 2:
        return array
    else:
        pivot = array[0]

        less = [i for i in array[1:] if i <= pivot]

        greater = [i for i in array[1:] if i >= pivot]

        return quick_sort(less) + [pivot] + quick_sort(greater)

你可能感兴趣的:(算法问题杂集(持续更新))