C 删除存储在数组中的标志位
我目前拥有存储011111110 011011111的变送器阵列 我希望接收器阵列存储0110111。我想消除所有01111110位 但我收到的是011011110。为什么我的代码只删除发射机阵列中的前0111110位 我的尝试代码如下所示:C 删除存储在数组中的标志位,c,arrays,loops,C,Arrays,Loops,我目前拥有存储011111110 011011111的变送器阵列 我希望接收器阵列存储0110111。我想消除所有01111110位 但我收到的是011011110。为什么我的代码只删除发射机阵列中的前0111110位 我的尝试代码如下所示: #define nosbits 23 #include<stdio.h> #include <stdlib.h> #include<stdbool.h> int main() { unsigned trans
#define nosbits 23
#include<stdio.h>
#include <stdlib.h>
#include<stdbool.h>
int main()
{
unsigned transmitter[nosbits] = { 0,1,1,1,1,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0 };
unsigned receiver[nosbits];
int count = 0;
int outputreceivercount = 0;
bool flag = false;
for (int i = 0; i < nosbits; i++)
{
if (transmitter[i] == 1)
{
count++;
}
else
{
count = 0;
}
receiver[outputreceivercount++] = transmitter[i];
//After 5 consecutive 1s, if the next two bits are '10', then the flag is detected.
if ((transmitter[i + 1] == 1) && (transmitter[i + 2] == 0) && count == 5)
{
if (!(flag))
{
flag = true;
i = i + 2;
outputreceivercount = 0;
count = 0;
}
}
}
printf("Bitstream before removing flag bits:\n");
for (int i = 0; i < nosbits; i++)
{
printf("%d", transmitter[i]);
}
printf("\n\n");
printf("Bitstream after removing flag bits:\n");
for (int i = 0; i < outputreceivercount; i++)
{
printf("%d", receiver[i]);
}
printf("\n");
system("pause");
return 0;
}
#定义位23
#包括
#包括
#包括
int main()
{
无符号发射机[nosbits]={0,1,1,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,0};
无符号接收机[nosbits];
整数计数=0;
int outputreceivercount=0;
布尔标志=假;
for(int i=0;i
要回答您的具体问题,您需要在执行看起来是“删除”部分的操作之前检查标志的状态-您需要在“删除”位之前将标志设置为false。第一次检测到此类标志时,请将标志
设置为true。然后,它将在所有后续循环中保持为真,因此您的“remove”部分将无法再次执行
更一般地说,我对您的“删除”部分有点困惑——每次检测到“标志”时,您都会从第0个元素开始覆盖receiver
?字符串中发生了什么,例如“011111110011011101111111010101010”-您希望您的输出是什么?实际上,您不需要“flag”变量来检测标志。
替换以下代码并查看是否有帮助
//After 5 consecutive 1s, if the next two bits are '10', then the flag is detected.
if ((transmitter[i + 1] == 1) && (transmitter[i + 2] == 0) && count == 5)
{
i = i + 2;
outputreceivercount -= (count+1);
count = 0;
}
如果需要,可以对其进行更多优化。1)如果需要以8位的倍数检测标志,最好使用字符,因此当检测到字节0x7e时,请将其删除。这适用于在仅传输8位字节的异步行中使用平面字符的情况。(您的示例数据在标志之间只有七位数据,因此我假设情况并非如此。)
2) 如果需要按位检测标志,则面临HDLC成帧问题,该问题有两部分:a)当检测到6个1
位时检测标志,b)如果序列中有5个以上1
位,则发射机插入0
位(以确保透明度)。对于第二部分,您还需要删除序列51
位之后的第60
位。我不知道您是否想要这个,但是您的标志似乎非常类似于HDLC标志,假设您实际上没有研究这个协议
这个问题可以用有限自动机来解决。检测这一点的NFA等效物为:
0,1
,--.
| /
| /
|v 1 1 1 1 1 0
(0)--->(1P)--->(2P)--->(3P)--->(4P)--->(5)--->(6D)
| | _
. . / \ 1
\ \ 1 | V
\0 `-->(7B)
\
\ 1 1 1 1 1 0
(8)--->(9)--->(10)--->(11)--->(12)--->(13)--->(14F)
在哪里
([1-4]P)
接受状态,打印状态号中显示的1
字符数,(例如,对于状态(3P)
打印111
)
(6D)
接受状态,打印11111
(7B)
接受状态。检测到中断条件
(14F)
接受状态。检测到标志
- 所有其他国家都不是接受国。自动装置必须继续
匹配状态,直到无法达到更多的接受状态,才能输出
作为输出访问的最后一个接受状态的字符串(例如,如果最后一个接受状态是6D,则它必须输出“11111”。如果访问的最后一个状态包括多个接受状态,则优先级顺序为:
14F, 7B, 6D, 4P, 3P, 2P, 1P
这个NFA识别8种字符串(我将它们表示为regexp),即:0
,01111110
,1
,11
,111
,1111
,11111 0
,和11111111*
。如果接受标志,您还必须检查位数是否为8的倍数,因为您可以使用此协议拥有任意位序列。可能您没有,因为samp您发布的le数据仅包含七位。它可以由以下lex(1)
模式表示:
%%
0 ECHO;
01111110 putchar('F');
1111111* putchar('B');
1 |
11 |
111 |
1111 ECHO;
111110 fputs("11111", stdout);
. ;
%%
注
下面是一个完整的DFA,它将输入位转换为
字母表(对于您的问题,只需将“F”
和“B”
字符串替换为空字符串“”
):
或者,如果要调试自动机工作方式的跟踪,请使用
cc -o hdlc_enc -DDEBUG=1 hdlc.c
ln hdlc_enc hdlc_dec
您将使用两个命令对标准输入进行编码hdlc_enc
,并使用hdlc_dec
对其进行解码。要编码,请使用F
作为标志,B
作为中断,0
和1
(无限制)它将在适当的位置插入0
。要解码,只需输入一个位序列,它将把标志转换为F
,分解为B
,并消除编码器插入的虚假0
。(插入五个1
位后,插入a0
,以确保透明度)
我手工编译了这个自动机,所以它的状态数可能不是最优的,但是18个状态并不太多
状态名称代表前缀ST
,后跟读得太远而尚未输出的内容,因为我们无法确定它是标志、中断还是简单的数据位序列。锚定到流开头的状态是
cc -o hdlc_enc hdlc.c
ln hdlc_enc hdlc_dec
cc -o hdlc_enc -DDEBUG=1 hdlc.c
ln hdlc_enc hdlc_dec