反转字符数组中单词的顺序
Posted
技术标签:
【中文标题】反转字符数组中单词的顺序【英文标题】:Reversing the order of words in a character array 【发布时间】:2013-07-11 13:39:00 【问题描述】:问题是特殊字符的位置(例如:'?'、','、''、'.')应该保持不变。所以对于输入字符串“Hello World,你好吗?”输出将是“你是,你好吗?世界你好?”。现在对于没有特殊字符的字符串,O(n) 算法是将每个单词反转然后反转整个数组,但这并没有考虑特殊字符。
我想出的最佳算法如下。我们遍历数组并将每个单词压入堆栈顶部,然后将特殊字符排入队列。然后,我们同时从堆栈和队列中弹出元素,并将它们组合起来形成所需的输出。
是否有就地 O(n) 算法?如果没有,您能否建议一个没有额外空间的 O(n^2) 算法。还假设,您不能使用任何字符串库函数。
【问题讨论】:
reverse a string word by word的可能重复 请查看:***.com/questions/12879348/… 正在使用 std::string (仅用于字符串表示)和 std::istream 好吗? 你的算法是 O(n) OP 正在寻找合适的算法。 【参考方案1】:所以,这是一个想法。
1) 初始字符串
"Hello World, how are you?"
2) 反转字符串,但不包含任何最后的特殊字符
"uoy era woh ,dlroW olleH?"
3) 反转字符串中的单词
"you are how ,World Hello?"
4) 为字符串的开头和结尾创建一个迭代器(指针、索引,无论您使用什么),递增/递减每个迭代器,直到它们碰到非单词。非单词是指空格或特殊字符。所以在这种情况下,递增的迭代器首先会遇到“you”和“are”之间的空白,而递减的迭代器会遇到“world”和“Hello”之间的空白,如下所示。
"you are how ,World Hello?"
^ ^
5) 如果没有特殊字符,则继续,但如果您遇到特殊字符。反转迭代器之间的所有内容,包括它们指向的字符。下面显示了这种情况发生的时间
"you are how ,World Hello?"
^ ^
6) 现在我们看到了反转的结果。
"you are, woh World Hello?"
根据 johnchen902 的评论进行编辑
7) 现在在这些迭代器之间反转子字符串,不包括在步骤 (5) 中找到的特殊字符。
"you are, how World Hello?"
8) 返回步骤 (5)。
我还没有编写代码,解释起来有点棘手,但我希望你能理解
【讨论】:
不适用于A,B,C D E
。建议的修复:(7) 反转迭代器之间的 子字符串,不包括 (5) 中找到的特殊字符。 (8) 转到 (5)
很好,johnchen902,我认为现在应该可以了。我想我原来的解决方案只适用于奇数个特殊字符。我将编辑我的帖子以包含您的建议
你能检查测试用例“Hello World,你好吗?”在我看来,该算法可能不起作用。 (请注意逗号前后都有一个空格)考虑多个特殊字符同时出现的测试用例。
您好,用户。所以我没有对此进行编码,但我确实把它草草写了下来,然后我得到了“你是,你好,世界怎么样?” 'How' 和 'World' 之间有 2 个空格,尽管我想你希望得到“You Are , How World Hello?”你是吗?如果不是,也许需要更明确的规则。您可以修改步骤 4-5,以便迭代器在到达后面没有字母的空格时停止。当你坐下来开始考虑这些案件时,这是一个有点棘手的小难题,但我认为基础在这里。
为什么字符串 " are how, World " 没有反转?这是算法遇到特殊字符的第一个实例。一旦我清除了所有的疑虑,我会试运行算法并很快开始真正编码。【参考方案2】:
对于就地算法,只需创建两个迭代器(对单词进行迭代),一个反向迭代器,另一个向前迭代。
您的循环将仅包含以下内容:
while(FirstIteratorIsBefore(forward_iterator, backward_iterator))
if(IsSpecialCharacter(*forward_iterator))
++forward_iterator;
else if(IsSpecialCharacter(*backward_iterator))
++backward_iterator;
else
// Swap the two
Swap(forward_iterator, backward_iterator);
++forward_iterator;
++backward_iterator;
注意:您必须创建自己的简单单词迭代器才能使此逻辑正常工作,但这很容易实现。
【讨论】:
您无法比较不同类别的迭代器(至少不符合标准的迭代器)。 感谢@jrok,我已经更新了代码以反映这一点。请注意,由于这些是您自己的迭代器,您的 FirstIteratorIsBefore 只是检查它正在迭代的原始字符串中的位置。 鉴于这是给出解决方案的唯一答案,否决投票者能否解释一下? 抱歉,我无法按照您的代码进行操作。可以给我解释一下吗? @user2560730 我现在正要离开,但请阅读有关矢量和地图之类的 stl 迭代器的信息。此解决方案使用迭代器的概念。您需要在 Swap() 中做一些工作,以便能够处理不同大小的单词,其中文本必须移动到位并且迭代器内的内部位置也需要更改。以上是关于反转字符数组中单词的顺序的主要内容,如果未能解决你的问题,请参考以下文章