这实际上是一个有趣的益智程序。
这是一个用 C# 编写的答案。转换为 C++ 是一个练习!有 2 个递归函数,一个用于计算扩展字符串的长度,另一个用于查找给定字符串的第 k 个字符。它向后工作,从右到左,一次剥离一个字符。
using System;
using System.Collections.Generic;
using System.Text;
namespace expander
{
class Program
{
static void Main(string[] args)
{
string y = "AB2C3";
Console.WriteLine("length of expanded = {0} {1}", y, length(y));
for(uint k=0;k<length(y);k++)
{
Console.WriteLine("found {0} = {1}",k,find(k,y));
}
}
static char find(uint k, string s)
{
string left = s.Substring(0, s.Length - 1);
char last = s[s.Length - 1];
uint len = length(left);
if (last >= '0' && last <= '9')
{
if (k > Convert.ToInt32(last -'0') * len) throw new Exception("k out of range");
uint r = k % len;
return find(r, left );
}
if (k < len) return find(k, left);
else if (k == len) return last;
else throw new Exception("k out of range");
}
static uint length(string s)
{
if (s.Length == 0) return 0;
char x = s[s.Length - 1];
uint len = length(s.Substring(0, s.Length - 1));
if (x >= '0' && x <= '9')
{
return Convert.ToUInt32(x - '0') * len;
}
else
{
return 1 + len;
}
}
}
}
这是示例输出,它表明如果您遍历 k 的所有有效值(0 到 len-1),find 函数会复制扩展。
length of expanded AB2C3 is 15
if k=0, the character is A
if k=1, the character is B
if k=2, the character is A
if k=3, the character is B
if k=4, the character is C
if k=5, the character is A
if k=6, the character is B
if k=7, the character is A
if k=8, the character is B
if k=9, the character is C
if k=10, the character is A
if k=11, the character is B
if k=12, the character is A
if k=13, the character is B
if k=14, the character is C
此程序的内存使用仅限于堆栈使用。堆栈深度将等于字符串的长度。在这个 C# 程序中,我一遍又一遍地复制字符串,这样会浪费内存。但即使管理不善,它也应该使用 O(N^2) 内存,其中 N 是字符串的长度。实际扩展的字符串可以长得多。比如“AB2C999999”只有N=10,所以应该使用O(100)个内存元素,但是展开后的字符串超过200万个字符。