题目描述
给你一串未加密的字符串str,通过对字符串的每一个字母进行改变来实现加密,加密方式是在每一个字母str[i]偏移特定数组元素a[i]的量,数组a前三位已经赋值:a[0]=1,a[1]=2,a[2]=4。
当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3]。
例如:原文 abcde 加密后 bdgkr,其中偏移量分别是1,2,4,7,13。
输入描述
第一行为一个整数n(1<=n<=1000),表示有n组测试数据,每组数据包含一行,原文str(只含有小写字母,0<长度<=50)。
输出描述
每组测试数据输出一行,表示字符串的密文。
用例
输入 | 1 |
输出 | ya |
说明 | 第一个字符x偏移量是1,即为y,第二个字符y偏移量是2,即为a。 |
字符串加密算法解析:如何通过动态偏移数组实现字符转换加密
1. 核心解题思路
1.1 问题拆解
要实现加密,需解决以下两个核心问题:
- 生成偏移数组
a
:- 根据递推公式计算每个位置的偏移量。
- 关键点:处理大数问题(偏移量可能非常大)。
- 字符偏移转换:
- 将每个字符按对应的偏移量转换为新字符。
- 关键点:字母循环处理(如
z
偏移1
后应为a
)。
1.2 关键步骤
步骤1:生成偏移数组 a
- 初始值:
a[0] = 1
a[1] = 2
a[2] = 4
- 递推公式:
a[i] = a[i-1] + a[i-2] + a[i-3]
- 优化:模26运算:
- 由于字母表长度为26,偏移量超过26时实际等效于
a[i] % 26
。 - 例如,偏移量27等价于1(
27 % 26 = 1
),避免数值过大。
- 由于字母表长度为26,偏移量超过26时实际等效于
步骤2:字符偏移转换
- 字符位置计算:
- 将字符转换为字母表的索引(
a=0, b=1, ..., z=25
)。
- 将字符转换为字母表的索引(
- 偏移操作:
- 新位置 = (原位置 + 偏移量) % 26
- 字符还原:
- 将计算后的索引转换回字符。
2. 代码实现与详细注释
Python代码
n = int(input()) # 读取测试用例数量
for _ in range(n):
s = input().strip() # 读取原文
m = len(s)
a = [] # 初始化偏移数组
# 填充前三个元素(注意字符串长度可能小于3)
if m >= 1:
a.append(1)
if m >= 2:
a.append(2)
if m >= 3:
a.append(4)
# 生成后续元素(i从3到m-1)
for i in range(3, m):
# 计算当前偏移量并取模26
next_val = (a[i-1] + a[i-2] + a[i-3]) % 26
a.append(next_val)
# 加密每个字符
encrypted = []
for i in range(m):
# 将字符转换为0-25的索引
original_pos = ord(s[i]) - ord('a')
# 计算新位置并取模26
new_pos = (original_pos + a[i]) % 26
# 转换回字符
encrypted_char = chr(new_pos + ord('a'))
encrypted.append(encrypted_char)
# 输出结果
print(''.join(encrypted))
代码解析
2.1 生成偏移数组 a
- 边界处理:当字符串长度小于3时,仅填充有效的前几个元素。
if m >= 1: a.append(1) if m >= 2: a.append(2) if m >= 3: a.append(4)
- 递推优化:每次计算新偏移量时对26取模。
next_val = (a[i-1] + a[i-2] + a[i-3]) % 26
2.2 字符偏移转换
- ASCII转换:
ord('a')
返回字母a
的ASCII码(97)。chr(97)
返回ASCII码对应的字符(a
)。
- 循环处理:
new_pos = (original_pos + a[i]) % 26
3. 复杂度分析
- 时间复杂度:O(n * m)
- 外层循环处理
n
组测试数据。 - 内层生成偏移数组和字符转换的时间复杂度为 O(m)。
- 外层循环处理
- 空间复杂度:O(m)
- 存储偏移数组
a
和加密结果。
- 存储偏移数组
4. 优化与扩展
4.1 预计算偏移数组
- 若多组测试数据中字符串长度较大,可预先生成长度固定的偏移数组缓存,避免重复计算。
4.2 大数处理的数学依据
- 由于
a[i]
的偏移量对26取模,递推公式可简化为:a[i] = (a[i-1] + a[i-2] + a[i-3]) % 26
- 该优化使得即使
i
很大时,计算也不会溢出。
4.3 扩展功能
- 解密算法:逆向操作,将偏移量取反(即
new_pos = (original_pos - a[i]) % 26
)。
5. 测试与验证
测试用例1
- 输入:
1 xy
- 输出:
ya
- 解释:
x
→ 索引23 → 23 + 1 = 24 →y
y
→ 索引24 → 24 + 2 = 26 → 26 % 26 = 0 →a
测试用例2
- 输入:
2 abcde zzz
- 输出:
bdgkr cba
- 解释:
a
偏移1 →b
b
偏移2 →d
c
偏移4 →g
d
偏移7 →k
(3 + 7 = 10 → 'k'
)e
偏移13 →r
(4 + 13 = 17 → 'r'
)zzz
偏移量为1,2,4
→ 依次变为c, b, a
。
6. 总结
通过动态规划生成偏移数组,并结合模运算处理字符循环,本方法能够高效解决字符串加密问题。代码实现中,通过逐层分解问题、边界条件处理和数学优化,确保了算法的正确性和性能。此思路还可扩展至其他需要周期性偏移的场景(如凯撒密码变种)。