0 0

对于一个长字符串怎么切割才最快?5

我现在有一个长度约6000万的字符串,全是字母,按照每5个切分,怎么才能速度最快呢?切分的方式:比如字符串是"ABCDEFG"切分为ABCDE,BCDEF,CDEFG

求高手指导,现在我把他拆分的切割,但是总是很慢很慢,而且总是内存溢出

注:我使用的是Java语言
2012年10月09日 11:16

12个答案 按时间排序 按投票排序

0 0

可以考虑用随机文件读取

2012年10月11日 09:10
0 0

什么样的需求需要切割这么大的字符串? 切割完之后做什么用?
如果只是拆完之后写到文件中完全没必要把整个字符都读进来啊
以流形式读取,读完一个之后写入文件。看了你的代码我没看出
把这么多字符数据读入内存有什么必要

2012年10月10日 09:43
0 0

修正下  耗时50多秒(也挺长的)  不过占用内存 固定

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import edu.emory.mathcs.backport.java.util.Arrays;


public class FileTest {

    private static final String READ_FILE_NAME = "D:/a.txt";

    private static final String WRITE_FILE_NAME = "D:/b.txt";
    
    private static final char[] LINE_SEPARATOR = new char[]{'\r', '\n'};
    
    public static void main(String[] args) throws Exception {
        
//        writeTestData();
        
        long begin = System.currentTimeMillis();
        readTestData();
        long end = System.currentTimeMillis();
        
        System.out.println(end - begin);
        
    }

    private static void readTestData() throws Exception {
        File f = new File(READ_FILE_NAME);
        BufferedReader r = new BufferedReader(new FileReader(f));
        char[] chars = new char[8192*8];//读取字符的缓冲
        char[] endChars = new char[5];//缓冲区最后5个字符 用于连接上次读取字符的
        boolean firstCharsArrayRead = true;//是否是首次读取字符数组
        
        
        while(r.read(chars) != -1) {
             readKey(chars, endChars, firstCharsArrayRead);
            
        }
    }
    
    

    private static void readKey(char[] chars, char[] endChars, boolean firstCharsArrayRead) throws Exception {
        int charsLength = chars.length;
        
        //不足5个不必处理
        if(charsLength < 5 && firstCharsArrayRead) {
            return;
        }
        
        
        List<char[]> keyBuffer = new ArrayList<char[]>(1024*4); //写出的缓冲 大小1024
        
        if(firstCharsArrayRead) {//如果第一次处理 补4个char 到 endChars
            System.arraycopy(chars, 0, endChars, 1, 4); //补后四个即可
        }
        
       
        
        //新的数组从0【第二次读数组时】/4【第一次读数组时,补充给endChars了】开始即可
        int begin = firstCharsArrayRead ? 0 : 4;
        for(int i=begin; i<charsLength; i++) {
            char[] key = new char[5];
            System.arraycopy(endChars, 1, key, 0, 4);
            key[4] = chars[i];
            keyBuffer.add(key);
            endChars = key;
            
        }
        writeBuffer(keyBuffer);
    }

    private static void writeBuffer(List<char[]> keyBuffer) throws Exception {
        
        File f = new File(WRITE_FILE_NAME);
        BufferedWriter w = new BufferedWriter(new FileWriter(f, true), 8192);
        for(char[] key : keyBuffer) {
            w.write(key);
            w.write(LINE_SEPARATOR);
        }
        w.close();
    }

    private static void writeTestData() throws Exception {
        
        
        File f = new File(READ_FILE_NAME);
        
        OutputStream os = new BufferedOutputStream(new FileOutputStream(f)); 
        
        for(int i=0;i<12000000;i++) { //6
            os.write("abcde".getBytes());
        }
        
        os.close();
    }
}

2012年10月09日 20:40
0 0

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import edu.emory.mathcs.backport.java.util.Arrays;


public class FileTest {

    private static final String READ_FILE_NAME = "D:/a.txt";

    private static final String WRITE_FILE_NAME = "D:/b.txt";
    
    private static final char[] LINE_SEPARATOR = new char[]{'\r', '\n'};
    
    public static void main(String[] args) throws Exception {
        
//        writeTestData();
        
        long begin = System.currentTimeMillis();
        readTestData();
        long end = System.currentTimeMillis();
        
        System.out.println(end - begin);
        
    }

    private static void readTestData() throws Exception {
        File f = new File(READ_FILE_NAME);
        BufferedReader r = new BufferedReader(new FileReader(f));
        char[] chars = new char[8192];//读取字符的缓冲
        char[] endChars = new char[5];//缓冲区最后5个字符 用于连接上次读取字符的
        boolean firstCharsArrayRead = true;//是否是首次读取字符数组
        
        
        while(r.read(chars) != -1) {
             readKey(chars, endChars, firstCharsArrayRead);
            
        }
    }
    
    

    private static void readKey(char[] chars, char[] endChars, boolean firstCharsArrayRead) throws Exception {
        int charsLength = chars.length;
        
        //不足5个不必处理
        if(charsLength < 5 && firstCharsArrayRead) {
            return;
        }
        
        
        List<char[]> keyBuffer = new ArrayList<char[]>(1024); //写出的缓冲 大小1024
        
        if(firstCharsArrayRead) {//如果第一次处理 补4个char 到 endChars
            System.arraycopy(chars, 0, endChars, 1, 4); //补后四个即可
        }
        
       
        
        //新的数组从0【第二次读数组时】/4【第一次读数组时,补充给endChars了】开始即可
        int begin = firstCharsArrayRead ? 0 : 4;
        for(int i=begin; i<charsLength; i++) {
            char[] key = new char[5];
            System.arraycopy(endChars, 1, key, 0, 4);
            key[4] = chars[i];
            keyBuffer.add(key);
            endChars = key;
            
            if(keyBuffer.size() == 1024) {
                writeBuffer(keyBuffer);
            }
            
        }
        
    }

    private static void writeBuffer(List<char[]> keyBuffer) throws Exception {
        
        File f = new File(WRITE_FILE_NAME);
        BufferedWriter w = new BufferedWriter(new FileWriter(f));
        for(char[] key : keyBuffer) {
            w.write(key);
            w.write(LINE_SEPARATOR);
        }
        w.close();
    }

    private static void writeTestData() throws Exception {
        
        
        File f = new File(READ_FILE_NAME);
        
        OutputStream os = new BufferedOutputStream(new FileOutputStream(f)); 
        
        for(int i=0;i<12000000;i++) { //6
            os.write("abcde".getBytes());
        }
        
        os.close();
    }
}


我的机器 22秒

2012年10月09日 19:19
0 0

public static main(String [] args) throws Exception{
      File file = new File("c:\\test.txt");
      FileInputStream in = new FileInputStream(file);
      byte [] b = new byte[5];
      int i = 0;
      ConcurrentLinkedQueue<Byte> queue = new ConcurrentLinkedQueue<Byte>();
      while(in.read(b)>0){
        if(i==0){
            queue.add(b[0]);
            queue.add(b[1]);
            queue.add(b[2]);
            queue.add(b[3]);
            queue.add(b[4]);
         }else{
            queue.add(b[0]);
         }
         System.out.println(queue);
         queue.poll();
         i++;
      }
     in.close();
}

随便写的,不知道对不对。。

2012年10月09日 18:34
0 0

你已经把这6000万字母读入内存了,如果再用某种方法拆分成1200万个字符数组或者字符串也好,等于又使用了6000万字节(或者更多)的内存,等于是浪费。
其实你只需要知道每个拆分的起始索引就可以了。
第i个子串的起始索引是i*5,那么第i个字串就是
str_i = str.substring(i*5,i*5+5);
这样的话,你根本没必要去拆它。

2012年10月09日 16:08
0 0

string strk = "";
            for (int i = 0; i < str.Length; i++)
            {
                if (i % 5 == 0 && i - 5 > 0)
                {
                    strk += str.Substring(i - 5, 5);
                    strk += " ";
                }
            }

2012年10月09日 15:47
0 0

是不是可以这样理解
你就是需要一个长度为5的滑动窗口,走字符串开头滑动,每次向右滑动一个字符后,就输出窗口内的所有字符。

如果问题是这样,那最直观的就是使用一个队列,先把队列压满5个字符,输出队列内所有字符;然后再将队列头字符出队列,再在队尾压入一个新字符,再输出整个队列。
思路就是这样,可以直接用Queue,也可以根据这种思路自己去做一些优化。

2012年10月09日 15:19
0 0

你的数据源呢?如果都是字母,那肯定是一个字节一个!
思路就是连个变量,分别记录总长度和现在读取到的长度,然后使用StringBuffer每次读取指定的长度,循环读取!
然后循环StringBuffer,5个一步进行截取!

2012年10月09日 13:22
0 0

不用读出来,直接处理。

2012年10月09日 12:52
0 0

如果你的内存足够多,直接读到内存里。当然要用JAVA的char保存 。然后你就按数组切好了。
如果内存不够,那就一段一段的读出来,在一段段的切。注意 一下byte,char,这几种类型的应用 。

2012年10月09日 12:49
0 0

这个长字符串是在文件里吗?
切分好的结果如何保存?

2012年10月09日 12:09

相关推荐

    OJ_将数组中的字符串按指定长度重新分割

    标题“OJ_将数组中的字符串按指定长度重新分割”涉及的是一个在线编程挑战(OJ,Online Judge)的问题,其核心是处理字符串数组,并按照特定的长度要求进行分割。这个问题主要涵盖以下知识点: 1. **字符串操作**:...

    substring截取字符串 字符串截取方法

    Substring截取字符串字符串截取方法是指从字符串中提取某一段子字符串的过程,通常会使用“切割”的方式,把字符串的一段子字符串截取出来,该子字符串以索引指定,也可以使用正则表达式或函数实现字符串截取。...

    各种简单的排序算法(快速,合并,堆,计数,包含整数和字符串)

    而对于字符串,需要根据字符串的特性选择合适的排序策略。 总之,了解和掌握这些排序算法对于任何IT专业人士来说都是至关重要的,因为它们不仅提供了理解算法和数据结构的基础,而且还能帮助我们在处理大量数据时...

    python针对不定分隔符切割提取字符串的方法

    模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式是一种快速精确地描述字符串结构的形式,并能进行复杂的查找、替换、提取等操作。 在本文中,针对不定分隔符切割提取字符串的方法,可以通过Python的re...

    易语言最快的逐字分割

    逐字分割,顾名思义,是指将一个字符串按照每个字符进行切割,形成一个字符数组或列表。在许多文本处理任务中,这样的操作是非常常见的,比如文本分析、搜索、替换等。在易语言中,实现这个功能需要对字符串处理的...

    js split 的用法和定义 js split分割字符串成数组的实例代码

    JavaScript中的split()方法是一个非常常用的字符串操作函数,其主要用途是将一个字符串按照指定的分隔符切割成子字符串,并将这些子字符串组成的数组返回。该方法在处理需要从文本中提取信息或者进行文本格式化时...

    Java中关于处理字符的方法集合.doc

    这里使用了`java.util.StringTokenizer`类,这是一个古老的分词工具,它可以按照指定的分隔符将字符串切割成多个部分。在`getStringTonkenizer`方法中,我们创建一个`StringTokenizer`实例,然后通过`hasMoreTokens`...

    php学习 字符串课件

    - `explode()`:使用分隔符将字符串切割成数组。 - `implode()`:将数组元素组合成一个字符串,通常用在数组元素之间插入特定字符。 字符串比较: - `strcmp()`:比较两个字符串的大小,返回值为整数,负数表示第一...

    浅析51个PHP处理字符串的函数

    9. `explode()`:使用分隔符将字符串切割成数组,方便处理包含多个值的字符串。 10. `flush()`:清空服务器的输出缓冲区,立即发送所有等待的输出到浏览器。 11. `get_meta_tags()`:从HTML文档中提取元标记信息,...

    百度(baidu)分词算法分析

    如果是比 4 个中文字符更长的字符串,那分词程序就更不客气了,一定大卸八块而后快。 我们来看看三个字符的情况,提交查询”当然择”,看起来这个查询不伦不类,那是因为我希望看到这个字符串被切分为&lt;当然,择&gt;,...

    后缀数组 后缀数组.pdf

    后缀数组是计算机科学中的一个重要概念,尤其在字符串处理领域。它是一种数据结构,用于存储一个字符串的所有后缀,并将它们以特定的排序方式排列。在处理大规模数据集时,后缀数组被广泛应用于搜索引擎、文本压缩、...

    易语言过滤文本只保留数字.7z

    那么...`,这些结构可以让我们遍历字符串中的每一个字符,并根据字符是否为数字进行处理。在易语言中,数字字符的ASCII码是48到57(对应0-9),所以我们可以用`ASCII`函数获取字符的ASCII码,然后与这个范围进行比较...

    易语言-最快的逐字分割

    总的来说,这个“最快的逐字分割”源码例程是易语言学习者深入理解字符串处理和优化的一个宝贵资源,它不仅可以帮助初学者掌握基本的编程技巧,还能启发他们思考如何在实际项目中实现高性能的文本处理功能。...

    Google 算法真题 20201

    这是一个关于字符串处理和计数的问题,可以通过哈希表记录每个字符出现的频率,然后寻找合适的分割点。 2. **棋盘中的蛋糕分配**: - 这是一道动态规划问题,涉及在棋盘上分割蛋糕,可能需要考虑如何有效地分配...

    commons-lang常用

    - **字符串切割与分割**:能够根据分隔符切割字符串(`split`, `splitPreserveAllTokens`),并支持基于正则表达式的复杂分割(`splitPreserveAllTokens`)。 - **字符串去除与查找**:提供了去除字符串两端空白字符...

    易语言源码易语言切割石材源码.rar

    这个“易语言源码易语言切割石材源码.rar”压缩包文件显然包含了使用易语言编写的一个项目源码,具体是关于“切割石材”的模拟或管理系统。下面将详细探讨易语言及其在切割石材应用中的可能实现。 一、易语言基础 ...

    encode_geohash.rar_geohash_geohash encode_matlab与geohash

    MATLAB程序“encode_geohash.m”很可能实现了上述步骤,提供了一个将经纬度坐标转换为GeoHash字符串的函数。用户可以输入经度和纬度值,程序会返回对应的GeoHash编码,便于后续的空间检索和数据分析。 在GIS应用中...

    最快的逐字分割-易语言

    例如,可以使用“字符串取子串”或“字符串分割”命令,对字符串进行逐字切割。这些函数的高效性能,使得易语言在处理大量文本数据时,能够展现出优秀的性能。 “最快的逐字分割”不仅要求准确无误地完成分割任务,...

    vb关键词检索工具

    1. 定义关键词列表,可以是一个字符串数组或自定义的Keyword类集合。 2. 获取待检索的文本,可能是从文件、数据库或用户输入中获取。 3. 使用`InStr()`或`Like`运算符逐个检查关键词是否存在于文本中。 4. 如果找到...

Global site tag (gtag.js) - Google Analytics