如何将其用于x个数字?对于我的方法,其硬编码为2个子字符串。还有一种更好的方法,可以减少时间复杂度吗?由于我根本不使用um参数,因此此处可能存在一个漏洞,该漏洞需要确定通过的num im数量。
答案 0 :(得分:1)
您当前的方法存在一些问题,包括硬编码的最大ngram数和固定的ngram大小。此外,您的变量名简短且缺少注释,无助于向正在阅读代码的人解释该代码。
一个更简单的解决方案是使用map
来计数每个ngram的出现次数,然后找到计数最高的那个。这会给N.logN
带来麻烦的时间复杂性。另外,unordered_map
将更接近线性时间复杂度。
当然会有一个极端情况,即一个以上的ngram出现相同的最高计数。您将需要决定使用各种策略中的哪一种来解决该问题。在我的示例中,我利用std::map
的固有顺序来选择排序顺序最低的ngram。如果使用unordered_map
,则需要采用其他策略来确定性地解决争用。
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
std::string ngram(const std::string &input, int num)
{
if (num <= 0 || num > input.size()) return "";
// Count ngrams of size 'num'
std::map<std::string, int> ngram_count;
for(size_t i = 0; i <= input.size() - num; i++)
{
++ngram_count[input.substr(i, num)];
}
// Select ngram with highest count
std::map<std::string, int>::iterator highest = std::max_element(
ngram_count.begin(), ngram_count.end(),
[](const std::pair<std::string, int>& a, const std::pair<std::string, int>& b)
{
return a.second < b.second;
});
// Return ngram with highest count, otherwise empty string
return highest != ngram_count.end() ? highest->first : "";
}
int main()
{
std::cout << ngram("engineering", 2) << std::endl;
std::cout << ngram("engineering", 3) << std::endl;
return 0;
}
答案 1 :(得分:0)
我所做的与稻田略有不同,所以我想将其发布。使用std::set
。他解释了这个问题,因此应得到您的答复。
struct test {
test(const std::string& str) :val(str), cnt(0) {}
test(const test& thet) { *this = thet; }
std::string val;
int cnt;
friend bool operator < (const test& a, const test& b) { return a.val < b.val; }
};
using test_set_type = std::set<test>;
const test ngram(std::string A, int num) {
test_set_type set;
for (auto it = A.begin(); it < A.end() - num + 1; ++it)
{
auto found = set.find(std::string(it, it + num));
if (found != set.end())
++const_cast<test&>(*found).cnt;
else
set.insert(std::string(it, it + num));
}
int find = -1;
test_set_type::iterator high = set.begin();
for (auto it = set.begin(); it != set.end(); ++it)
if(it->cnt > find)
++find, high= it;
return *high;
}
int main() {
int num = 2;
std::string word("engineering");
std::cout << ngram(word, num).val << std::endl;
return 0;
}