复杂度

2020北航OO表达式求导作业总结

我的未来我决定 提交于 2020-03-18 22:40:21
三次作业的思路与bug测试 第一次作业 ​ 第一次作业内容为简多项式单导函数的求解,项包含常数项(带符号整数)与变量项(系数与幂函数的乘积),表达式由加法和减法运算符连接若干项组成。且输入中确保格式的正确性。 1.1 实现方案 根据需求,我们很容易联想到用 HashMap 表示每一项中幂函数指数与系数的对应关系。而且因为这是第一次作业,我没有考虑可扩展性,直接在多项式类 Ploy 中使用了类型为 HashMap<BigInteger,BigInteger> 的 ploy 作为存储的数据结构。 数据层次:根据指导书表述,容易联想到建立指数与系数的 HashMap 来表示多项式,我建立了多项式类 Ploy ,项类 Term ,主类 MainClass 。 输入解析:我采用了按项拆分字符串的方法,提取过程中应用了正则表达式。 三次作业包你掌握正则表达式(●'◡'●) 求导功能:我在Ploy类中实现了 diffPloy() 方法,该方法会返回一个求导后的导函数,即一个新的Ploy对象。 输出:我在Ploy类中实现了 printFirst() 方法。 优化方面:实现了合并同类项、正项先输出、零项不输出、系数为1或-1时省略。 ①在 MainClass 里实例化 Ploy 对象 ploy,借用正则表达式将输入的字符串拆为单项的字符串,将拆好的字符串扔进 Term

关于HashMap的一些知识点整理

只愿长相守 提交于 2020-03-17 01:11:17
本文来自网上各个知识点的整理 HashMap采用Entry数组(Java8叫Node)来存储key-value对,每一个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体,以此来解决Hash冲突的问题。 但链表的查询复杂度大,一但链表过长,查询的效率下降。 在Jdk1.8中HashMap的实现方式做了一些改变,数据结构的存储由数组+链表的方式,变化为数组+链表+红黑树的存储方式,当链表长度超过阈值(8)时,将链表转换为红黑树。在性能上进一步得到提升。但每次插入新的数据,都得维护红黑树的结构,复杂度为O(logn)。 链表:插入复杂度O(1),查找复杂度O(n) 红黑树:插入复杂度O(logn),查找复杂度O(logn) 但既然红黑树这么棒,那为什么HashMap为什么不直接就用红黑树呢? 因为树节点所占空间是普通节点的两倍,所以只有当节点足够多的时候,才会使用树节点。也就是说,节点少的时候,尽管时间复杂度上,红黑树比链表好一点,但是红黑树所占空间比较大,综合考虑,认为只能在节点太多的时候,红黑树占空间大这一劣势不太明显的时候,才会舍弃链表,使用红黑树。 那为什么链表长度为8时才会选择使用红黑树呢? 为了配合使用分布良好的HashCode,树节点很少使用。并且在理想状态下,受随机分布的HashCode影响

[洛谷P4721]【模板】分治 FFT

我与影子孤独终老i 提交于 2020-03-17 01:02:21
题目大意: 给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$ f_i=\sum_{j=1}^if_{i-j}g_j\\ f_0=1 $$ 题解: 直接求复杂度是$O(n^2)$,明显不可以通过此题 分治$FFT$,可以用$CDQ$分治,先求出$f_{[l,mid)}$,可以发现这部分对区间的$f_{[mid,r)}$的贡献是$f_{[l,mid)}*g_{[0,r-l)}$,卷出来加到对应位置就行了,复杂度$O(n\log_2^2n)​$ 卡点: 无 C++ Code: #include <algorithm> #include <cstdio> #include <cctype> namespace std { struct istream { #define M (1 << 21 | 3) char buf[M], *ch = buf - 1; inline istream() { #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); #endif fread(buf, 1, M, stdin); } inline istream& operator >> (int &x) { while (isspace(*++ch)); for (x = *ch & 15; isdigit(*+

noip模拟测试11

你。 提交于 2020-03-12 17:09:46
T1:string   第一眼秒出思路,这不就是排序那道题的加强版吗?   然而歪?解复杂度虽然是对的,但常数过大,竟被卡到70   歪?解:(实际上std写的就是这个,但据说std被卡掉了 OAO)     因为字符集很小,所以我们可以把区间排序改为区间查询和覆盖     即:先查询区间内所有字符的个数,再从左端点开始按照大小关系依次将长度为字符个数的区间修改为该字符。     期望复杂度O ( 26*mlogn ),实际复杂度O ( 26*mlogn*( 巨大的常数 ) )     所以需要一(feng)定(kuang)的卡常   正?解:     因为字符集很小,所以重复字符很多,又因为我们的操作是排序,所以操作后字符显然会变为一块一块的     所以可以在线段树上每个节点记录段内字符是否全部相等     若相等直接return,否则向下递归     这样直接递归看起来似乎单次复杂度不太对     但是仔细一想会发现,对于较短的区间操作来说,整块字符较少,递归次数较多,但区间短,所以复杂度正确               对于较长的区间操作来说,整块字符较多,递归次数较少,虽区间长,但复杂度仍正确     所以均摊复杂度正确,可过(还跑的挺快???)          so,歪?解 code 1 #include<cstdio> 2 #include<iostream> 3

数组循环移动 空间复杂度O(1)

眉间皱痕 提交于 2020-03-11 17:02:35
---恢复内容开始--- 题目大意: 输入元素个数,输入数组,输入右移步数,输出结果; 基本思路: 可以把数组(从下标为0开始存储)看成两部分,分别是【0,n-step-1】,【n-step,n-1】,然后两部分分别倒置,然后将整个数组倒置,就得到了正确结果; 至于为什么是这样,你可以找个例子看看,然后理论证明上吗,哇,脑补一下就知道了。 代码如下: #include<stdio.h> #include<stdlib.h> #include<string.h> int arr[100]; void Reverse(int l,int r){ int mid=(l+r)/2; for(int i=l;i<=mid;i++){ int tmp=arr[i]; arr[i]=arr[r+l-i]; arr[r+l-i]=tmp; } return; } int main(){ int n; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&arr[i]); } int step; scanf("%d",&step); Reverse(0,n-step-1); Reverse(n-step,n-1); Reverse(0,n-1); for(int i=0;i<n;i++){ printf("%d ",arr[i]); } return 0

递归

喜你入骨 提交于 2020-03-11 03:20:25
什么问题可以用递归? 当前问题可以进行拆分,拆分为子问题。子问题的本质和父问题是一样的,解决了子问题,父问题也就迎刃而解。同时子问题可以继续向下分解。 例如:数组排序问题 分解为数组左边部分排序和又边部分排序 找数组最大数问题 找数组左边最大数和数组右边最大数,然后返回最大的那一个 求 n 的阶乘 等价于求(n-1)的阶乘再乘以n n-1的阶乘等于n-2的阶乘再乘以n-1 递归行为 递归行为在程序执行时,相当于系统帮程序员进行压栈出栈的行为,在压栈的时候不仅会将要执行的函数、变量等压入栈中,同时还会记录当前执行到程序的哪一行。 递归的时间复杂度估算 master公式的使用 T(N) = a*T(N/b) + O(N^d) log(b,a) > d -> 复杂度为O(N^log(b,a)) log(b,a) = d -> 复杂度为O(N^d * logN) log(b,a) < d -> 复杂度为O(N^d) 例如:找数组最大值 int Maxnum ( vector < int > & obj , int left , int right ) { if ( left == right ) return obj [ left ] ; int mid = ( left + right ) / 2 ; int left_max = Maxnum ( obj , left , mid )

【LeetCode题解】144_二叉树的前序遍历

妖精的绣舞 提交于 2020-03-05 23:09:48
目录 【LeetCode题解】144_二叉树的前序遍历 描述 方法一:递归 Java 代码 Python 代码 方法二:非递归(使用栈) Java 代码 Python 代码 【LeetCode题解】144_二叉树的前序遍历 描述 给定一个二叉树,返回它的 前序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,2,3] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 方法一:递归 Java 代码 /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public List<Integer> preorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); preorderTraversal(root, res); return res; } private void preorderTraversal(TreeNode root, List<Integer> res) { if

01-复杂度2 Maximum Subsequence Sum (25分)

橙三吉。 提交于 2020-03-05 20:07:00
Sample Input: 10 -10 1 2 3 4 -5 -23 3 7 -21 Sample Output: 10 1 4 题目有一个测试点是“最大和前面有一段是0”,所以呢基本上就是在老师的代码的基础上做一点点的修改。每次开始新的子序列记录一个位置,当更新最大子序列和的时候更新最大子序列和的start 和 end。 #include <stdio.h> int main(int argc, char const *argv[]) { int i, k; scanf("%d", &k); int numbers[k]; for (i = 0; i < k; i++) { scanf("%d", &numbers[i]); } int best_sum, current_sum; int best_start, best_end, current_start; best_sum = -1; current_sum = 0; for (i = 0; i < k; i++) { current_sum += numbers[i]; if (current_sum > best_sum) { best_sum = current_sum; best_start = current_start; best_end = i; } else if (current_sum < 0) {

OO第二单元总结

ぃ、小莉子 提交于 2020-03-02 08:30:45
概述: 第二单元的主要内容是通过编写多线程程序来模拟电梯的运行。第一次作业是单傻瓜电梯,不考虑策略,基本是初步了解多线程程序的编写;第二次作业是单ALS电梯,在上一次的基础上要实现捎带,尽可能在最短时间内完成所有请求;第三次作业是多电梯,每个电梯可停的层和容量都不同,需要考虑乘客换乘的情况。在这三次作业中,我们的程序需要使用不同的策略将线程安全贯彻始终,以免出现与期望不符的BUG,我认为这也是多线程程序编程中的重点所在。 一、程序分析 1、第一次作业 (1) 设计策略    第一次作业要实现一个傻瓜电梯,思路很简单,可以看作一个传统的生产者-消费者的问题。考虑一个输入线程作为生产者,电梯线程作为一个消费者,维护一个线程安全的共享队列作为托盘(这里我使用了JDK自带的ConcurrentLinkedQueue)。输入线程每次向队列输入请求,无请求时结束;电梯线程的调度策略就是每次从队列中取出一个请求来完成,当队列为空且输入线程结束时结束。 (2) 度量分析 代码规模 类图 复杂度分析   本次作业需求比较简单,所以方法的复杂度都不高,最高就是5。 协作图 SOLID原则    本次作业输入线程只负责输入,电梯线程负责运行和输出,调度器作为共享对象被前二者共享,符合单一责任原则(SRP)。其他原则个人认为由于本次作业要求都无需考虑。 (3) BUG分析   

程序复杂度之圈复杂度

给你一囗甜甜゛ 提交于 2020-03-01 09:31:23
圈复杂度(Cyclomatic complexity)也称为条件复杂度或循环复杂度,是一种软件度量,是由Thomas J. McCabe, Sr. 在 1976 年提出,用来表示程序的复杂度,其符号为 VG 或是 M。圈复杂度是对源代码中线性独立路径数的定量测量。 圈复杂度使用的程序的控制流图来计算:在图中的节点对应于程序中一组不可分割的命令[代码行],有向边连接两个可连续执行的节点;[可连续执行的两个节点:第二个节点的命令组可能在第一个节点执行后立刻开始执行]。圈复杂度可以应用到独立的功能,模块,方法或类。 基础路径测试:通过测试用例测试程序中的每个线性无关的独立路径;在这种测试策略下,测试用例的数目将等于该程序的圈复杂度; #####圈复杂度定义 圈复杂度度量的是程序中线性独立路径的数量;例如:如果程序中不包含控制、判断、条件语句(例如 if,swith 等),那么复杂度就是 1 ;因为整个程序只有一条执行路径;如果程序包含一条IF语句,那么就会有两条路径来执行完整个程序(IF为 TRUE,IF 为 FALSE),所以这时候的复杂度就是 2;两个嵌套的 IF 语句,或者包含两个判断条件的一个 IF 语句,复杂度就是 4; 在数学上,一个结构化程序的圈复杂度通过该程序的控制流图来定义;控制流图包含程序的基本块(图的节点),和两个基本块之间可执行性(图的边)。 原理: 上图