C ++中(整个)单词的拆分

Posted

技术标签:

【中文标题】C ++中(整个)单词的拆分【英文标题】:Splits of (entire) words in C++ 【发布时间】:2015-12-15 10:56:48 【问题描述】:

假设我们有一个文本必须由一组工作人员(map/reduce 项目中的映射器)处理:文本的每个部分(拆分)必须是一致的(没有一个词可以在两个之间拆分worker),并且拆分的大小应尽可能相等(负载平衡)。

这是我的算法:

    将文本分成等份,每份由off_t beginoff_t end(文本中的开始和结束字节)组成。 使每个拆分保持一致:如果拆分在单词中间结束,则跳转到下一个空格(并对开头执行相同操作)。如果没有这个阶段,结果可能是错误的:想想 map/reduce 中著名的“字数统计”示例。

输入(文本长度 = 29 个字符):

Hello Darkness my old friend

第 1 阶段有 4 个工人(~= 每个工人 7 个字符):

|Hello D|arkness| my old| friend|

第 2 阶段:

|Hello Darkness| |my old |friend|

这是每个拆分阶段 2 的代码:

        ifstream ifs (file , ifstream::in);
        char c;
        string s;
        if(begin>0)//begin=0 then first split: cannot break a word!
            //if char before the first one is different from ' ' or '\n'
            //then the split begins in the middle of a word (bad)
            ifs.seekg(begin-1,ios::beg);
            ifs.get(c);
            if(c!=' ' && c!='\n')
                getline(ifs,s,' '); //jump to the next white space
                begin+=s.length();
            
            if(begin>end)
                end=begin;
        
        ifs.seekg(end,ios::beg);
        ifs.get(c);
        if(c!=' ' && c!='\n' && end != size)
            getline(ifs,s,' ');
            end+=s.length();
        

如你所见,这个解决方案有两个问题:

    拆分大小可能不平衡(查看第一个拆分和第二个拆分!) 代码有点棘手

您对改进解决方案有什么建议(在优雅和/或性能方面)?

【问题讨论】:

这里有一个镜头:在那一刻完全忘记第 2 阶段!我解释:只需分成相等的部分,处理所有这些部分,然后在第三阶段,检查单词是否损坏,并将一个工人的最后一个与下一个工人的第一个结合起来。此外,为了在第三阶段提供帮助,工作人员可以记录他们是否已经开始/结束了空间 不能那样做!正如您在更新中看到的,工作人员是 Map/Reduce 项目中的映射器。如果您知道著名的“字数统计”示例,那么您就知道不能在两个工人之间拆分一个单词!无论如何,我缺乏问题描述,对此感到抱歉! 如果我说您只是在尝试进行多线程字数统计,我会不会错。或类似的东西,也许将 fstream 转换为单词向量。工作人员是否也像传统的多线程情况一样共享内存,还是您要部署到机器集群??? 【参考方案1】:

我认为从算法上讲,你不能做得更好(如果你在做 Map|Reduce,你大概有 很多 数据,所以差异会很小)。将拆分安排为Hello| Darkness| my old| friend 的工作量太大了。

可能会有轻微的改进:

估计第一次拆分的位置(在本例中为字符 7) 读一读。 向前向后寻找最近的空间。 就此分开。 如果您已经搜索过,那么您已经掌握了下一个块的开始。 更新您对下一个块应该多长时间的估计。 循环

唯一的麻烦是这会使代码变得更加复杂。

【讨论】:

这个解决方案还有一个问题:它在迭代之间引入了一个状态,这意味着没有“并行循环”(迭代的结果取决于前一个)。顺便说一句,感谢您的回答,这对串行执行很有好处!【参考方案2】:

您也可以向后检查并使用字符较少的一侧直到空格。然而,这将导致额外的复杂性。对于这种简单的情况,这无关紧要,因为我希望如此小的零件会被处理得如此之快,以至于不会有任何明显的差异。

随着拆分大小的增加(比如 500 个字符甚至 1 MB),如果单词保持相对较短,不平衡将变得越来越不重要 - 所以我也不会打扰,我会“继续很简单,愚蠢”(KISS)。

【讨论】:

以上是关于C ++中(整个)单词的拆分的主要内容,如果未能解决你的问题,请参考以下文章

在c ++中将单词拆分为字母? [关闭]

在 Embarcadero 的 C++ Builder 中使用 RegEx 将文本拆分为单个单词

如何在C ++中突出显示整个单词?

使用C读取并保存txt文件的每个单词?

单词拆分

Leetcode No.140 单词拆分 II(DFS)