Create two functions to encode and then decode a string using the Rail
Fence Cipher. This cipher is used to encode a string by placing each
character successively in a diagonal along a set of “rails”. First
start off moving diagonally and down. When you reach the bottom,
reverse direction and move diagonally and up until you reach the top
rail. Continue until you reach the end of the string. Each “rail” is
then read left to right to derive the encoded string. You can
optionally include or dis-include punctuation.For example, the string “WEAREDISCOVEREDFLEEATONCE” could be
represented in a three rail system as follows:W E C R L T E E R D S O
E E F E A O C
A I V D E N The encoded string would be:WECRLTEERDSOEEFEAOCAIVDEN Write a function/method that takes 2
arguments, a string and the number of rails, and returns the ENCODED
string.Write a second function/method that takes 2 arguments, an encoded
string and the number of rails, and returns the DECODED string.For both encoding and decoding, assume number of rails >= 2 and that
passing an empty string will return an empty string.Note that the example above excludes the punctuation and spaces just
for simplicity. There are, however, tests that include punctuation.
Don’t filter out the punctuation as they are a part of the string.
解题:
这道题的意思是按照波浪线的方式对给定的字符串进行编码和解码实现.
代码如下:
#include <string>
#include <vector>
std::string encode_rail_fence_cipher(std::string str, int n) {
if (n <=1)
{
return str;
}
if (str.empty())
{
return str;
}
std::vector<std::string> rails(n);
int iLen = str.size();
int iTemp = 0;
bool bAddDir = true;
for (int i=0;i <iLen;i++)
{
rails[iTemp].push_back(str[i]);
if (bAddDir)
{
if (iTemp ==n -1)
{
bAddDir = false;
iTemp--;
}
else
{
iTemp++;
}
}
else
{
if (iTemp ==0)
{
bAddDir = true;
iTemp++;
}
else
{
iTemp--;
}
}
}
std::string strResults;
for (auto &strTemp: rails)
{
strResults += strTemp;
}
return strResults;
}
std::string decode_rail_fence_cipher(std::string str, int n) {
if (n <= 1)
{
return str;
}
if (str.empty())
{
return str;
}
int iLen = str.size();
int iMod = (n - 1) * 2;
int iDiv = iLen / iMod;
int iAdd = iLen % iMod;
std::vector<int> addvec(n,0);
int iIndex = 0;
bool bAddDir = true;
while (iAdd > 0)
{
addvec[iIndex] += 1;
iAdd--;
if (bAddDir)
{
if (iIndex ==n -1)
{
iIndex--;
bAddDir = false;
}
else
{
iIndex++;
}
}
else
{
iIndex--;
}
}
std::vector<std::string> strTemps(n);
for (int i=0;i <n;i++)
{
if (i ==n -1)
{
strTemps[i] = str;
break;
}
int iCurLen = iDiv;
if (i !=0 )
{
iCurLen = 2 * iDiv;
}
iCurLen += addvec[i];
strTemps[i] = str.substr(0, iCurLen);
str.erase(str.begin(), str.begin()+ iCurLen);
}
std::string strResults;
bAddDir = true;
int iTemp = 0;
while (strResults.length() != iLen)
{
strResults.push_back(strTemps[iTemp][0]);
strTemps[iTemp].erase(strTemps[iTemp].begin());
if (bAddDir)
{
if (iTemp == n - 1)
{
bAddDir = false;
iTemp--;
}
else
{
iTemp++;
}
}
else
{
if (iTemp == 0)
{
bAddDir = true;
iTemp++;
}
else
{
iTemp--;
}
}
}
return strResults;
}