C 消息同步算法

C 消息同步算法,c,algorithm,C,Algorithm,我们有两个无限重复的消息,由字符a-z组成。每个字符的传输时间单位不同;a=1,b=2,c=4,d=8,e=16…,字符|告诉我们消息中的当前位置。我们的工作是确定同步这两条消息需要多少时间单位。同步意味着两条消息同时开始 例如: 我们有信息1:ea | babab 信息2:d|abaca 因此,我们知道信息1是bababea,信息2是abacad 消息将在42个时间单位内同步: ea | bababea |=42 d | abacad | abacad |=42 例2: 消息1:| acabb

我们有两个无限重复的消息,由字符a-z组成。每个字符的传输时间单位不同;a=1,b=2,c=4,d=8,e=16…,字符|告诉我们消息中的当前位置。我们的工作是确定同步这两条消息需要多少时间单位。同步意味着两条消息同时开始

例如:

我们有信息1:ea | babab

信息2:d|abaca

因此,我们知道信息1是bababea,信息2是abacad

消息将在42个时间单位内同步:

ea | bababea |=42

d | abacad | abacad |=42

例2: 消息1:| acabbaaa消息2:| dcbabaaaa

解决方案:0,因为它们已同步

我们想提出一个算法来计算第一次同步发生之前的时间

我是用C写的。我基本上做了所有的事情,除了算法本身


我认为这可以用扩展的欧几里德算法来实现。

我回答了一个不同的问题,我认为这个问题的解决方案是完全相同的。您需要解方程m1Offset+(m1Len*intN1)=m2Offset+(m2Len*intN2)

我们需要找到满足上述方程的intN1和intN2当且仅当m1Len和m2Len的GCD除以(m2Offset-m1Offset)时,才会有解决方案。

在下面的代码中

  • m1Len和m2Len:消息m1和m2的长度。例如:“ea | babab”的长度是“bababa”的长度=25,而在消息“d | abaca”中,“abacad”的长度=17
  • m1Offset和m2Offset:初始偏移。例如:在消息“ea | babab”中,“ea”是偏移量,等于17。类似地,在“d | abaca”中,“d”是偏移量,等于8

  • m1Time和m2Time应该相等,这是第一次同步时间

这是我的密码

#include <stdio.h>

void findVal(unsigned int m1Offset, unsigned int m1Len, unsigned int m2Offset, unsigned int m2Len) ;
unsigned int getGCD(unsigned int n1, unsigned int n2);

int main()
{
    findVal(17, 25, 8, 17);
    return 0;
}

void findVal(unsigned int m1Offset, unsigned int m1Len, unsigned int m2Offset, unsigned int m2Len) {

    unsigned int  n1       = 0;
    unsigned int  n2       = 0;
    unsigned char foundVal = 1;
    unsigned int  m1Time   = m1Offset;
    unsigned int  m2Time   = m2Offset;

    //No need to find n1 and n2 if msgs are starting from beginning.
    if(((m1Offset == m1Len) && (m2Offset == m2Len)) || ((0 == m1Offset) && (0 == m2Offset)))
    {
        m1Time = 0;
        m2Time = 0;
    }

    //No need to find n1 and n2 if offset times are same.
    else if(m1Offset != m2Offset)
    {
       //Offset times are not same.
       foundVal = 0;

       //Find GCD of m1Len and m2Len.
       unsigned int gcd = getGCD(m1Len, m2Len);

       //There is a solution only if the difference of offsets is divisible by gcd.
       if(0 == (m2Offset-m1Offset) % gcd)
       {
           for(n2=1; n2<(unsigned int)-1; n2++)
           {
               unsigned int temp1 = (m2Len*n2)+(m2Offset-m1Offset);
               if(0 == temp1 % m1Len)
               {
                    n1 = temp1/m1Len;
                    m1Time = m1Offset + n1*m1Len;
                    m2Time = m2Offset + n2*m2Len;

                    foundVal = 1;
                    break;
               }
           }
       }
    }

    if(1 == foundVal)
    {
        printf("Found n1[%u] n2[%u] m1Time[%u] m2Time[%u]\n", n1, n2, m1Time, m2Time);
    }
    else
    {
        printf("Could not find n1, n2, m1Time, m2Time\n");
    }
}

unsigned int getGCD(unsigned int n1, unsigned int n2)
{
    while(n1!=n2)
    {
        if(n1 > n2)
            n1 -= n2;
        else
            n2 -= n1;
    }
    printf("GCD = %u\n",n1);

    return n1;
}

如果我正确理解了您的问题陈述,那么解决方案就是直接应用,非常感谢!虽然我发现下面的输入创建了无限循环:findVal(16,20,19,24)@Mykybo:它不是无限循环,它检查从0到UNSIGNED_INT_MAX,这需要时间。你可以参考我对那个问题的回答。如果消息长度不是成对共素数,即GCD(m1Len,m2Len)大于1,您可能找不到解决方案。实际上,findVal(52,56,60,72):m1Len是56,m2Len是72,它有GCD 8(大于1),您可以找到解决方案:276。是的。如果GCD>1,则无法保证找到同步时间。是否没有确定的方法来说明解决方案是否存在?一直运行到UNSIGNED_INT_MAX需要很多时间。
#include <stdio.h>

void findVal(unsigned int m1Offset, unsigned int m1Len, unsigned int m2Offset, unsigned int m2Len) ;
unsigned int getGCD(unsigned int n1, unsigned int n2);

int main()
{
    findVal(17, 25, 8, 17);
    return 0;
}

void findVal(unsigned int m1Offset, unsigned int m1Len, unsigned int m2Offset, unsigned int m2Len) {

    unsigned int  n1       = 0;
    unsigned int  n2       = 0;
    unsigned char foundVal = 1;
    unsigned int  m1Time   = m1Offset;
    unsigned int  m2Time   = m2Offset;

    //No need to find n1 and n2 if msgs are starting from beginning.
    if(((m1Offset == m1Len) && (m2Offset == m2Len)) || ((0 == m1Offset) && (0 == m2Offset)))
    {
        m1Time = 0;
        m2Time = 0;
    }

    //No need to find n1 and n2 if offset times are same.
    else if(m1Offset != m2Offset)
    {
       //Offset times are not same.
       foundVal = 0;

       //Find GCD of m1Len and m2Len.
       unsigned int gcd = getGCD(m1Len, m2Len);

       //There is a solution only if the difference of offsets is divisible by gcd.
       if(0 == (m2Offset-m1Offset) % gcd)
       {
           for(n2=1; n2<(unsigned int)-1; n2++)
           {
               unsigned int temp1 = (m2Len*n2)+(m2Offset-m1Offset);
               if(0 == temp1 % m1Len)
               {
                    n1 = temp1/m1Len;
                    m1Time = m1Offset + n1*m1Len;
                    m2Time = m2Offset + n2*m2Len;

                    foundVal = 1;
                    break;
               }
           }
       }
    }

    if(1 == foundVal)
    {
        printf("Found n1[%u] n2[%u] m1Time[%u] m2Time[%u]\n", n1, n2, m1Time, m2Time);
    }
    else
    {
        printf("Could not find n1, n2, m1Time, m2Time\n");
    }
}

unsigned int getGCD(unsigned int n1, unsigned int n2)
{
    while(n1!=n2)
    {
        if(n1 > n2)
            n1 -= n2;
        else
            n2 -= n1;
    }
    printf("GCD = %u\n",n1);

    return n1;
}
Found n1[1] n2[2] m1Time[42] m2Time[42]