The smallest free number

本文探讨了在无序自然数集合中寻找最小未出现整数的三种算法,包括直接搜索、布尔数组检查及分治策略,展示了不同方法的实现与效率分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The smallest free number

介绍

    假设给定了一个自然数的集合Set X,现在要求找出最小的一个不在集合Set X中的自然数。

    现在我们假设如果集合Set X中的数据是按非降序给定的,那此时解法也非常的直观,我们只要从头开始比较X和集合[0..],第一个不同的数即为所求,但是,当Set X是以一个无序给定时,例如:

[08,23,09,00,12,11,01,10,13,07,41,04,14,21,05,17,03,19,02,06]

    此时我们要在怎么找出最小数呢?

解法一

    我们可以根据有序时的思想,我们只要从头开始判断[0..]是否在Set X中,Haskell代码如下:

vs \\ xs = filter (`notElem` xs) vs

minFree xs = head $ [0..] \\ xs

    中序操作符\\和集合运算符\功能差不多,vs \\ xs 是在vs中去除在xs中的元素,此时复杂度为Θ(n2)。

解法二

    我们再次分析下,我们是从集合[0..]的0开始找的,然后每个元素去比对是否在Set X中,假设Set X的长度为n,则此时如果元素不重复,并且充满[0..n-1],则此时满足条件的自然数为n,而且此时n是满足条件的自然数中最大的数了,因为假如Set X的n个元素中有比n大的数,则此时必然满足条件的数是[0..n-1]中的数了,于是根据上面的想法,我们可以根据Set X产生一个长度为n+1序列b,其中每个元素的含义为bi:自然数i在Set X中是否存在,存在为True,此时我们就可以在序列b中从头开始找有多少个连续的True了,此时True的长度即为所求的自然数了。Haskell代码如下:

search :: Array Int Bool -> Int
search = length . takeWhile id . elems

checklist    :: [Int] -> Array Int Bool
checklist xs =  accumArray (||) False (0,n)
				(zip (filter (<=n) xs) (repeat True))
minFree = search . checklist

    上面主要有两个函数,一个是search,另一个是checklist,其中search主要是传入一个Bool的数组,然后从头找出最长的True序列的长度,而checklist则是根据数组的Int list来得到一个Bool的数组,即上面的序列b.

解法三

    解法三是运用分治的方法,首先我们给出一些式子:

  • (as++bs)\\cs =(as\\cs)++(bs\\cs)

  • as\\(bs++cs)=(as\\bs)\\cs

  • (as\\bs)\\cs =(as\\cs)\\bs

    现在我们假设as和vs不相关,则此时我们可以得到as\\vs=as,bs和us也不相关,则有bs\\us=bs,此时我们可以得到:

(as++bs)\\(us++vs)=(as\\us)++(bs\\vs)

    此时,我们让as=[0..b−1] ,bs =[b..],并且让us=filter(<b)xs,vs=filter(≥b),则此时我们可以得到

[0..] \\ xs = [0..b-1] \\ us ++ [b..] \\ vs
				where (us,vs) = partition (<b) xs 
				
head (xs++ys) = if null xs then head ys else head xs -- when is the recursive is out??

    然后我们分析指导 null xs的含义即 length [0..b-1] == b,于是我们可以定义下函数如下:

minfree xs = minfrom 0 xs

minfrom a xs	                | null xs 		     = a  -- 递归结束的条件
				| length us == b - a = minfrom b vs
				| otherwise          = minfrom a us
				  where (us,vs) = partition (<b) xs

    接下去我们要确定b的值,我们希望确定的b值,能够将xs进行等分,这样则对问题的规模可以有效的减小,一个直观想法是

b =  a + n / 2 where n = length xs

    但是上面是有问题的,为什么呢?

    因为上面我们有个假设是这样的 us = [ x | x < b] = [a,b)的,而 vs = [ x | x >= b ] = [b..],故我们应该要的是

b =  a + 1 + n / 2 where n = length xs

    这样我们就可以保证上面的式子成立了,并且递归后的问题规模为:

length us ≤n div 2 < n 或者 length vs =n−ndiv 2−1≤n div 2

    于是问题的复杂度为 

T(n) = T(ndiv 2) + Θ(n)

minfrom a (n,xs)	| n == 0 	 = a
			| m == b - a     = minfrom b (n-m,vs)
			| otherwise      = minfrom a (m,us)
			where    (us,vs) = partition (<b) xs
				 b       = a + 1 + (n / 2)
				 m	 = length us

Implement the classic method for composing secret messages called a square code. Given an English text, output the encoded version of that text. First, the input is normalized: the spaces and punctuation are removed from the English text and the message is down-cased. Then, the normalized characters are broken into rows. These rows can be regarded as forming a rectangle when printed with intervening newlines. For example, the sentence ```text "If man was meant to stay on the ground, god would have given us roots." ``` is normalized to: ```text "ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" ``` The plaintext should be organized into a rectangle as square as possible. The size of the rectangle should be decided by the length of the message. If `c` is the number of columns and `r` is the number of rows, then for the rectangle `r` x `c` find the smallest possible integer `c` such that: - `r * c >= length of message`, - and `c >= r`, - and `c - r <= 1`. Our normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`: ```text "ifmanwas" "meanttos" "tayonthe" "groundgo" "dwouldha" "vegivenu" "sroots " ``` The coded message is obtained by reading down the columns going left to right. The message above is coded as: ```text "imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau" ``` Output the encoded text in chunks that fill perfect rectangles `(r X c)`, with `c` chunks of `r` length, separated by spaces. For phrases that are `n` characters short of the perfect rectangle, pad each of the last `n` chunks with a single trailing space. ```text "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau " ``` 上述为题目要求,请用C语言实现,函数声明如下: char *ciphertext(const char *input)
08-13
内容概要:本文档详细介绍了一个基于MATLAB实现的跨尺度注意力机制(CSA)结合Transformer编码器的多变量时间序列预测项目。项目旨在精准捕捉多尺度时间序列特征,提升多变量时间序列的预测性能,降低模型计算复杂度与训练时间,增强模型的解释性和可视化能力。通过跨尺度注意力机制,模型可以同时捕获局部细节和全局趋势,显著提升预测精度和泛化能力。文档还探讨了项目面临的挑战,如多尺度特征融合、多变量复杂依赖关系、计算资源瓶颈等问题,并提出了相应的解决方案。此外,项目模型架构包括跨尺度注意力机制模块、Transformer编码器层和输出预测层,文档最后提供了部分MATLAB代码示例。 适合人群:具备一定编程基础,尤其是熟悉MATLAB和深度学习的科研人员、工程师和研究生。 使用场景及目标:①需要处理多变量、多尺度时间序列数据的研究和应用场景,如金融市场分析、气象预测、工业设备监控、交通流量预测等;②希望深入了解跨尺度注意力机制和Transformer编码器在时间序列预测中的应用;③希望通过MATLAB实现高效的多变量时间序列预测模型,提升预测精度和模型解释性。 其他说明:此项目不仅提供了一种新的技术路径来处理复杂的时间序列数据,还推动了多领域多变量时间序列应用的创新。文档中的代码示例和详细的模型描述有助于读者快速理解和复现该项目,促进学术和技术交流。建议读者在实践中结合自己的数据集进行调试和优化,以达到最佳的预测效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值