java 一个较长的String如何快速拆分?

恒温 发布于 2017/01/27 16:44
阅读 1K+
收藏 2

几十万的单词由空格间隔链接,已知substring处理速度过慢。

我需要统计这个String里面每个单词出现的次数截取存入Map

加载中
0
Feng_Yu
Feng_Yu

这不就是Hadoop的入门范例中被用烂的word count?

恒温
恒温
原谅菜鸟的无知吧,大神,请细说。。
0
excepiton
恒温
恒温
java.util.Scanner是Java5的新特征,主要功能是简化文本扫描。这个类最实用的地方表现在获取控制台输入,其他的功能都很鸡肋,尽管Java API文档中列举了大量的API方法,但是都不怎么地。 你觉得是这个????
0
GestureWei
GestureWei
这不典型的mapreduce的wordcount?
恒温
恒温
回复 @GestureWei : 嗷嗷,看了下。貌似也不行。一个小项目,定制的,硬件只有一台一般的台式电脑。。据说还很卡。。所以只能优化代码。。不奢望硬件了
GestureWei
GestureWei
hadoop及spark的生态环境都是建立在java上的,大规模的数据适合分布式处理
恒温
恒温
这.... java有这个吗。。。
0
kakai
kakai

几十万的量,我觉得你直接遍历字符串的char数组,记录上一个空格的索引(单词起始),遍历到下一个空格(单词结束),这样的效率还是很高的。

kakai
kakai
回复 @恒温 : 你的半小时是按照这个逻辑写的?楼下“蓝水晶飞机”的代码和我这个逻辑差不多,你试了?
恒温
恒温
额。。拆分完就四百万的量了。。。半个多小时才能搞定。。不能这么玩啊。。
0
小王来了
小王来了
spark入门也有
恒温
恒温
spark又是什么。。
0
v若水
v若水

我去这就是hadoop的入门程序wordcount

恒温
恒温
分布式貌似Linux平台啊。。看的有点懵
0
g
greenspan321

正则运算

恒温
恒温
半个小时 ,太慢。。
0
蓝水晶飞机
蓝水晶飞机

搞了许久才写出来,拿你的字符串来试试看?

想用Map<char[], Integer>来避免循环中处理单词时new String,但我发现统计不准了,不知道是不是char[].hashCode计算的原因导致出现次数全部是1,还是要Character[]才行?(既想想要装箱还是换回String来。。。)

package com.test;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

public class TestClass {

	public static void main(String[] args) {
		String bigString = "Bootstrap is downloadable in two forms,"
				+ " within which you'll find the following directories and files,"
				+ " logically grouping common resources and"
				+ " providing both compiled and minified variations. and more than more happy happy happy word";
		long start = System.nanoTime();
		Map<String, Integer> wordCount = wordCount(bigString);
		System.out.println("耗时" + (System.nanoTime() - start));
		for (Entry<String, Integer> en : wordCount.entrySet()) {
			System.out.println(String.format("%1$s\t%2$s", en.getKey(), en.getValue()));
		}
	}

	private static final char SPACE = ' ';

	/**
	 * 统计单词出现次数
	 * 
	 * @return map<word, count> LinkedHashMap
	 */
	public static Map<String, Integer> wordCount(
			String bigString/* , char... spaceChars */) {
		char space = SPACE; // space
		Map<String, Integer> wcMap = new LinkedHashMap<>(); // 存储统计单词出现次数的数据
		char[] buffer = bigString.toCharArray();
		int startIndex = 0; // 上一个单词开始下标(空格之后)
		int wordLen = 0; // 单词长度
		char ch = SPACE; // char element
		String word = null; // 单词
		for (int i = 0; i < buffer.length; i++) {
			ch = buffer[i];
			if (ch != space) {
				wordLen++; // 单词匹配中
			}
			if (ch == space && wordLen == 0) { // [空格,空格,a]
				startIndex = i + 1; // 连续的空格
				wordLen = 0;
				continue;
			} else if ((ch == space || i + 1 == buffer.length) && wordLen > 0) { // [a,b,空格,空格]
				word = new String(buffer, startIndex,
						/* i+1 < buffer.length ? */wordLen/* : wordLen+1 */); // 单词匹配完成,
																				// 空格或字符末尾
				wcMap.put(word, wcMap.containsKey(word) ? wcMap.get(word) + 1 : 1);
				wordLen = 0;
				startIndex = i + 1;
			} /**
				 * else if(ch != space) { wordLen++; // 单词匹配中 }
				 **/
		}
		buffer = null;
		word = null;
		return wcMap;
	}
}

 

恒温
恒温
抱歉。。我写的跟复杂一点。。
蓝水晶飞机
蓝水晶飞机
@红薯 ,问答页加一个用户可自己设置的宽屏模式可否,你看现在这样子的代码贼难看,宽屏就宽一点啊。
0
l
liushizhi

(defun s (str)
    (let ((h (make-hash-table))(c 0))
      (loop
  (multiple-value-bind (val n) (read-from-string str nil nil :start c)
    (if val (setf c n)(return-from s h))
    (if (Gethash val h) (setf (gethash val h) (incf (gethash val h))) (setf (gethash val h) 1))))))

 

(maphash #'(lambda (key val) (print `(,key ,val))) (s "a b c a b c 123 123"))

(B 2)
(C 2)
(123 2)
(A 2)

l
liushizhi
回复 @恒温 : 这是common lisp,我测试了一下,长度为一百万字符的序列解析出来不到3秒,我的机器比较慢,CPU为1.8。
恒温
恒温
这个格式是什么语言的。。。亲 看不懂的说。。
0
斯武丶风晴
斯武丶风晴

推荐jdk的StreamTokenizer 解析10万单词 不到1秒。至于每个单词的频次计算,那就随意了。

简单示例:

public static void main(String[] args) throws IOException {
	StreamTokenizer tokenizer = new StreamTokenizer(new FileReader("d:/2.txt"));
	long start=System.currentTimeMillis();
	int i =0;
	while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {// 流末尾
		if (tokenizer.ttype == StreamTokenizer.TT_WORD) {//单词
			System.out.println(tokenizer.sval);
			i++;
		} else if (tokenizer.ttype == StreamTokenizer.TT_EOL) {// 行末尾
			System.out.println();
		}
	}
	System.out.println(i);
	System.out.println((System.currentTimeMillis()-start)+"ms");
}

100200
815ms

恒温
恒温
亲,我需要的是数据的快速拆分。。不是读取的问题,我是用爬虫获取页面的数据,然后链接分类,拆分统计。。现在的问题是拆分统计数据超过百万。。时间在二十分钟左右太慢了。。。
返回顶部
顶部