【发布时间】:2017-05-17 08:03:49
【问题描述】:
有一个词,我希望它变成这样:
奇迹 => Iraclemend.
基本上是把第一个字母加到最后,然后加上end。
但是特殊字符必须从词尾开始保持在同一个位置,所以
Britne's => Ritnesben'd
' 距离末尾 2 个位置,因此它必须位于转换后的字符串从末尾开始的第二个位置,这也适用于大写(但从字符串的开头)所以
McBeth => CbEthmend
我的解决方法如下:
1) 遍历单词并检测大写和特殊字符, 如果是 UpperCase ,则将字符的索引推入 UpperCases 的数组中 它的特殊字符将字符和索引推入 specialchars 数组, 如果它上面什么都没有,只是将字符附加到字符串(如果它的大写附加它的小写变体)
所以 Britne's 会在第一步之后变成 Britnes。在特殊字符 arr 中使用索引 2 和字符“'”(从单词末尾开始)
2) 将字符串转换成 ritnesbend
3) 从 0 循环到 word 的长度,每次迭代检查该索引是否与 specialchars 或大写数组中的索引匹配。如果匹配特殊字符添加特殊字符+下一个字符,如果匹配upperCases添加大写版本的字符。
这在O(2k) = O(k) 中运行,其中 k = 单词的长度。
对字符串转换算法没有太多经验,有没有更快的解决方案?
伪代码
function detetectChars ( word , object )
for i... word.length
if word[i] is spececial
object.specials.add( char: word[i] , index:i )
if word[i] is upperCase
object.upper.add(i)
function addSpecials ( word , object )
upperIndex = 0;
specialIndex = 0;
transformed = "";
for i... word.length
if i == object.upper[ upperIndex ]
transformed += word[i].toUpper(); upperIndex++;
if i == object.special[ specialIndex ]
transformed += object.special[ specialIndex++ ] + word[i]
else
transformed += word[i]
return transformed
感谢您的建议。
【问题讨论】:
-
我的错字,谢谢指出
-
"该解决方案应该用 javascript 或 c++ 实现" - 选择 一个,或者只是省略两者以支持可选的pseudocode,因为其中没有代码问题。
-
比 O(k) 做得更好意味着你设法避免甚至需要查看每个字符。很容易看出这是不可能的,因为您至少需要检查每个字符以查看它是否是特殊字符。除非输入中的大多数字符不需要更改或移动,否则您也永远不会比 O(输出大小)更快,除非您将字符串表示为循环缓冲区,否则情况并非如此。
-
@Dukeling 添加伪代码
-
A circular buffer 可以表示为具有起始索引和结束索引的固定大小数组,并带有环绕。如果您以这种方式表示字符串(我所知道的任何语言都没有这样做),您可以将第一个字符移动到末尾并在恒定时间内添加“end”(如果数组足够大),但如果存在则这不起作用是字符串中间的特殊字符或大写字母,您仍然无法绕过需要查找。