首页 > 解决方案 > Caesar Cipher 的第二变体(将最终字符串拆分为多个部分时遇到问题)

问题描述

提示

在这个国家,士兵很穷,但他们的通信需要一定程度的保密,因此,尽管他们不知道凯撒密码,但他们以以下方式重新发明了它。

他们使用 ASCII,但并不真正了解它,但只编码字母 az 和 AZ。保留其他字符,例如。

他们更改“轮换”每个新消息。一旦消息被编码,这个“旋转”就是他们消息的前缀。前缀由 2 个字母组成,第二个字母通过“旋转”从第一个字母移位,第一个字母是未编码消息的第一个字母,在被小写后。

例如,如果“旋转”是 2,如果未编码消息的第一个字母是“J”,则前缀应该是“jl”。

为了降低风险,他们将编码信息和前缀分成五部分,因为他们只有五个跑步者,每个跑步者只有一件。

如果可能的话,消息将在五名跑步者之间平均分配;如果不可能,第 1、2、3、4 部分会更长,第 5 部分会更短。第五部分的长度可以等于其他部分或更短。如果拆分方式有很多选项,只要满足前面的条件,就选择第五部分长度最长的选项。如果最后一部分是空字符串,请不要将此空字符串放入结果数组中。

例如,如果编码消息的长度为 17,则五个部分的长度将为 4、4、4、4、1。部分 1、2、3、4 被平均分割,长度为 1 的最后部分较短. 如果长度为 16,则部分的长度为 4、4、4、4、0。部分 1、2、3、4 均分,第五名选手将留在家中,因为他的部分是空字符串,而不是保留。

你能让他们轻松编写代码吗?

shift = 1 的示例:

message : "我早该知道你会给我一个完美的答案!!!"

代码:=> [“ijJ tipvme ibw”,“f lopxo uibu z”,“pv xpvme ibwf”,“b qfsgfdu botx”,“fs gps nf!!!”]

顺便说一句,也许你能帮他们解码吗?

//到此结束

面临的问题:

无法弄清楚如何根据给定的条件划分编码的字符串。我了解如何进行除法背后的数学运算,但无法将其转换为代码。我知道我使用的 num 变量需要减 4 并且 count 变量应该增加 4 直到条件 (num/4 > count) 因为条件是这样的,如果字符串可以以多种方式拆分,那么我们应该这样做,使第 5 部分的长度最长。

我的代码:

static vector<string> encodeStr(const string &s, int shift)
{
    char pre = tolower(s[0]);
    pre += shift;
    string newS = "";
    newS += tolower(s[0]);
    newS += pre;
    vector<string> ans;

    for (int i = 0; i < (int)s.size(); i++)
    {
        if ((s[i] >= 65 && s[i] <= 90) || (s[i] >= 97 && s[i] <= 122))
        {
            char c = s[i];
            c += shift;
            newS += c;
        }
        else
            newS.push_back(s[i]);
    }

    if (newS.size() % 4 == 0)
    {
        int parts = newS.size() / 4;
        int start = 0;
        while (start < (int)newS.size())
        {
            ans.push_back(newS.substr(start, parts));
            start += parts;
        }
    }
    else if (newS.size() % 5 == 0)
    {
        int parts = newS.size() / 5;
        int start = 0;

        while (start < (int)newS.length())
        {
            ans.push_back(newS.substr(start, parts));
            start += parts;
        }
    }
    else if (newS.length() % 5 != 0 && newS.length() % 4 != 0)
    {
        int num = newS.length();
        int count = 0;
        int start = 0;
        while (num % 4 != 0)
        {
            num--;
            count++;
        }
        while (num / 4 > count)
        {
            num = num - 4;
            count = count + 4;
        }

        int x = newS.length() - count;
        int parts = x / 4;

        while (start < (int)newS.length() - count)
        {
            ans.push_back(newS.substr(start, parts));
            start += parts;
        }
        ans.push_back(newS.substr((int)newS.size() - count, count));
    }

    return ans;
}

static string decode(vector<string> &s)
{
    string s1 = "";
    char check = ' ' - 1;

    for (int i = 0; i < (int)s.size(); i++)
    {
        s1 += s[i];
    }
    char a = s1[1];
    char b = s1[0];
    int shift = a - b;
    s1.erase(0, 2);
    transform(s1.begin(), s1.end(), s1.begin(), [&](auto x)
              {
                  if ((x >= 65 && x <= 90) || (x >= 97 && x <= 122))
                      return x -= shift;
                  else
                      return x;
              });

    for (int i = 0; i < (int)s1.size(); i++)
    {
        if (s1[i] == check)
        {
            s1[i]++;
        }
    }
    return s1;
}

代码输出

标签: c++stringmathsplitsubstring

解决方案


推荐阅读