寻找真实单词的回文

时间:2011-12-09 18:35:52

标签: algorithm

我刚刚阅读了问题Anagram of a Palindrome,这引出了一些其他的回文问题。但是,当我想到一个回文时,我会想到现实世界的回文,它们使用一种语言中的真实词汇,并在那种语言中有一定程度的意义。

那么,如果我们放弃语法和意义太难,我们是一个很好的算法来找到由字典中的单词组成的回文?您可以将字典预处理为数据结构,使其更容易。你不能通过找到每个可能的回文来预处理字典,除非你有办法在一定的计算时间和空间内做到这一点。

假设您要查找最多100,000个字符的回文,并且您有一个包含100,000个小写英文单词的字典。

如果您能想出一种快速找到回文标记的方法,那么可以获得积分。我不确定是否有可行的方法。

编辑 - 似乎有些混乱,所以我一定不够清楚。我正在寻找单词序列(长达100,000个字符),这些单词是回文,而不是单个字典单词,这是一个微不足道的问题。因此,任何数量的“a”或“i”都是palindroms,因为每个都是单词而序列是回文。 “amanaplanacanalpanama”也是一个回文,因为“a”,“man”,“plan”,“canal”和“panama”都是单词(如果“panama”真的在这本词典中)

2 个答案:

答案 0 :(得分:0)

在C#中我会使用LINQ来转换给定的字符串......

public bool isPalindrome(string str){
    var rev= new string(Enumerable.Range(1, str.Length).Select(i => str[str.Length - i]).ToArray());
    return String.Compare(str, rev, true);
}

这部分很容易,但如果要攻击100,000个字符长度,则会对性能进行一些调整。有人可能会将琴弦切成两半并翻转后半部分以加快翻转过程并缩短比较琴弦。

从那里,我将每个发现的回文转储到IEnumerable集合中,并根据预定义的字典对它们进行测试......再次,我没有解决的关键是性能。

编辑:更好的效果选项(归功于http://www.softwareandfinance.com/CSharp/Palindrome.html

static bool IsPalindrome(string s)
{
    bool palindrome = true;
    for (int i = 0; i < s.Length / 2 + 1; i++)
    {
        if (s[i] != s[s.Length - i-1])
        {
            palindrome = false;
            break;
        }
    }
    return palindrome;
}

这种方法假设这个词是回文(可能是危险的),但比较字母到字母的字母直到没有匹配。奇怪的字母词被照顾。在我上面的方法中,为了比较苹果和苹果,你必须抓住一半+ 1。

那你在找什么?

答案 1 :(得分:0)

我在想,如果我真的想在运行时以牺牲一些工作为代价来有效地检查字典,那么我将构建一个状态机来检查字典中是否有一系列字母。我可以通过阅读每个字典条目来构建它,然后逐字母创建一个新的状态,如果一个不存在。

因此,如果字典中的第一个单词是“a”,则在读取“a”时从开始状态变为“a”状态将是有效的过渡。如果下一个单词是“ax”,我将在“x”上创建从“a”到“ax”的转换,并在“e”上创建从“ax”到“ax”的转换。 “a”和“ax”状态是接受状态,但不是“ax”。

这将是一个非确定性的状态机,允许从任何接受到开始状态的转换(因为在读取“ax”之后我可能读取“a”,而“axea”是完整字符串的语言可以在字典中找到的单词)。

然后我会使用众所周知的技术将状态机优化为确定性状态机(实际上使用其他人的代码,因为这段代码肯定写了1000多次)。

在运行时,我会通过状态机向前运行可能的回文,如果它向前传递,则向后运行。

我不知道什么是找到回文字符串的好方法。