问题背景:
小明是我司的一名优秀数据研发,每天他要处理着上千亿的数据。然而他的老板今天又给了他新的任务,要通过自然语言学习的方法,去挖掘数据中的更多价值,于是小明踏上了NLP的学习之路。
小明翻阅了很多书籍,初步的了解了一些NLP的算法,它们有一个共同的步骤,是要做分词,然后做词频统计。现在小明已经通过一些算法,得到了一个分好词的词典,然后对于一篇给定的文章,他想知道,他得到的词典中的每个词,在文章中出现的频次。
值得注意的是,有许多无意义的词,往往会对文章的分析造成一些影响,所以,小明还得先过滤掉这些无意义的词。此外,通常情况下,我们按先出现,先过滤的规则进行过滤(如文章’abcdefg’, 需要过滤[‘cde’, ‘bcd’], ‘bcd’先出现在了文章中,所以文章被过滤为’a efg’)。但为了尽可能保持原文的完整性,对于两个过滤词(A, B),如果A包含了B,那么要求先过滤掉B,无论是A还是B先出现(如文章’abcdefg’, 需要过滤[‘bcde’, ‘cd’],那么文章被过滤为’ab efg’)。注意,过滤之后,文章是被截断的
由于小明每天忙于数据研发,现在他想请你帮忙解决这个难题。
编程说明:
编译器版本:
Java 1.8.0_66
请使用标准输入输出(System.in, System.out);已禁用图形、文件、网络、系统相关的操作,如java.lang.Process , javax.swing.JFrame , Runtime.getRuntime;不要自定义包名称,否则会报错,即不要添加package answer之类的语句;您可以写很多个类,但是必须有一个类名为Main,并且为public属性,并且Main为唯一的public class,Main类的里面必须包含一个名字为'main'的静态方法(函数),这个方法是程序的入口
时间限制:
1S (C/C++以外的语言为: 3 S)
内存限制:
64M (C/C++以外的语言为: 576 M)
输入:
输入第一行是一个长度不超过100000的的字符串,代表着小明要检索的文章。 输入第二行是两个用空格隔开的,不超过100000的整数m n,分别代表需要过滤的过滤词个数,和需要统计的统计词典大小。 接下来的m行,每行是一个长度不超过100000的过滤词。所有m个词加起来总长度不超过100000。 再接下来的n行,每行是一个长度不超过100000的统计词。所有n个词加起来总长度不超过100000。 输入保证,所有的字符都在[a-z]范围
输出:
输出n行,每行一个整数,代表相应的次序的统计词在词典中出现的频数。
输入范例:
bobisaopieceofssshitmostof
2 4
ao
o
bb
bob
s
s s
输出范例:
0
0
5
2
解题代码和思路:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.TreeSet;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String tar = br.readLine();
String[] mn = br.readLine().split("\\s+");
int m = Integer.parseInt(mn[0]);
int n = Integer.parseInt(mn[1]);
String[] mstr = new String[m];
String[] nstr = new String[n];
for (int i = 0; i < m; i++) {
mstr[i] = br.readLine();
}
for (int i = 0; i < n; i++) {
nstr[i] = br.readLine();
}
countTimes(deal(tar, mstr, nstr, m, n), nstr);
}
/*
* 把object数组变成String数组
*/
public static String[] toStr(Object[] t) {
String[] re = new String[t.length];
for (int i = 0; i < t.length; i++) {
re[i] = t[i].toString();
}
return re;
}
/*
*str目标数组
*mstr 过滤数组
*产生一个带优先级的序列的过滤词数组
*/
public static String[] order(String str, String[] mstr) {
String tmp[] = judge(mstr);
int[] or = new int[mstr.length];
for (int i = 0; i < mstr.length; i++) {
or[i] = str.indexOf(mstr[i]);
}
for (int i = 0; i < tmp.length; i++) {
for (int j = i + 1; j < tmp.length; j++) {
if (or[i] > or[j]) {
int t = or[i];
or[i] = or[j];
or[j] = t;
String p = tmp[i];
tmp[i] = tmp[j];
tmp[j] = p;
}
}
}
return tmp;
}
/*
* 判断过滤词是否存在包含关系
* 如果存在就保留最小包含的
*/
public static String[] judge(String[] t) {
ArrayList
list = new ArrayList
();
for (String s : t) {
list.add(s);
}
for (int i = 0; i < t.length; i++) {
for (int j = i + 1; j < t.length; j++) {
if (t[i].contains(t[j])) {
list.remove(t[i]);
}
}
}
return toStr(list.toArray());
}
/*
* 切割数组过程
*/
public static String[] deal(String tar, String[] mstr, String[] nstr, int m, int n) {
String[] filter = order(tar, mstr);// 产生合适过滤数组
String[] re = tar.split(filter[0]);
ArrayList
list = new ArrayList
();
ArrayList
delete = new ArrayList
(); ArrayList
add = new ArrayList
(); for (String r : re) { list.add(r); } for (int i = 1; i < filter.length; i++) { for (String ary : list) { String obs = ary; delete.add(ary); String[]splited=judgeEmpty(obs.split(filter[i])); if(splited!=null){ for(int j=0;j
count=new HashMap
(); for(String t:nstr){ count.put(t, 0); } for(String t:nstr){//出现词 次数计算 for(String p:str){ String copy=p; /* * 这个while循环计算t字符串在p分割词中出现次数 */ int index=-1; while((index=copy.indexOf(t))>-1){ count.put(t, count.get(t)+1); copy=copy.substring(index+1); } } } // TreeSet
ts=new TreeSet
(count.keySet()); for(String s:nstr){ System.out.println(s+":"+count.get(s)); } } /* * 判断字符串是否为空,如果是空串或者空就不加入新数组 */ public static String[] judgeEmpty(String[] str) { ArrayList
list = new ArrayList
(); for (String s : str) { if (s.length() > 0 && s != null) { list.add(s); } } if (list.size() > 0) { return toStr(list.toArray()); } else { return null; } } }
感悟:
记得谁说过,人们的自信不是源于强大,而是源于无知,无知者无谓,自己这次笔试做得很差,两道编程题都花了很多时间去想结果没解出来,结果睡一觉就有办法了.都是缘分啊.
上面程序输出可能有点不同一下应该就可以了 .如果出错了希望大家说下 .