首页 新闻 会员 周边

C#高效的文本数据获取

0
悬赏园豆:100 [已解决问题] 解决于 2015-05-24 10:43

txt文件:

都是由数字组成,由可变个数的空格或换行隔开。比如:3 4 2 7    6

21 19

12    12    19……

 

前面24个数字是描述。

后面所有的数字是具体数据,个数可以根据前面24个数字的几个算出来。

 

我现在的方法:string st[24]放前面24个数字,string st[a+b*c]放后面数字;

对于读取的txt用regex.split(s,@"\s+")方法分开,再放入两个数组里面;但效率很低。

 

求助大神:有没有更好的效率,完成这件事情?

cxwcdxw的主页 cxwcdxw | 初学一级 | 园豆:10
提问于:2015-05-23 12:40
< >
分享
最佳答案
0

试试string.split,应该比正则表达式的效率好点吧。

    var str = "3 4 2 7    6";
    str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

再不行的话,只能自己写算法一个个字符的解析啦。

收获园豆:100
天方 | 大侠五级 |园豆:5407 | 2015-05-24 10:13

str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

这个不管空格的个数吗?因为空格是不定长的?

cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 10:38

写算法的话,就是用低层的字符一个个的来,如果是空格就跳过,如果是字符,就转存。这样吗?

cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 10:39

百度了下,StringSplitOptions.RemoveEmptyEntries,你的答案已经让我找到解决方法了。

这种效率,和你说的,自己写算法一个个的字符解析,哪种效率高啊?

因为我有很多很多这种1M到10M的文件要解析,效率特别重要。

cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 10:42

@cxwcdxw: 

自己写算法就一个个的来呗, 专用算法比这种通用型算法一般来讲效率要好些, 不过大部分的时候应该差距不大。你可以试一下系统算法是否满足要求,10m应该不是什么大数据, 能用系统算法尽量用系统算法,可靠性,稳定性,扩展性都好得多。

另外,自己写的算法相对自由些,比如说有几个G的大小,系统的算法是在全部内存中处理的,可能就搞不定了。 自己写的时候可以从文件中一点点读,一点点的存。

天方 | 园豆:5407 (大侠五级) | 2015-05-24 10:58

@天方: 嗯,理解你的意思。

感谢感谢。您的忽略空字符串,就基本解决我的问题了。我用正则表达式,效率太低。

cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 11:21
其他回答(3)
0

文件多大?

顾晓北 | 园豆:10844 (专家六级) | 2015-05-23 13:51

从300K到20M左右

支持(0) 反对(0) cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 10:37
0

如果文本数据达到M级别的话,建议使用StringBuilder,不要使用String,这样或许会更好!

hippieZhou | 园豆:578 (小虾三级) | 2015-05-24 12:42
 var str = "3 4 2 7    6";
    str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

比如说,这个str大到M级别的话,

就用stringbuilder 读取txt,最后再存到这个str里面来进行拆分?还是用stringbuilder直接进行什么操作,就可以获取数据了?
支持(0) 反对(0) cxwcdxw | 园豆:10 (初学一级) | 2015-05-24 13:13

@cxwcdxw: 建议将string类型的数据作为中间变量进行单一处理,然后依次将他们加入到StringBuilder中,直接使用StringBuilder进行大文本操作,string类型的变量对较短的小容量字符串进行处理,这样对程序的执行效率比较好,考虑到你的文本数量很大,建议使用StringBuilder对文本操作!

支持(0) 反对(0) hippieZhou | 园豆:578 (小虾三级) | 2015-05-24 14:30
0

Hello World!
[Scanner]读取5000000个数据,用时1665毫秒
[String.Split]读取6111958个数据,用时1960毫秒
[Regex.Split]读取5000002个数据,用时7187毫秒
Press any key to continue . . .

 

class Scanner{
        public Scanner(String sr)
        {
            this.sr = sr;
            this.position = 0;
        }
        string sr;//构造函数初始化为文件流
        char[] buffer = new char[10];//数字最大长度,假设最多为10字符
        int position;
        int SPACE = (int)' ';
        public string next(){
            
            while(position<sr.Length){
                char read = sr[position];
                position++;
                if(read != SPACE && read != '\r' && read != '\n'){
                    int i = 0;
                    while(position<sr.Length){
                        buffer[i] = read;
                        i++;
                        
                        read = sr[position];
                        position++;
                        if(read == SPACE || read == '\r' || read == '\n'){
                            break;
                        }
                    }
                    return new String(buffer, 0, i);
                }
            }
            return null;
        }
    }
小彬 | 园豆:947 (小虾三级) | 2015-05-27 14:00

超级感谢。圆豆都给第一个同学了。

我自己现在用的是第二种方法,1、2方法耗时数量级相同,但第二种方法要简单太多了。一个语句就可以了。

2、3方法我自己也比过时间,大约1:5。你的1:3.5,总体来说,这两种方法,是第二种方法更好更效率,同时写法都非常简单。

 

我现在读取的文件大约是500K左右,用第二种方法,每个耗时大约30ms。

支持(0) 反对(0) cxwcdxw | 园豆:10 (初学一级) | 2015-05-28 00:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册