IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 算法导论4.1-3 最大子数组问题暴力与递归 -> 正文阅读

[数据结构与算法]算法导论4.1-3 最大子数组问题暴力与递归

题目

在你的计算机上实现最大子数组问题的暴力解法和递归算法。请指出多大的问题规模n0是性能交叉点 – 从此之后递归算法将击败暴力算法?然后,修改递归算法的基本情况 – 当问题规模小于n0时采用暴力算法。修改后,性能交叉点会改变吗?

题解

我用的是C语言来测试该问题,在我机器上测试的结果是n0等于20的时候起,递归算法将击败暴力算法。代码如下:

#include <cstdio>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <cassert>

#define OPTIMIZATION 0

struct Sub {
    int low;
    int high;
    int sum;
};

Sub FindMaximumSubarray1(const int array[], int low, int high) {
    Sub maxSub = { 0, 0, -INT_MIN};
    int count = high - low + 1;
    if (count == 1) {
        maxSub = { low, low, array[low] };
        return maxSub;
    }

    int sum[count][count];

    for (int i = 0; i < count; ++i) {
        for (int j = i; j < count; ++j) {
            if (i != j) {
                sum[i][j] = sum[i][j-1] + array[j+low];
            } else {
                sum[i][j] = array[j+low];
            }
            if (sum[i][j] > maxSub.sum) {
                maxSub = { i+low, j+low, sum[i][j] };
            }
        }
    }
    return  maxSub;
}

Sub FindMaxCross(const int array[], int low, int center, int high) {
    Sub sub = { center, center, array[center] };
    int pos = center;
    int mx = INT_MIN;
    int sum = 0;

    while (pos >= low) {
        sum += array[pos];
        if (sum > mx) {
            mx = sum;
            sub.low = pos;
        }
        --pos;
    }

    pos = center + 1;
    sum = mx;
    while (pos <= high) {
        sum += array[pos];
        if (sum > mx) {
            mx = sum;
            sub.high = pos;
        }
        ++pos;
    }
    sub.sum = mx;

    return sub;
}

Sub FindMaximumSubarray2(const int array[], int low, int high) {
    if (high == low) {
        Sub s0 = { low, high, array[low] };
        return s0;
    }
#if OPTIMIZATION
    // optimization
    if (low - high + 1 <= 20) {
        return FindMaximumSubarray1(array, low, high);
    }
#endif

    int center = (low + high) / 2;
    Sub s1 = FindMaximumSubarray2(array, low, center);
    Sub s2 = FindMaximumSubarray2(array, center + 1, high);
    Sub s3 = FindMaxCross(array, low, center, high);
    if (s1.sum >= s2.sum && s1.sum >= s3.sum) {
        return s1;
    } else if (s2.sum > s1.sum && s2.sum >= s3.sum) {
        return s2;
    }
    return s3;
}

int* GenerateData(int count) {
    int* data = (int*)malloc(count * sizeof(int));
    for (int i = 0; i < count; ++i) {
        data[i] = rand() % 1000 - 499;
    }
    return data;
}

void DestroyData(int* data) {
    free(data);
}

int main() {
    for (int count = 4; count < 1100; ++count) {
        int* arr = GenerateData(count);
        clock_t c1 = clock();
        Sub ans1;
        for (int i = 0; i < 200000; ++i) {
            ans1 = FindMaximumSubarray1(arr, 0, count-1);
        }
        clock_t c2 = clock();
        Sub ans2;
        for (int i = 0; i < 200000; ++i) {
            ans2 = FindMaximumSubarray2(arr, 0, count-1);
        }
        clock_t c3 = clock();
        DestroyData(arr);
        long t1 = c2 - c1;
        long t2 = c3 - c2;
        printf("count = %d t1 = %ld t2 = %ld\n", count, t1, t2);

        if (ans1.low != ans2.low || ans1.high != ans2.high || ans1.sum != ans2.sum) {
            printf("error!\n");
            exit(-1);
        }
        if (t2 < t1) {
            break;
        }
    }
    return 0;
}

接下来修改递归算法的基本情况 – 当问题规模小于n0时采用暴力算法。(将OPTIMIZATION宏改为1),改动后性能交叉点在我机器上变成了9

相关代码已同步至github: https://github.com/FengHaiTongLuo/Introduction-to-Algorithms-Prac/blob/main/prac_4.1-3.cpp


通过微信公众号”风海铜锣技术君“的菜单可以加我入面试交流的”程序员卷卷群“。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-09-08 10:59:23  更:2021-09-08 11:01:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:25:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码