算法

蓝桥杯——算法训练——前缀表达式

时光怂恿深爱的人放手 提交于 2020-02-13 03:34:41
蓝桥杯——算法训练——前缀表达式 —————————————————————————————— 资源限制 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,以字符串方式输入一个前缀表达式,然后计算它的值。输入格式为:“运算符 对象1 对象2”,其中,运算符为“+”(加法)、“-”(减法)、“*”(乘法)或“/”(除法),运算对象为不超过10的整数,它们之间用一个空格隔开。要求:对于加、减、乘、除这四种运算,分别设计相应的函数来实现。 输入格式 输入只有一行,即一个前缀表达式字符串。 输出格式 输出相应的计算结果(如果是除法,直接采用c语言的“/”运算符,结果为整数)。 样例输入 + 5 2 样例输出 7 —————————————————————————————— 思路分析:这道题其实没什么思路,注意是不大于10的整数,因此做好字符串的转换,以及学会如何输入带空格字符串(这里使用的是 cin.get() )即可,直接看代码: # include <iostream> # include <string> # include <string.h> using namespace std ; int pl ( int a , int b ) { return a + b ; } int mi ( int a , int b ) { return a - b ; }

【DS】排序算法之希尔排序(Shell Sort)

让人想犯罪 __ 提交于 2020-02-13 02:00:14
一、算法思想 希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序是基于插入排序的以下两点性质而提出改进方法的: 1)插入排序在对几乎已经排好序的数据操作时, 效率高, 即可以达到线性排序的效率; 2)插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位; 我们将数组中两个元素之间的距离称为Gap,相邻元素之间的Gap自然是1,很明显的,插入排序的算法在调节元素的时候,Gap是1,这就造成了上面讲的低效的原因2)。因此希尔排序的思想如下: 1)假设序列的元素个数是n,选取一个初始Gap的d(d<n); 2)将序列中元素之间距离(即Gap)为d的元素分为一组,在每组之间直接进行插入排序; 3)全部完成以后,缩小Gap至d1(d1<d),然后继续2)直到Gap为1; 常见的Gap序列如下: 1)希尔原本的Gap:N/2、N/4、...1(反复除以2) 2)Hibbard的Gap:1、3、7、...、2k-1(k表示第几个gap) 3)Knuth的Gap: 1、4、13、...、(3k - 1) / 2(k表示第几个gap) 4)Sedgewick的Gap: 1、5、19、41、109、... 二、算法示意图 如图所示,展示了分组和排序的过程。第一行是分组的过程,总共有8个元素,Gap为8/2=4,标记为相同颜色的元素为一组

算法分析

笑着哭i 提交于 2020-02-12 23:26:40
理解算法分析之前,先看一看科学家的平时如何分析一个问题。 科学方法 1.细致的观察真实世界的特点,通常还需要精确的测量。 2.根据观察结果提出假设模型。 3.根据模型预测未来的事件。 4.继续观察并核实预测的准确性。 5.一直反复直到确认预测和观察一致。 一 观察 陈程序的观察基本就是观察时间的运行,现有一个简单类用于查看时间。 public class Stopwatch { private final long start; public Stopwatch() { start = System.currentTimeMillis(); } public double elapsedTime() { long now = System.currentTimeMillis(); return (now - start) / 1000.0; } public void howManyTime(){ System.out.println("时间过了:"+elapsedTime()); } } 二 数学模型 数学模型的分析大概如下: 1.确定输入模型,定义问题的规模。 2.识别内循环。 3.根据内循环中的操作确定成本模型。 4.对于给定的输入,判断这些操作的执行频率,需要使用数学分析。 三 时间复杂度分析 1、时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的

算法手记(4)算法分析

流过昼夜 提交于 2020-02-12 23:19:24
“我的程序会运行多长时间?为什么我的程序耗尽了所有内存?” 在我们使用计算机解决困难问题或是处理大量数据时,不可避免地会产生这些疑问。为这些基础问题给出答案有时其实非常简单,这个过程是科学方法,这就是我们今天讨论的内容。 科学方法概述: 科学家用于观察世界的方法对于研究计算机程序一样有效: 1.观察真实世界特点 2.提出假设模型 3.根据假设模型预测未来事件 4.继续观察并核实预测的准确性 5.如此反复直至确认预测与观察一致 正如爱因斯坦所说:“再多的实验也不一定能够证明我是对的,但只需要一个实验就能证明我是错的”。科学方法的一条关键原则是我们所设计的实验必须是可重现的,我们提出的假设也必须是可证伪的。我们永远无法知道某个假设是绝对正确的,我们只能验证他和我们观察的一致性。 举例: 这里我们编写了一个ThreeSum的程序,用于统计所有和为0的三整数元组的数量。示例代码使用最简单的 暴力算法 ,我们通过对其分析,可以进一步的优化,并了解算法分析的过程。 public class ThreeSum { public static int count(int[] a) { int N = a.Length; int cnt = 0; for (int i = 0; i < N; i++) for (int j = i + 1; j < N; j++) for (int k = j +

RT-thread内核之小内存管理算法

一世执手 提交于 2020-02-12 22:12:27
一、动态内存管理 动态内存管理是一个真实的堆(Heap)内存管理模块,可以在当前资源满足的情况下,根据用户的需求分配任意大小的内存块。而当用户不需要再使用这些内存块时,又可以释放回堆中供其他应用分配使用。RT-Thread系统为了满足不同的需求,提供了两套不同的动态内存管理算法,分别是 小内存管理算法 和 SLAB内存管理算法 。小堆内存管理模块主要针对系统资源比较少,一般用于小于2M内存空间的系统;而SLAB内存管理模块则主要是在系统资源比较丰富时,提供了一种近似多内存池管理算法的快速算法。 两种内存管理模块在系统运行时只能选择其中之一或者完全不使用动态堆内存管理器。这两种管理模块提供的API接口完全相同。 因为动态内存管理器要满足多线程情况下的安全分配,会考虑多线程间的互斥问题,所以请不要在中断服务例程中分配或释放动态内存块。因为它可能会引起当前上下文被挂起等待。 二、小内存管理算法 本文主要介绍小内存管理算法,至于SLAB内存管理算法则在后续文章中介绍。小内存管理算法是一个简单的内存分配算法。初始时,它是一块大的内存。当需要分配内存块时,将从这个大的内存块上分割出相匹配的内存块,然后把分割出来的空闲内存块还回给堆管理系统中。每个内存块都包含一个管理用的数据头,通过这个头把使用块与空闲块用双向链表的方式链接起来,如 内存块链表图所示:

操作系统-面试

跟風遠走 提交于 2020-02-12 18:19:13
1.操作系统的四个特性:并发、共享,虚拟、异步。 2.操作系统的主要功能:处理机管理、存储器管理、设备管理、文件管理、提供用户接口。 3.线程是进程的子任务,是CPU调度和分派的基本单位,用于保证程序的实时性,实现进程内部的并发; 在没有实现线程的操作系统中,进程既是资源分配的基本单位,又是调度的基本单位,它是系统中并发执行的单元。而在实现了线程的操作系统中,进程是资源分配的基本单位,但是线程是调度的基本单位,是系统中并发执行的单元。 引入线程主要有以下4个方面的优点: 1)易于调度。 2)提高并发性。通过线程可以方便有效地实现并发。 3)开销小。创建线程比创建进程要快,所需要的开销也更小。 4)有利于发挥多处理器的功能。通过创建多线程,每个线程都在一个处理器上运行,从而实现应用程序的并行,使每个处理器都得到充分的运行。 4.进程间的通信的几种方式? 管道及命名管道、信号、消息队列、共享内存、信号量、套接字。 5.线程同步的方式:临界区、互斥量、信号量、事件(信号)。 6.进程有哪几种状态? 7.什么是死锁?死锁产生的条件? 1). 死锁的概念 所谓死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去,此时称系统处于死锁状态或系统产生了死锁。通俗的讲,就是两个或多个进程无限期的阻塞、相互等待的一种状态。 2).

Java垃圾回收机制

。_饼干妹妹 提交于 2020-02-12 15:33:32
Java垃圾回收机制 一、如何确定一个对象是否可以被回收? 1、引用计数算法:判断对象的引用数量 引用计数算法通过判断对象的引用数量决定对象是否可以被回收;引用计数算法的堆内每个对象实例都有一个引用计数,当一个对象被创建时,且该对象实例分配给一个引用变量,该对象实例的引用计数设置为1,当任何其他变量被赋值为这个对象的引用时,对象实例的引用计数就加1;当一个对象实例的某个引用超过了生命周期或被设置为一个新值时,该对象实例的计数就减1;当一个对象实例被垃圾收集时,它引用的任何实例对象的计数器均减1,任何计数器为0的对象实例可以被当作垃圾收集; 引用计数收集器可以很快执行,并且交织在程序运行中,对程序需要不被长时间打断的实时环境比较有利; 缺点:很难解决对象之间相互循环引用的问题。 2、可达性分析算法:判断对象的引用链是否可达来决定对象是否可以被回收 可达性分析算法通过一系列“GC Roots”的对象最为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象的GC Roots没有任何引用链相连时,则此对象时不可用的。 GC Roots对象包括: (1)虚拟机栈(栈帧中的局部变量表)中引用的对象; (2)方法区中的类静态属性引用的对象; (3)方法区中常量引用的对象; (4)本地方法栈中Native方法引用的对象; 二、垃圾收集算法 1、标记–清除算法

算分-NP COMPLETENESS

雨燕双飞 提交于 2020-02-12 14:46:03
Easy and Hard Problems:   NP完全理论是为了在可处理的问题和不可处理的问题之间画一条线,目前最重要的问题是是否这两者是本质不同的,而这个问题目前还没有被解决。典型的结果是一些陈述,比如“如果问题B有一个多项式时间的算法,那么C也会有一个多项式时间的算法”,或者逆否表述为“如果C没有多项式时间的算法,那么B也没有”。第二个表述是说,对于一些问题C以及一个新的问题B,我们先去找是否有这种关系,如果有的话我们可能不想去做问题B,先来看看C。为了描述这些东西,需要不少形式主义的记号,我们在这里尽可能地少涉及。   先来看什么是问题?一个抽象的做决定问题是从问题实例集合I到{0,1}的映射,其中0代表错误,1代表正确。为了更严谨,我们把问题实例写成I到{0,1}*,也就是0/1组成的字符串,一个具体的做决定问题是从比特串到{0,1}的映射,我们把那些没有意义的问题映射到0。举个例子来说,对于最短路径问题,一个问题事实例是一个图以及两个顶点,做决定的问题是是否存在这两个顶点之间长度至多为k的一条路径。要注意的是,做决定问题不会比相应的最优算法要复杂,也就是说其复杂度小于等于最优算法,因此为了去证明相应的最优化算法是hard的,如果我们可以证明做决定问题是hard的,那么就可以达成我们的目标。(相当于充分性)   接着来看什么是多项式时间

算法训练 大小写转换

落爺英雄遲暮 提交于 2020-02-12 05:11:48
http://lx.lanqiao.org/problem.page?gpid=T216 算法训练 大小写转换 时间限制:1.0s 内存限制:512.0MB 问题描述   编写一个程序,输入一个字符串(长度不超过20),然后把这个字符串内的每一个字符进行大小写变换,即将大写字母变成小写,小写字母变成大写,然后把这个新的字符串输出。   输入格式:输入一个字符串,而且这个字符串当中只包含英文字母,不包含其他类型的字符,也没有空格。   输出格式:输出经过转换后的字符串。   输入输出样例 样例输入 AeDb 样例输出 aEdB 分析: 字符操作。 AC代码: 1 #include <stdio.h> 2 #include <string.h> 3 int main() 4 { 5 char str[27]; 6 gets(str); 7 int i , len = strlen(str); 8 for(i = 0;i < len ;i ++) 9 if(str[i] >= 'A' && str[i] <= 'Z') 10 printf("%c" , str[i] + 32); 11 else 12 printf("%c" , str[i] - 32); 13 puts(""); 14 return 0; 15 } View Code 来源: https://www.cnblogs

算法训练 大小写转换

老子叫甜甜 提交于 2020-02-12 04:56:00
算法训练 大小写转换 时间限制:1.0s 内存限制:512.0MB 问题描述   编写一个程序,输入一个字符串(长度不超过20),然后把这个字符串内的每一个字符进行大小写变换,即将大写字母变成小写,小写字母变成大写,然后把这个新的字符串输出。   输入格式:输入一个字符串,而且这个字符串当中只包含英文字母,不包含其他类型的字符,也没有空格。   输出格式:输出经过转换后的字符串。 输入输出样例 样例输入 AeDb 样例输出 aEdB 思路: string 里面的islower()和tolower()、toupper()函数 代码: #include<iostream> #include<string> using namespace std; int main() { string s; cin>>s; for(int i=0;i<s.length();i++) if(islower(s[i])) s[i]=toupper(s[i]); else s[i]=tolower(s[i]); cout<<s<<endl; return 0; } 来源: https://www.cnblogs.com/lemonbiscuit/p/7776034.html