| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 512 人关注过本帖
标题:如何利用c++从文档内,抽取特定行列
只看楼主 加入收藏
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
结帖率:66.67%
收藏
已结贴  问题点数:20 回复次数:8 
如何利用c++从文档内,抽取特定行列
文档内容:
程序代码:
@HWI-BRUNOP16X_0001:4:1:1386:1030#0/1
GACCAATAAGTGATGATTGAATCGCGAGTGCTCGGCAGATTGCGATAAAC
+HWI-BRUNOP16X_0001:4:1:1386:1030#0/1
TNTTJTTTETceJSP__VRJea`_NfcefbWe[eagggggfgdggBBBBB
@HWI-BRUNOP16X_0001:4:1:1836:1032#0/1
CAGCAGACGCTTTGATTGCTCGATCTCTTGGTAAATACGGCATCATCTGC
+HWI-BRUNOP16X_0001:4:1:1836:1032#0/1
TJTTTJFFFFa`TWNMPJGTbZSTPZJHHGT^I^H^SKZeeeeeeb``RT

我利用一下的code,来读取及处理14Gb的文档:
程序代码:
[home@cpp]time grep -A1 '@HWI' input_file.txt | sed -e 's/--//g' -e 's/@HWI/>HWI/g' | sed '/^$/d' > output_file.txt
real    7m13.413s
user    5m25.382s
sys     1m37.668s
[1]+  Done       time grep -A1 '@HWI' input_file.txt | sed -e 's/--//g' -e 's/@HWI/>HWI/g' | sed '/^$/d' > output_file.txt           
[home@cpp]cat output_file.txt
>HWI-BRUNOP16X_0001:4:1:1386:1030#0/1
GACCAATAAGTGATGATTGAATCGCGAGTGCTCGGCAGATTGCGATAAAC
>HWI-BRUNOP16X_0001:4:1:1836:1032#0/1
CAGCAGACGCTTTGATTGCTCGATCTCTTGGTAAATACGGCATCATCTGC

在文体框,理想的格式输入法:
程序代码:
c++程序名称 要被读取的文档名称 结果输出新的文档名称
例如:
cplusplus_program input_file.txt output_file.txt

c++分析要被读取的文档逻辑:
1.当c++程序,发现要被读取文档的开头是"@HWI"时,取出该行及其下一行的内容,并将结果储存于新的文档内;
2.将所有开头是"@HWI",改成">HWI";
3.结果文档的理想内容是:
>HWI-BRUNOP16X_0001:4:1:1386:1030#0/1
GACCAATAAGTGATGATTGAATCGCGAGTGCTCGGCAGATTGCGATAAAC

谢谢各位c++高手的意见...
搜索更多相关主题的帖子: 如何 
2011-07-05 10:04
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:20 
这个怎么叫抽取特定的列?感觉还是按行操作的呀?
2011-07-05 18:48
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
感觉你用了很多次 s 指令,不知道有些是什么意思。比如:'s/--//g'

你这个命令行可以压缩一下,看看是不是能快一些:
$ time sed -ne '/@HWI/{s/@HWI/>HWI/p;n;p}' < input_file.txt  > output_file.txt
2011-07-05 19:09
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
如果你想用 c++ 写这个功能的话,和你上回问的那个问题几乎是一样的。
只不过读到 @HWI 不是把这行扔掉,而是把 @ 改成 > 就行了,再打印,然后它的下一行也原封不动地打印出来。然后再循环往后找就可以。

这没什么难度。如果你是想学 c++ 的话,我觉得练这些意义不大。就用 sed 做,然后把节约出来的时间,用来学习一些更有意义的话题。
2011-07-05 19:14
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 3楼 pangding
以下是我利用您的sed command,处理14Gb数据,所花的时间:
程序代码:
real    6m16.302s
user    2m21.376s
sys     0m34.904s

[3]   Done                    time sed -ne '/@HWI/{s/@HWI/>HWI/p;n;p}' < input_file.txt > output_file.txt

这是另一个我试着用c++,分析相同数据,所花的时间:
程序代码:
real    1m6.012s
user    0m31.242s
sys     0m27.554s

[3]-  Done                    time ./cpp_program < input_file.txt > output_file.txt

以下是我所使用c++程序的code:
程序代码:
#include <stdio.h>
#include <string.h>

int main(void)
{
        char buf[4096];

       while(fgets(buf, 4096, stdin))
       {
               if(strncmp(buf, "@HWI", 4) == 0)
               {
                       buf[0]='>';
                       fputs(buf, stdout);
                       if(fgets(buf, 4096, stdin) == NULL) continue;
                       fputs(buf, stdout);
               }
}
}


2011-07-06 08:43
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 4楼 pangding
awk,sed,perl我有基本了解的基础.
相同的文档,我打算试着改用c++来分析,最主要的目的,也是希望可以加快,分析及处理输入文档的时间 :)
c++需要从错误和讨论中学习.
若是你有任何可以加快及改进我以上的c++程序,我很乐意接受你的意见.
谢谢你的任何宝贵意见

2011-07-06 08:48
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
不要让一个文件过大,一个良好的习惯是把任何单一文件的大小控制在2G以内。而且事实上,我觉得2G也太大了。
    另外你那个程序写的还是有很多值得提点的问题的,你可以再回去好好研究一下 玩出来 上次写的那个代码。处理文本文件有很多常规动作,要自己想清楚之后理解掉才好。而且人们普遍不认为处理文本流有足够速度,所以为了加速,应该考虑有结构的二进制格式。

    你写的那个是 C 程序,c 的IO库要比 c++ 的快很多。而且无论如何,这都是线性行为,可以轻松的想见:无论用什么方式,它的实现都不能真正提速。即使是你所谓的从6分钟缩短到1分钟也一样。

我的意思是:你这种行为很类似转码操作,就是说你的原始文件根本不符合你后续处理的需要,因此需要把它过滤成其它格式。
    但这种行为只需要做一次。我用了五秒钟就写了上面的那个 sed 的程序,虽然它也许比 c 程序慢了几分种,但慢的时间根本不够你开发一个 c 程序(不要告诉我你一个新手可以在几分钟内编好上面的程序并调试通过),因此这么做反而是节约时间的。而且如果愿意,可以接管线分割文件。这就是为什么所有类似的程序应该开发成过滤器,而不是像你想的那样要求使用位置参数。

    如果你的后续操作还很复杂(就是指你转完这后的统计工作),那么真的想节约时间的话,应该在转码格式上下些心思,而不是只是单纯的转成文本文件。而你的精力,应该用在真正有意义的程序设计上,既用在统计程序的设计上。或者也许后续工作,你会考虑用其它软件,而不是自己动手。
2011-07-06 13:41
cpp_初学者
Rank: 1
等 级:新手上路
帖 子:32
专家分:0
注 册:2011-6-30
收藏
得分:0 
回复 7楼 pangding
版主,谢谢你的指导。
不好意思噢,最近网络不好,迟复你的。
你分享的意见,我再消化及理解着。
我主要想尝试利用c程序来处理文档,主要是,当我的输入文档,大过1Gb时,因为能使用的RAM有限,我时常需要消耗很多时间,才能得到理想的输出文档 :(
你是否有任何书能介绍?
关于如何利用c++及统计方面的资料?
我现在看着c++ primer plus。
觉得还不错下。
还在慢慢学习中.
2011-07-11 16:35
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
你说的那本书就不错。
用 c 写的文本库一般都是要解析文本内容(很复杂的解析,往往要遍历数次文本,而不只是一次线性扫描)。

一般来说向用 sed 做你说的那些变换我觉得就比较合适,sed 并不会用太多的内存。因为它也不是把文本全部加载进来,所以应该还不会因为内存小而出问题。
如果你要编辑文本,那么用 ed 好一点,因为它也一样,并不是把文本加载到内存里,而是加载到了硬盘上。(虽然这方法看上去很诡异吧……)
而像 vi 或者 emacs 这种工具则会加载到内存里,所以不是很适合加载过大的文件(emacs 对文件的大小有一定限制。但 vi 就更憨厚些,给什么开什么,如果内存不够就会比较纠结)。

另外,我很少做统计工作。(做也是用专门的工具做,比如我只用过 spss 和 sas,后者几乎不会用,不过前者会的功能也不多)
不过看你最近问的问题也不太像统计就是了。你们用这些文本统计什么东西呢?难道是 DNA 序列之类的?
2011-07-11 20:46
快速回复:如何利用c++从文档内,抽取特定行列
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013707 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved