6.Z 字形变换
我的思路貌似没有第二家,不过我懒得解释了。
#include <string>
#include <iostream>
using namespace std;
template<typename T>
T ConvertZ(const T& vec, int N)
{
if (N <= 1)
return vec;
T ret;
int n = N - 1;
int n2 = n * 2;
int length = vec.size();
ret.resize(length);
//组数-1
int m = length / n2;
//最后一组的元素数量 [0, 2n)
int other = length - m * n2;
//最后一组的每行元素数量(一共N行)
int* last = new int[N]();
//首尾行特殊判断
if (other > 0)
{
last[0] = 1;
if (other > n)
{
last[n] = 1;
}
}
//其余行
for (int i = 1; i != N; ++i)
{
if (i < other)
last[i] += 1;
if (n2 < other + i)
last[i] += 1;
}
//第n行前的数量求和
for (int i = 0; i != N; ++i)
{
last[i] += m;//组数
//第一行和最后一行只加m
if (i != 0 && i != n)
last[i] += m;
if (i > 0)
last[i] += last[i - 1];
}
for (int i = 0; i != length; ++i)
{
//余数
int mu = i % n2;
//组号
int div = i / n2;
if (mu == 0)
{
ret[div] = vec[i];
}
else if (mu == n)
{
ret[last[n - 1] + div] = vec[i];
}
else if (mu < n)
{
ret[last[mu - 1] + div * 2] = vec[i];
}
else if (mu > n)
{
ret[last[n2 - mu - 1] + div * 2 + 1] = vec[i];
}
}
delete[] last;
return ret;
}
int main()
{
wcout << L"---------------------string is------------------------" << endl;
wstring str0 = L"PAYPALISHIRING";
wcout << str0 << L" -> " << ConvertZ(str0, 3) << " should be \"PAHNAPLSIIGYIR\"" << endl;
wcout << str0 << L" -> " << ConvertZ(str0, 4) << " should be \"PINALSIGYAHRPI\"" << endl;
}