【问题标题】:Add spaces between words in spaceless string在无空格字符串中的单词之间添加空格
【发布时间】:2011-04-28 09:24:56
【问题描述】:

我在 OS X 上,在 Objective-c 中我正在尝试转换

例如, “Bobateagreenapple”

进入 “鲍勃吃了一个青苹果”

有什么方法可以有效地做到这一点?涉及拼写检查器的东西会起作用吗?

编辑:只是一些额外的信息: 我正在尝试构建一些格式错误的文本(例如,从最终没有空格的旧 pdf 粘贴的文本副本,尤其是来自 JSTOR 等互联网档案)。由于格式错误的文本可能会很长......好吧,我只是想弄清楚这是否可行,然后我才真正尝试实际编写系统,却发现修复一段文本需要 2 小时.

【问题讨论】:

  • +1 非常有趣的问题。我很高兴看到解决方案,尽管我想不出一个。可以考虑的唯一方法是简单地遍历所有字母并在将其作为一个完整单词与字典进行比较时将其切掉......尽管这种方法很快就会失败。
  • 这也可以解释为(当然是荒谬的)“鲍勃茶青苹果”。
  • @Ferruccio :您已经证明了为什么这会充满麻烦......而这只是在这个问题中发布的示例文本。现实生活中会有确实有意义的例子,但仍然是错误的。
  • @Ferruccio: +1 在我写之前偷了我的例子>:(
  • 正文有标点符号吗?显然这让它变得容易多了,因为您可以分别处理每个句子(片段)。

标签: objective-c string nsstring


【解决方案1】:

我将以非操作系统特定的方式对此进行描述的一种可能性是对构成字母集合的所有可能的单词进行搜索。

基本上,您将字母集的第一个字母切掉并将其添加到您正在形成的当前单词中。如果它生成一个单词(例如字典查找),则将其添加到当前句子中。如果您设法用完集合中的所有字母并用所有字母组成单词,那么您就有了一个完整的句子。但是,你不必停在这里。相反,你继续运行,最终你会产生所有可能的句子。

伪代码看起来像这样:

FindWords(vector<Sentence> sentences, Sentence s, Word w, Letters l)
{
    if (l.empty() and w.empty())
        add s to sentences;
        return;
    if (l.empty())
        return;
    add first letter from l to w;
    if w in dictionary
    {
        add w to s;
        FindWords(sentences, s, empty word, l)
        remove w from s
    }
    FindWords(sentences, s, w, l)
    put last letter from w back onto l
}

当然,您可以执行许多优化以使其快速运行。例如检查单词是否是字典中任何单词的词干。但是,这是给出所有可能句子的基本方法。

【讨论】:

    【解决方案2】:

    解决这个问题比你在框架中找到的任何东西都要困难得多。请注意,即使在您的示例中,还有其他“解决方案”:“Bob 一个茶青苹果”。

    一种非常幼稚(而且不是很实用)的方法可能是使用拼写检查器尝试在字符串中一次隔离一个“真实单词”;当然,在这个例子中,这只是因为“Bob”恰好是一个英文单词。

    这并不是说没有办法实现你想要的,但你表达这个问题的方式向我表明它可能比你所期望的要复杂得多。也许有人可以给你一个可接受的解决方案,但我敢打赌,他们需要更多地了解你到底想要做什么。

    编辑:为了响应您的编辑,在 PDF 上运行某种 OCR 工具并更正其输出可能比仅仅纠正该系统可能给您的内容(更不用说对其进行编程)花费更少的精力

    【讨论】:

    • 它也可能是“波巴茶……”,这是一种相当受欢迎的饮料,确实有苹果口味,因此即使是对短语出现的频率以及在什么情况下可能会被抛弃的复杂分析.
    【解决方案3】:

    我实现了一个解决方案,代码在代码项目中可用:

    http://www.codeproject.com/Tips/704003/How-to-add-spaces-between-spaceless-strings

    我的想法是优先考虑用尽大部分字符(最好是所有字符)的结果,然后优先考虑那些单词最长的结果,因为 2,3 或 4 个字符长的单词经常会从遗漏的字符中偶然出现。大多数情况下,这提供了正确的解决方案。

    为了找到所有可能的排列,我使用了递归。即使使用大字典(用 50 000 个单词测试),代码也相当快。

    【讨论】:

    • 我们的社区不欢迎仅链接的答案。请在此处添加相关代码