【问题标题】:Efficiently find a sequence within a buffer有效地在缓冲区中查找序列
【发布时间】:2014-09-17 23:39:21
【问题描述】:

所以我有一个缓冲区,我用一个最大为 1200 字节且大小可变的帧填充。当我得到一个始终相同且不会出现的尾部序列时,我知道帧是完整的。所以我试图找到如何最有效地检测该尾序列。这是嵌入的,因此我使用的函数调用和数据结构越少越好。

这是我目前所拥有的:

//I am reading off of a circular buffer so this is checking that I still have unread bytes  
while (cbuf_last_written_index != cbuf_last_read_index) {
    buffer[frame_size] = circular_buffer[cbuf_last_read_index];
    //this function does exactly what it says and just maintains circular buffer correctness
    increment_cbuf_read_index_count();
    frame_size++;

    //TODO need to make this more efficient
    int i;
    uint8_t sync_test_array[TAIL_SYNC_LENGTH] = {0};
    //this just makes sure I have enough in the frame to even bother checking the tail seq
    if (frame_size > TAIL_SYNC_LENGTH) { 
        for (i = 0; i < TAIL_SYNC_LENGTH; i++) {
            //sets the test array equal to the last TAIL_SYNC_LENGTH elements the buffer 
            sync_test_array[i] = buffer[(frame_size - TAIL_SYNC_LENGTH) + i];
        }
        if (sync_test_array == tail_sequence_array) {                     
            //I will toggle a pin here to notify that the frame is complete

            //get out of the while loop because the following bytes are part of the next frame
            break;
        }
     }
     //end efficiency needed area              
}

所以基本上对于添加到帧中的每个新字节,我都会检查最后 x 个字节(实际上可能是 ~8 个字节),看看它们是否是尾序列。你能想出更好的方法吗?

【问题讨论】:

  • 只检查最近读取的字节以查看它是否进一步匹配会更快。例如,如果读取的最后 3 个字节与模式的前三个匹配,则下一个字节需要匹配模式的第 4 个字节,等等。您一次只能将一个字节读入缓冲区吗?
  • 是的,这是我能想到的唯一选择,只需从检查最近的字节开始,一次检查每个字节。但那会是什么样子,基本上是一大堆嵌套的 if 语句,对吗?我想我只是觉得这很丑,但我想它肯定会更有效率。

标签: c arrays embedded


【解决方案1】:

将其实现为状态机。

如果您的尾部序列是 1,2,5,则伪代码将是:

switch(current_state) {
 IDLE: next_state = ONE_SEEN if new_byte == 1 else next-state = IDLE
 ONE_SEEN: next_state = TWO_SEEN if new_byte == 2 else next_state = IDLE
 TWO_SEEN: next_state = TERMINATE if new_byte == 5 else next_state = IDLE
}

【讨论】:

  • 这会比 caskey 的解决方案更高效还是更优雅?我想它会更有效,因为它只会在每个循环中运行一个条件,对吗?
  • 它基本上是对caskey解决方案的扩展。使用有限状态机是识别随时间变化的一系列值的最常用方法。
猜你喜欢
  • 2021-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多