挤表:同一行重叠在一起,并计数
squeeze table: same row overlap together, and count the number
假设我有一个这样的表:(表是c++中的二维数组)Number是每行的计数。
1 a b c
1 a b c
1 c d e
1 b c d
1 b c d
2 a b c
1 c d e
2 b c d
我的算法是O(n*n),有人能改进吗?
suppose t1 is original one;
initial another t2;
row_num = 1;
copy first row of t1 to t2;
foreach row in t1 (1 to n)
search each row in t2 (0 to row_num);
if equal, then add the number;
break;
if not found, then copy current t1's row to t2;
row_num++
如果您的数据像示例中那样排序,那么它只是O(n)。
使用std::sort(或任何其他O(nlogn)排序)对数组排序。然后它只是另一个传递,并完成:)
这是O(N log N)
复杂度的一个工作示例。它首先对数据进行排序,然后循环遍历每个元素,并通过查找第一个不匹配来计算出现的次数,然后将当前元素的计数总和存储在结果向量中。注意,在初始数组中也可以有不同于1的计数。该代码无需指定特定的比较函数就可以工作,因为std::array
已经有了字典表operator<
。
下面的代码使用了c++ 11的特性(auto, lambda),这些特性可能在你的编译器上不起作用。您也可以使用初始化列表在一条语句中初始化vector,但是对于int和array对的嵌套vector,我有点困惑需要写多少大括号:-)
#include <algorithm>
#include <array>
#include <iostream>
#include <utility>
#include <vector>
typedef std::pair<int, std::array<char, 3> > Element;
std::vector< Element > v;
std::vector< Element > result;
int main()
{
v.push_back( Element(1, std::array<char, 3>{{'a', 'b', 'c'}}) );
v.push_back( Element(2, std::array<char, 3>{{'a', 'b', 'c'}}) );
v.push_back( Element(1, std::array<char, 3>{{'c', 'd', 'e'}}) );
v.push_back( Element(1, std::array<char, 3>{{'b', 'c', 'd'}}) );
v.push_back( Element(3, std::array<char, 3>{{'b', 'c', 'd'}}) );
// O(N log(N) ) complexity
std::sort(v.begin(), v.end(), [](Element const& e1, Element const& e2){
// compare the array part of the pair<int, array>
return e1.second < e2.second;
});
// O(N) complexity
for (auto it = v.begin(); it != v.end();) {
// find next element
auto last = std::find_if(it, v.end(), [=](Element const& elem){
return it->second != elem.second;
});
// accumulate the counts
auto count = std::accumulate(it, last, 0, [](int sub, Element const& elem) {
return sub + elem.first;
});
// store count in result
result.push_back( Element(count, it->second) );
it = last;
}
for (auto it = result.begin(); it != result.end(); ++it) {
std::cout << it->first << " ";
for (std::size_t i = 0; i < 3; ++i)
std::cout << it->second[i] << " ";
std::cout << "n";
}
}
Ideone上的输出
注意:在排序元素上的循环可能看起来像O(N^2)
(线性std::find_if
嵌套在线性for
中),但它是O(N)
,因为最后一个循环语句it = last
跳过了已经搜索的元素。
相关文章:
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 将图形属性与 std::unique_ptr 捆绑在一起
- 你能在 c++ 中将不同的数字类型加在一起吗?
- 如何将两个字符串加在一起,就好像它们是变量一样?
- 当返回语句时,逗号运算符、大括号初始化列表和 std::unique_ptr 组合在一起
- 为什么push_back和emplace_back结合在一起时,会有不同的行为
- 在浮点精度成为一个问题之前,可以将多少个浮点值加在一起
- 为什么在template函数广播中把两个extensor表达式加在一起不正确
- 实现具有浮点键的类似哈希表的数据结构,其中公差内的值被合并在一起
- 如何在Qt TableView中将列的宽度调整为数据并将最后一部分拉伸在一起
- 编译器如何将链表中的地址字符串在一起?
- 在 c++ 中,两个日志行与 log4Cxx 混合在一起
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 将许多向量排序在一起
- C++ std:: 并包括它们如何组合在一起?
- 通过字符串迭代并将每个循环中的先前字符组合在一起
- CMake 项目结构:如何正确地将库合并在一起并将它们包含在多个可执行文件中
- C 操作员超载将3个向量加在一起
- 有没有一种干净(更)的方法将 CRTP 与可变参数继承混合在一起?
- 挤表:同一行重叠在一起,并计数