c++ - 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;
}
解决方案
推荐阅读
- layout - Xcode 10 - 如何固定 UI 元素库窗口?
- android - 导航抽屉项目单击不适用于其他活动
- c# - 在 C# 中不知道发件人的情况下收听事件?
- regex - 正则表达式合并所有段落的所有行,同时保持这些段落分开
- c - C,将半字节从输入转换为十六进制
- python - 如何在不改变 LSTM-Cell 之后的图形部分的情况下逐步使用 LSTM - 即具有新状态?
- flutter - Flutter:ListView.builder 中的文本字段
- android - 如何在Android(TextView)中将带有HTML代码的双引号显示为文本?
- android - Facebook AccountKit 的 Firebase 身份验证错误
- swift - Swift:Quickblox 跟踪 startcall 并获取错误(调试)