You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求Codesys中IQueue使用示例及FIFO数组中位数计算方案

解决Codesys中FIFO数组的中位数计算问题

核心思路概述

由于数组长度始终为奇数,中位数本质是排序后处于中间位置的元素。结合FIFO的特性,可通过两种方案实现:基于IQueue的官方队列组件,或手动用固定长度数组模拟FIFO,后者更直观可控。

方案一:用IQueue实现FIFO+中位数计算

步骤1:初始化队列

首先导入System.Collections库,创建固定容量的IQueue实例(容量设为你的目标奇数长度):

VAR
    fifoQueue: IQueue;
    queueCapacity: INT := 5; // 示例奇数长度
    initDone: BOOL := FALSE;
END_VAR

// 初始化逻辑(放在程序初始化块)
IF NOT initDone THEN
    fifoQueue := Queue.Create(queueCapacity);
    initDone := TRUE;
END_IF

步骤2:实现FIFO写入逻辑

新增元素时,若队列已满则先移除队首元素,再添加新元素:

VAR
    newValue: REAL;
    tempValue: REAL;
END_VAR

// FIFO写入操作
IF fifoQueue.Count = queueCapacity THEN
    tempValue := fifoQueue.Dequeue(); // 移除首个元素
END_IF
fifoQueue.Enqueue(newValue); // 添加新元素

步骤3:计算中位数

IQueue不支持直接排序,需先将元素复制到临时数组,排序后取中间值:

VAR
    tempArray: ARRAY[0..4] OF REAL; // 长度与队列容量一致
    i: INT;
    median: REAL;
    midIndex: INT;
END_VAR

// 复制队列元素到数组
FOR i := 0 TO fifoQueue.Count - 1 DO
    tempArray[i] := fifoQueue.PeekAt(i); // 通过索引访问队列元素
END_FOR

// 对临时数组升序排序
SORT(tempArray, TRUE);

// 取中位数(奇数长度的中间索引为 (容量-1)/2)
midIndex := (queueCapacity - 1) DIV 2;
median := tempArray[midIndex];

方案二:手动用固定长度数组模拟FIFO(更直观)

若觉得IQueue操作不灵活,可手动实现FIFO逻辑:

步骤1:定义数组与指针

VAR
    fifoArray: ARRAY[0..4] OF REAL; // 示例奇数长度
    writePtr: INT := 0;
    elementCount: INT := 0;
    median: REAL;
    tempArray: ARRAY[0..4] OF REAL;
    i: INT;
    midIndex: INT;
END_VAR

步骤2:实现FIFO写入逻辑

用循环指针实现队列的循环覆盖:

VAR
    newValue: REAL;
END_VAR

// 写入新元素
fifoArray[writePtr] := newValue;
writePtr := (writePtr + 1) MOD queueCapacity; // 指针循环移位
IF elementCount < queueCapacity THEN
    elementCount := elementCount + 1;
END_IF

步骤3:计算中位数

复制有效元素到临时数组,排序后取中间值:

// 复制有效元素到临时数组(队列未满时仅复制已存入的元素)
FOR i := 0 TO elementCount - 1 DO
    tempArray[i] := fifoArray[(writePtr + i) MOD queueCapacity];
END_FOR

// 排序数组
SORT(tempArray, TRUE);

// 取中位数
midIndex := (elementCount - 1) DIV 2;
median := tempArray[midIndex];

优化建议

  • 若数组长度较大,每次排序会产生性能开销,可维护有序数组:新增元素时插入到对应排序位置,移除队首元素时直接删除对应索引,这样中位数可直接取中间元素,无需重复排序(适合性能敏感场景)。
  • 注意数据类型一致性,若使用整数数组,将代码中的REAL替换为INT即可。

内容的提问来源于stack exchange,提问作者lightswitch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 16:05:16