- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在编写一个程序,它将根据某些特定规则对输入文本进行标记。我为此使用 C++。
规则
Letter 'a' should be converted to token 'V-A'
Letter 'p' should be converted to token 'C-PA'
Letter 'pp' should be converted to token 'C-PPA'
Letter 'u' should be converted to token 'V-U'
这只是一个示例,实时我有大约 500 多个这样的规则。如果我以“appu”的形式提供输入,它应该像“V-A + C-PPA + V-U”一样进行标记化。我已经实现了执行此操作的算法,并希望确保我做的是正确的事情。
算法
所有规则都将保存在一个 XML 文件中,并带有相应的 token 映射。有点像
<rules>
<rule pattern="a" token="V-A" />
<rule pattern="p" token="C-PA" />
<rule pattern="pp" token="C-PPA" />
<rule pattern="u" token="V-U" />
</rules>
1 - 当应用程序启动时,读取此 xml 文件并将值保存在“std::map”中。这将一直可用到应用程序结束(单例模式实现)。
2 - 迭代输入文本字符。对于每个字符,寻找一个匹配项。如果找到,则变得更加贪婪并通过从输入文本中获取下一个字符来寻找更多匹配项。这样做直到我们得到一个不匹配。因此,对于输入文本“appu”,首先查找“a”的匹配项。如果找到,尝试通过从输入文本中获取下一个字符来获得更多匹配。所以它会尝试匹配 'ap' 但没有找到匹配项。所以它只是返回。
3 - 替换输入文本中的字母“a”,因为我们得到了它的标记。
4 - 对输入文本中的剩余字符重复步骤 2 和 3。
下面是更简单的步骤说明
input-text = 'appu'
tokens-generated=''
// First iteration
character-to-match = 'a'
pattern-found = true
// since pattern found, going recursive and check for more matches
character-to-match = 'ap'
pattern-found = false
tokens-generated = 'V-A'
// since no match found for 'ap', taking the first success and replacing it from input text
input-text = 'ppu'
// second iteration
character-to-match = 'p'
pattern-found = true
// since pattern found, going recursive and check for more matches
character-to-match = 'pp'
pattern-found = true
// since pattern found, going recursive and check for more matches
character-to-match = 'ppu'
pattern-found = false
tokens-generated = 'V-A + C-PPA'
// since no match found for 'ppu', taking the first success and replacing it from input text
input-text = 'u'
// third iteration
character-to-match = 'u'
pattern-found = true
tokens-generated = 'V-A + C-PPA + V-U' // we'r done!
问题
1 - 这个算法看起来是否适合这个问题,或者是否有更好的方法来解决这个问题?
2 - 如果这是正确的方法,std::map 是一个不错的选择吗?还是我需要创建自己的键/值容器?
3 - 是否有可用的库可以像上面那样标记字符串?
任何帮助将不胜感激
:)
最佳答案
所以您要遍历 map 中的所有标记以寻找匹配项?您也可以在那里使用列表或数组;无论如何,这将是一个低效的搜索。
找到适合开始或继续比赛的 token 的更有效方法是将它们存储为 trie .在那里查找一个字母会给你一个子树,它只包含以那个字母为第一个字母的标记,然后你就可以继续向下搜索,直到你可以去。
编辑:让我进一步解释一下。
首先,我应该解释一下,除了名称之外,我对 C++ std::map
不熟悉,这使得这是一个完美的例子,说明为什么人们将这些东西的理论学习为以及特定编程语言中特定库的详细信息:除非该库严重滥用名称“map”(这不太可能),否则名称本身告诉我很多关于数据结构的特征。例如,我知道会有一个函数,给定一个键和 map ,将非常有效地搜索并返回与该键关联的值,并且可能还有一个函数会为您提供一个列表/array/所有键中的任何一个,您可以使用自己的代码自行搜索。
我对你的数据结构的解释是你有一个映射,其中的键是你所说的模式,那些是字符列表(或数组,或类似性质的东西),值是标记。因此,您可以在给定完整模式的情况下快速找到与其关联的标记。
不幸的是,虽然这样的映射非常适合将您的 XML 输入格式转换为内部数据结构,但它不太适合您需要进行的搜索。请注意,您不是查找整个模式,而是查找模式的第一个字符,生成一组可能的标记,然后从第一个生成的模式集中查找模式的第二个字符 查找,等等。
因此,您真正需要的不是单个 map ,而是 map 的 map ,每个 map 都由一个字符键入。在顶层查找“p”应该会为您提供一个新 map ,其中包含两个键:p
,生成 C-PPA
token ,以及“其他任何东西”,生成 C-PA
token 。这实际上是一个 trie 数据结构。
这有意义吗?
如果您首先以这种方式编写解析代码,这可能会有所帮助:想象一下其他人将编写函数来执行您需要的查找,并且他是一个非常优秀的程序员并且几乎可以完成您的任何魔术想。编写解析代码,集中精力使其尽可能简单和干净,使用您需要的这些任意函数创建任何界面(同时不要变得微不足道并用一个函数替换整个东西!)。现在您可以查看最终得到的查找函数,它告诉您需要如何访问您的数据结构,这将引导您找到所需的数据结构类型。一旦你弄明白了,你就可以弄清楚如何加载它。
关于c++ - 根据某些特定规则对文本进行标记。 C++中的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/903133/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!