阿里巴巴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;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; } } } 
                    
                   
                  
                 
                
               
              
             
            
          
         
         
        
        
       
       
      
      


感悟:

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值