交换单词的内部字母

时间:2012-09-01 11:13:19

标签: regex vb.net string linq scramble

如何实现拼写内部字母的“旧”技巧?

对于那些不了解它的人Wikipedia描述得很好。

正如对this question的评论中所提到的那样,在最初形式的模因中最初提到的“研究”中有一些research

2 个答案:

答案 0 :(得分:1)

我在VB的“一行”中实现了这个:

Dim outText = Regex.Replace(inText, _
        "\b([a-zA-z])([a-zA-Z]+)([a-zA-Z])\b", _
        Function(g) (g.Groups(1).Value & String.Join("", _
            (g.Groups(2).Value.ToCharArray.OrderBy( _
                            Function(c) (Rnd(1))) _
                            )) & _
            g.Groups(3).Value))

更好的解决方案会为Function提供一个'更正确'OrderBy,它会为字符串中的特定字符返回相同的值,但在这种情况下,只需设置{{1}种子会做(有些)可重复的结果。

(请注意,将Rnd设置为直接依赖于所提供的Function意味着所有内部字符都会根据某些随机顺序重新排序,因此所有内部重复字母始终在拼写单词中组合在一起。)

输出的一个例子:

  

(请注意,c的标准是dopednent uopn    所有inratnel cthcearras的Fictunon previodd mnaes都是roeerredd    aindorccg到smoe ronadm oidrreng,所以所有ietnnarl reteaepd    在srlmceabd wodrs中,过去的人们都是在这里玩耍的。)

答案 1 :(得分:1)

Mark Hurd的回答是有缺陷的。即使纠正了重复字母的问题,使用排序算法也不会产生有效结果。 //见http://okmij.org/ftp/Haskell/perfect-shuffle.txt

这是我的尝试,使用递归。非常简单易懂,但性能可以提高。显然它不使用regex,vb.net或linq(参见标签)。我把它留给读者。

Random _rng = new Random();

string Scramble(string text) {
  return String.Concat(text[0], Shuffle3(text.Substring(1, text.Length - 2)), text[text.Length - 1]);
}

string Shuffle3(string text) {
  return ShuffleStep(text, _rng.Next(text.Length));
}

string ShuffleStep(string text, int i) {
  return (text.Length == 1) ? text : text[i] + ShuffleStep(text.Remove(i, 1), _rng.Next(text.Length-1));
}