如何解析制表符分隔的数据文件并在 Perl 中对提取的数据进行分组?
我是 Perl 的新手。我需要解析制表符分隔的文本文件。例如:
From name To name Timestamp Interaction
a b Dec 2 06:40:23 IST 2000 comment
c d Dec 1 10:40:23 IST 2001 like
e a Dec 1 16:03:01 IST 2000 follow
b c Dec 2 07:50:29 IST 2002 share
a c Dec 2 08:50:29 IST 2001 comment
c a Dec 11 12:40:23 IST 2008 like
e c Dec 2 07:50:29 IST 2000 like
c b Dec 11 12:40:23 IST 2008 follow
b a Dec 2 08:50:29 IST 2001 share
解析后我需要根据用户交互创建组。在此示例中
a<->b
b<->a
c<->a
a<->c
b<->c
c<->b
,我们可以创建一个组。我们需要显示组列表。 我需要一些有关如何解析文件和表单组的指示?
编辑 约束->创建组至少需要 3 个用户。 交互只不过是两个用户之间进行的一些通信。无论哪种通信,
我的解决方法都是
我们消除用户之间的重复交互。例如“a<>b like”再次,如果存在“a<>b follow”,那么我们删除这一行。
创建二维数组来存储两个用户的交互,即
命名 abcd
发件人姓名
一个 X <> <> X b<> X<> X c<> <> XX d X<> XX
X=代表没有交互 <>= 表示交互
在这种方法中,我们从第一行开始,即“a”用户检查“b”。如果“a”与“b”交互,那么我们执行相反的操作,即“b”与“a”交互。对每列执行相同的步骤。
但这种方法取决于用户数量。如果有 1000 个用户,那么我们必须创建 1000 X 1000 矩阵。有没有其他方法可以解决这个问题
我添加了示例输入
a c Dec 2 06:40:23 IST 2000 comment
f g Dec 2 06:40:23 IST 2009 like
c a Dec 2 06:40:23 IST 2009 like
g h Dec 2 06:40:23 IST 2008 like
a d Dec 2 06:40:23 IST 2008 like
r t Dec 2 06:40:23 IST 2007 share
d a Dec 2 06:40:23 IST 2007 share
t u Dec 2 06:40:23 IST 2006 follow
a e Dec 2 06:40:23 IST 2006 follow
k l Dec 2 06:40:23 IST 2009 like
e a Dec 2 06:40:23 IST 2009 like
j k Dec 2 06:40:23 IST 2003 like
c d Dec 2 06:40:23 IST 2003 like
l j Dec 2 06:40:23 IST 2002 like
d c Dec 2 06:40:23 IST 2002 like
m n Dec 2 06:40:23 IST 2005 like
c e Dec 2 06:40:23 IST 2005 like
m l Dec 2 06:40:23 IST 2011 like
e c Dec 2 06:40:23 IST 2011 like
h j Dec 2 06:40:23 IST 2010 like
d e Dec 2 06:40:23 IST 2010 like
o p Dec 2 06:40:23 IST 2009 like
e d Dec 2 06:40:23 IST 2009 like
p q Dec 2 06:40:23 IST 2000 comment
q p Dec 2 06:40:23 IST 2009 like
a p Dec 2 06:40:23 IST 2008 like
p a Dec 2 06:40:23 IST 2007 share
l p Dec 2 06:40:23 IST 2003 like
j l Dec 2 06:40:23 IST 2002 like
t r Dec 2 06:40:23 IST 2000 comment
r h Dec 2 06:40:23 IST 2009 like
j f Dec 2 06:40:23 IST 2008 like
g d Dec 2 06:40:23 IST 2007 share
w q Dec 2 06:40:23 IST 2003 like
o y Dec 2 06:40:23 IST 2002 like
x y Dec 2 06:40:23 IST 2000 comment
y x Dec 2 06:40:23 IST 2009 like
x z Dec 2 06:40:23 IST 2008 like
z x Dec 2 06:40:23 IST 2007 share
y z Dec 2 06:40:23 IST 2003 like
z y Dec 2 06:40:23 IST 2002 like
输出应该是:
(a,c, d, e)
(x,y,z)
I am newbie to Perl. I need to parse a tab separated text file. For example:
From name To name Timestamp Interaction
a b Dec 2 06:40:23 IST 2000 comment
c d Dec 1 10:40:23 IST 2001 like
e a Dec 1 16:03:01 IST 2000 follow
b c Dec 2 07:50:29 IST 2002 share
a c Dec 2 08:50:29 IST 2001 comment
c a Dec 11 12:40:23 IST 2008 like
e c Dec 2 07:50:29 IST 2000 like
c b Dec 11 12:40:23 IST 2008 follow
b a Dec 2 08:50:29 IST 2001 share
After parsing I need to create groups base upon users interaction. In this example
a<->b
b<->a
c<->a
a<->c
b<->c
c<->b
for this we can create one group. and we need to display list of groups.
I need some pointers on how to parse the file and form group?
Edit
Constraint-> at least 3 user required for creating group.
Interaction is nothing but some communication is done between two user. It does not matter of which communication
My Approach for solving is
We remove repeated interaction between users . such as "a<>b like "again if "a<>b follow" is present then we remove this row.
Creating 2 dimensional array which store interaction two users i.e
To Name a b c d
From Name
a X <> <> X b <> X <> X c <> <> X X d X <> X X
X= Represent no interaction
<>= represent interaction
In this approach we start from first row i.e "a" user check with "b". if "a" is interact with "b" then we perform reverse of i.e "b" interact with "a". same steps perform for each column.
But this approach depends on number of users. If 1000 users are present then we have to create 1000 X 1000 matrix. IS there any alternative to solve this
I have added sample input
a c Dec 2 06:40:23 IST 2000 comment
f g Dec 2 06:40:23 IST 2009 like
c a Dec 2 06:40:23 IST 2009 like
g h Dec 2 06:40:23 IST 2008 like
a d Dec 2 06:40:23 IST 2008 like
r t Dec 2 06:40:23 IST 2007 share
d a Dec 2 06:40:23 IST 2007 share
t u Dec 2 06:40:23 IST 2006 follow
a e Dec 2 06:40:23 IST 2006 follow
k l Dec 2 06:40:23 IST 2009 like
e a Dec 2 06:40:23 IST 2009 like
j k Dec 2 06:40:23 IST 2003 like
c d Dec 2 06:40:23 IST 2003 like
l j Dec 2 06:40:23 IST 2002 like
d c Dec 2 06:40:23 IST 2002 like
m n Dec 2 06:40:23 IST 2005 like
c e Dec 2 06:40:23 IST 2005 like
m l Dec 2 06:40:23 IST 2011 like
e c Dec 2 06:40:23 IST 2011 like
h j Dec 2 06:40:23 IST 2010 like
d e Dec 2 06:40:23 IST 2010 like
o p Dec 2 06:40:23 IST 2009 like
e d Dec 2 06:40:23 IST 2009 like
p q Dec 2 06:40:23 IST 2000 comment
q p Dec 2 06:40:23 IST 2009 like
a p Dec 2 06:40:23 IST 2008 like
p a Dec 2 06:40:23 IST 2007 share
l p Dec 2 06:40:23 IST 2003 like
j l Dec 2 06:40:23 IST 2002 like
t r Dec 2 06:40:23 IST 2000 comment
r h Dec 2 06:40:23 IST 2009 like
j f Dec 2 06:40:23 IST 2008 like
g d Dec 2 06:40:23 IST 2007 share
w q Dec 2 06:40:23 IST 2003 like
o y Dec 2 06:40:23 IST 2002 like
x y Dec 2 06:40:23 IST 2000 comment
y x Dec 2 06:40:23 IST 2009 like
x z Dec 2 06:40:23 IST 2008 like
z x Dec 2 06:40:23 IST 2007 share
y z Dec 2 06:40:23 IST 2003 like
z y Dec 2 06:40:23 IST 2002 like
Output should be:
(a,c, d, e)
(x,y,z)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
解析很容易。只需一个
split /\t/
就足够了。但是, Text::xSV 或 Text::CSV 可能会更好。对于连接,您可以使用 Graph 模块。为了能够有效地使用该模块,您至少需要了解图论的基础知识。
请注意,强连接组件定义为:
但是,请注意,如果您有
a <-> b
和b <-> c
、a
、b
和c
将形成一个强连接组件,这意味着它的要求比 a 的所有成员都弱。小组在两个方向上相互互动。我们仍然可以使用它来减少搜索空间。一旦有了候选组,您就可以检查每个组,看看它是否符合您对组的定义。如果某个候选组不符合您的要求,那么您可以检查所有少一个成员的子集。如果您在这些组中找不到任何组,则可以查看成员少于两个的所有子集,依此类推,直到达到最小组大小限制。
下面的脚本使用了这个想法。然而,它很可能无法扩展。我强烈怀疑人们也许能够组合出一些 SQL 魔法,但我的思维太有限了。
输出:
Parsing is easy. Just a
split /\t/
might be enough. However, Text::xSV or Text::CSV might be better.For the connections, you can use the Graph module. To be able to use that module effectively, you need to understand at least the basics of graph theory.
Note that a strongly connected component is defined as:
However, note that if you have
a <-> b
andb <-> c
,a
,b
, andc
will form a strongly connected component meaning that is a weaker requirement than all members of a group interacted with each other in both directions.We can still use this to reduce the search space. Once you have candidate groups, you can then check each to see if it fits your definition of a group. If a candidate group does not meet your requirements, then you can check all subsets with one fewer members. If you don't find any groups among those, you can then look at all subsets with two fewer members and so on until you hit the minimum group size limit.
The script below uses this idea. However, it very likely won't scale. I strongly suspect one might be able to put together some SQL magic but my mind is far too limited for that.
Output: