我需要的东西来表示对序列的序列,像这样:,我应该在C++中使用这个什么样的数据结构的
[((1,2) (1,3)) ((1,2) (1,4) (1,5))].
我还需要对的序列,自由追加到做一个序列对,像这样append.[((1 2)(3 4)) ((5 6))] = ((1 2)(3 4)(5 6)).
在C++中有没有什么可以让我操纵我的数据?
我需要的东西来表示对序列的序列,像这样:,我应该在C++中使用这个什么样的数据结构的
[((1,2) (1,3)) ((1,2) (1,4) (1,5))].
我还需要对的序列,自由追加到做一个序列对,像这样append.[((1 2)(3 4)) ((5 6))] = ((1 2)(3 4)(5 6)).
在C++中有没有什么可以让我操纵我的数据?
我需要的东西来表示对
有三个标准序列容器模板的序列的序列 - std::vector
,动态阵列; std::list
,一个双向链表;和std::deque
,这是一种阵列式的东西,可以在两端进行高效插入。 C++ 11还添加了std::forward_list
,一个单链表。 vector
通常是最好的选择,除非你有特别的使用模式推荐其他人之一。
有一个标准对模板std::pair
,它有两个任意类型的对象,称为first
和second
的成员。
所以你的结构可以表示为vector<vector<pair<int,int> > >
。
我还需要追加对的序列自由地做出对
的一个序列
有这样做的各种方法;一个是
#include <algorithm> // for std::copy
#include <iterator> // for std::back_inserter
#include <vector> // for std::vector
#include <utility> // for std::pair
typedef std::pair<int,int> pair;
typedef std::vector<pair> sequence;
typedef std::vector<sequence> seqseq;
sequence flatten(seqseq const & in) {
sequence out;
for (seqseq::const_iterator s = in.begin(); s != in.end(); ++s) {
std::copy(s->begin(), s->end(), std::back_inserter(out));
}
return out;
}
如果你的序列是非常长的,你不需要保留原始序列,它可能是更有效地使用链表,并通过拼接追加他们 - 这种移动大量元素从一个列表到另一个在固定时间内,无需将其复制:
#include <vector> // for std::vector
#include <list> // for std::list
#include <utility> // for std::pair
typedef std::pair<int,int> pair;
typedef std::list<pair> sequence;
typedef std::vector<sequence> seqseq;
sequence flatten(seqseq & in) {
sequence out;
for (seqseq::iterator s = in.begin(); s != in.end(); ++s) {
out.splice(out.end(), *s);
}
// The input only contains empty lists now - we might as well clean up
in.clear();
return out;
}
“矢量通常是最好的选择,除非你有特定的使用模式,推荐其中一个。” - 人们可以有效地争论“deque”通常是最好的选择,除非你有特别的用法推荐其他人之一。重要的是避免使用'list',之后就不会有大量的数据了;-) – 2012-02-23 09:41:35
这听起来像你可能需要对列出的对的列表,甚至一个列表,这取决于我如何解析:-)
您的要求,您可以看看std::queue
或std::deque
的名单方面,和std::pair
为对方面。按照链接了解详情。
作为一个起点,请参见下面的代码:
#include <iostream>
#include <queue>
#include <utility>
int main (void) {
std::queue <std::pair <int,int> > xyzzy = std::queue <std::pair <int,int> >();
std::pair <int,int> p1 = std::pair <int,int> (3, 9);
xyzzy.push (p1);
std::pair <int,int> p2 = xyzzy.front();
xyzzy.pop();
std::cout << p2.first << ' ' << p2.second << '\n';
return 0;
}
这就造成对整数的队列,推动一个上弹出它关闭 - 你真的需要front/pop
组合对于这一点,因为在queue::pop
简单删除最古老的元素,而不是返回它 - 为什么那些选择忽略几十年的惯例是超越我:-)
然后它打印出构成这对的两个整数。
这应该很有希望足以说明所有的操作和数据类型,你需要实现你的东西。
话虽如此,Mike Seymour在评论中提出了一个有效的观点。如果你的“列表”中需要非类队列行为,你应该选择一个向量而不是队列或双向队列。
向量允许您获取列表中的随机元素,而不仅仅是头部或尾部。
的缺点是,你可能会失去有效的排队能力,如果这一点很重要 - 有没有简单的方法在矢量前推的元素,只在结尾和从前方突然出现很可能是效率低下。这是可行的,但不可能是有效的,因为它不是什么载体设计为:
尽管如此,随机存取能力可能是值得的牺牲。
下面的代码演示了如何使用一个矢量,而不是一个队列,包括队列类似的行为,如果你需要它:
#include <iostream>
#include <vector>
#include <utility>
int main (void) {
std::pair <int,int> p1;
std::vector <std::pair <int,int> > xyzzy;
xyzzy = std::vector <std::pair <int,int> >();
for (int i = 0; i < 10; i++) {
p1 = std::pair <int,int> (i, i * i);
xyzzy.push_back (p1);
}
while (xyzzy.size() > 0) {
std::pair <int,int> p2 = xyzzy.at(0);
xyzzy.erase (xyzzy.begin());
std::cout << p2.first << ' ' << p2.second << '\n';
}
return 0;
}
与输出是:
0 0
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
试试这个:
std::vector<std::vector<std::pair<int, int> > >
您的任务最自然的数据结构应该是对列表的列表:即
#include <list>
#include <boost/assign/list_of.hpp>
#include <boost/assert.hpp>
int main_seq_assign(int, char **)
{
using namespace std;
using namespace boost::assign;
typedef pair<int, int> t_rec;
typedef list<t_rec> t_recs;
typedef list<t_recs> t_data;
t_recs a = list_of<t_rec>(1, 2) (1, 3),
b = list_of<t_rec>(1, 2) (1, 4) (1, 5);
t_data c = list_of<t_recs>(a)(b);
t_data d = list_of<t_recs>(list_of<t_rec>(1, 2) (1, 3))
(list_of<t_rec>(1, 2) (1, 4) (1, 5));
t_data e;
e.insert(e.end(), a);
e.insert(e.end(), b);
BOOST_ASSERT(c == d && c == e);
}
在您提供的第一个数据集中,它看起来像您有两个序列,是否正确? – 2012-02-23 07:27:46
你也说你想追加两个(或更多?)序列。你的意思是你想加入两个序列来做出更大的序列? – 2012-02-23 07:29:21
@freefallr:是的,是的 – Mark 2012-02-23 07:31:35