阿里巴巴2017实习生招聘数据研发工程师编程题2(字符串处理)

问题背景:

小明是我司的一名优秀数据研发,每天他要处理着上千亿的数据。然而他的老板今天又给了他新的任务,要通过自然语言学习的方法,去挖掘数据中的更多价值,于是小明踏上了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;jcount=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;
		}
	}

}


感悟:

记得谁说过,人们的自信不是源于强大,而是源于无知,无知者无谓,自己这次笔试做得很差,两道编程题都花了很多时间去想结果没解出来,结果睡一觉就有办法了.都是缘分啊.
上面程序输出可能有点不同一下应该就可以了 .如果出错了希望大家说下 .

猜你喜欢

转载自blog.csdn.net/c654528593/article/details/70853080