提问者:小点点

降低圈复杂度


我在写一个NMEAParser库。 顾名思义,它解析NMEA句子。 没什么疯狂的。

它的入口点是一个函数,它接受一个NMEA字符串作为它的唯一参数,并查看它的开头将它传递给正确的解码器。 下面是功能:

bool NMEAParser::dispatch(const char *str) {
    if (!str[0]) {
        return false;
    }

    //check NMEA string type
    if (str[0] == '$') {
        //PLSR245X
        if (str[1] == 'P' && str[2] == 'L' && str[3] == 'S' && str[4] == 'R' && str[5] == ',' && str[6] == '2' && str[7] == '4' && str[8] == '5' && str[9] == ',') {
            if (str[10] == '1')
                return parsePLSR2451(str);
            if (str[10] == '2')
                return parsePLSR2452(str);
            if (str[10] == '7')
                return parsePLSR2457(str);
        } else if (str[1] == 'G' && str[2] == 'P') {
            //GPGGA
            if      (str[3] == 'G' && str[4] == 'G' && str[5] == 'A')
                return parseGPGGA(str);
            //GPGSA
            else if (str[3] == 'G' && str[4] == 'S' && str[5] == 'A')
                return parseGPGSA(str);
            //GPGSV
            else if (str[3] == 'G' && str[4] == 'S' && str[5] == 'V')
                return parseGPGSV(str);
            //GPRMC
            else if (str[3] == 'R' && str[4] == 'M' && str[5] == 'C')
                return parseGPRMC(str);
            //GPVTG
            else if (str[3] == 'V' && str[4] == 'T' && str[5] == 'G')
                return parseGPVTG(str);
            //GPTXT
            else if (str[3] == 'T' && str[4] == 'X' && str[5] == 'T')
                return parseGPTXT(str);
            //GPGLL
            else if (str[3] == 'G' && str[4] == 'L' && str[5] == 'L')
                return parseGPGLL(str);
        }
        //HCHDG
        else if (str[1] == 'H' && str[2] == 'C' && str[3] == 'H' && str[4] == 'D' && str[5] == 'G')
            return parseHCHDG(str);
    }
    return false;
}

这不是真正的问题,因为代码非常容易阅读。 但我想知道如何降低它的复杂性,同时保持它的简单易读和高效。


共1个答案

匿名用户

您可以将其简化很多:

if (std::string_view{str, 10} == "$PLSR,245,")
{
  switch (str[10])
  {
    case '1' : return parsePLSR2451(str);
    case '2' : return parsePLSR2452(str);
    case '7' : return parsePLSR2457(str);
  }
}
else if (std::string_view{str + 1, 2} == "GP")
{
  auto s = std::string_view{str + 3, 3};
  if (s == "GGA")
    return parseGPGGA(str);
  if (s == "GSA")
    return parseGPGSA(str);
  // ... etc
}
else if (std::string_view{str + 1, 5} == "HCHDG")
{
   return parseHCHDG(str);
}

return false;

也没有构造额外的string,因此它至少应该同样有效。