最大频率栈

今天写到一到数据结构的题目,觉得很有意思,遂记录下leetcode895最大频率栈
这题既需要记录每个数字的频率,又需要记录每种频率拥有的数字,故采用两个map来实现。

执行过程如下:
请添加图片描述

class FreqStack {
public:
    FreqStack() {
        maxFreq=0;
    }
    
    void push(int val) {
        /*查询是否已存在*/
        if(numFreq.find(val)==numFreq.end()){
            numFreq[val]=1;
            freqNums[1].push(val);
            if(maxFreq==0)
                maxFreq=1;
        }else{
            numFreq[val]++;
            freqNums[numFreq[val]].push(val);
            if(numFreq[val]>maxFreq)
                maxFreq++;
        }
    }
    
    int pop() {
        int ans=freqNums[maxFreq].top();
        freqNums[maxFreq].pop();
        if(freqNums[maxFreq].empty())
            maxFreq--;
        if(numFreq[ans]==1){
            numFreq.erase(ans);
        }else{
            numFreq[ans]--;
        }
        return ans;
    }
private:
    map<int,int>numFreq;    //每个数字的频率
    map<int,stack<int>>freqNums;    //每种频率含有的数字
    int maxFreq;    //最大频率
};

/**
 * Your FreqStack object will be instantiated and called as such:
 * FreqStack* obj = new FreqStack();
 * obj->push(val);
 * int param_2 = obj->pop();
 */
<think>好的,用户想了解在120MHz频率下如何计算最大延时,以及相关的限制因素。我需要结合提供的引用资料,特别是引用[2]中的SysTick定时器配置方法,来解答这个问题。 首先,系统时钟频率是120MHz,也就是每秒钟有120,000,000个时钟周期。SysTick定时器通常是一个24位的递减计数器,最大值是0xFFFFFF,即16,777,215。因此,最基本的最大延时计算应该是计数器最大值除以时钟频率。不过需要确认用户使用的微控制器是否也是24位的SysTick,比如STM32F1系列通常如此。 然后,根据引用[2]中的代码示例,SysTick->LOAD的值设置为9000*nus,这里9000是因为F1系列的内核时钟是72MHz时的一个系数。但用户的情况是120MHz,所以需要调整系数。假设SysTick使用系统时钟,那么每个时钟周期的时间是1/120,000,000秒,即约8.333纳秒。当LOAD寄存器设置为最大值16,777,215时,最大延时时间应该是16,777,215 / 120,000,000 ≈ 0.1398秒,也就是约139.8毫秒。不过需要注意是否分频,如果SysTick被分频,比如使用系统时钟的八分之一,那时间会更长,但通常SysTick可以直接使用系统时钟。 接下来,用户提到的最大延时可能受限于定时器的位数。如果代码中使用的是类似引用[2]中的函数,那么当需要更长的延时时,可能需要多次调用delay函数,或者结合循环。比如,多次调用139毫秒的延时,再加上软件循环来达到更长的延时。但这样会增加额外的指令时间,需要考虑函数调用和循环带来的开销,如引用[1]中提到的LCALL和RET指令的时间,不过这部分在120MHz下可能影响较小,但仍需注意累积效应。 另外,中断的影响也是一个重要因素。如果在延时过程中发生中断,SysTick的计数会被中断处理打断,导致实际延时变长。因此,在需要精确延时的场合,可能需要禁用中断,但这会影响系统实时性。 总结下来,最大延时的计算需要考虑定时器的位数、时钟频率、分频系数,以及软件实现方式。同时,硬件限制如定时器溢出、中断响应和系统时钟稳定性都会影响实际的最大延时。需要根据具体硬件手册确认SysTick的配置,以及是否存在其他限制因素。</think>在120MHz系统频率下计算最大延时,需结合定时器位数、时钟分频系数和函数调用机制,以下是分步说明: ### 一、SysTick定时器基础计算 1. **确定定时器位数** SysTick为24位递减计数器,最大值$N_{max}=2^{24}-1=16,777,215$ 2. **计算单次最大延时的时钟周期数** $$T_{max} = \frac{N_{max}}{f_{sys}} = \frac{16,777,215}{120 \times 10^6} ≈ 0.1398s \quad (139.8ms)$$ ### 二、代码实现限制 1. **直接配置SysTick的局限** 引用[2]中代码的LOAD寄存器公式需调整系数: 原F1系列系数为$9000=72MHz/8kHz$,120MHz时系数应为: $$k = \frac{120MHz}{1MHz} = 12000$$ 对应单次最大延时: $$t_{max} = \frac{16,777,215}{12000} ≈ 1398μs \quad (仅1.398ms)$$ 这表明函数设计直接影响实际可用延时范围[^2]。 ### 三、扩展延时方法 1. **循环嵌套实现长延时** ```c void delay_ms(uint32_t tms) { while(tms--) { delay_us(1000); //调用基础延时函数 } } ``` 此时理论最大延时受限于变量类型(uint32_t最大$2^{32}-1=4,294,967,295ms≈49.7天$) 2. **硬件限制修正因子** 需考虑函数调用开销(如引用[1]中LCALL指令2μs) 实际延时$T_{real}=N \times (t_{base} + t_{overhead})$ 其中$t_{overhead}$包含操作、循环判断等指令时间[^1] ### 四、关键限制因素 1. **定时器溢出风险** 若直接使用16位定时器,120MHz时单次最大延时仅: $$\frac{65,535}{120 \times 10^6} ≈ 0.546ms$$ 2. **中断响应延迟** 根据ARM Cortex-M手册,SysTick中断响应需12周期,在120MHz下引入额外$0.1μs$误差 ### 五、推荐计算方法 1. **精确公式** $$T_{total} = \frac{(LOAD + 1) \times P}{f_{sys}}$$ 其中$P$为分频系数(通常=1),LOAD≤16,777,215 2. **120MHz下验证示例** 配置LOAD=60,000-1,则: $$T = \frac{60,000}{120 \times 10^6} = 0.5ms$$ 此时可构建精确500μs基准单元
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值