错题一
- 以下哪一项正则能正确的匹配网址:
http://www.bilibili.com/video/av21061574
()
正则表达式的规则:
规则字符在java.util.regex Pattern类中
A:字符
x 字符 x。举例:'a'表示字符a
\\ 反斜线字符。
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
B:字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围)
[0-9] 0到9的字符都包括
C:预定义字符类
. 任何字符。我的就是.字符本身,怎么表示呢? \.
\d 数字:[0-9]
\w 单词字符:[a-zA-Z_0-9]
在正则表达式里面组成单词的东西必须有这些东西组成
\s 匹配空格字符
D:边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
就是不是单词字符的地方。
举例:hello world?haha;xixi
E:Greedy 数量词
X? X,一次或一次也没有 比如""空串 就是没有
X* X,零次或多次 大于等于1次 都算多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
\w
还包括数字在内,但是双斜杠后面不能含有数字;
错题二
- 设int x=1,float y=2,则表达式x/y的值是:()
就本题而言,结果是float类型的,因为x,y两个数字精度最高的就是float,所以最终结果是0.5,并且这个0.5是float类型的;
错题三
public class Test {
private static int j = 0;
private static Boolean methodB(int k) {
j += k;
return true;
}
public static void methodA(int i) {
boolean b;
b = i < 10 | methodB(4);
b = i < 10 || methodB(8);
}
public static void main(String args[]) {
methodA(0);
System.out.println(j);
}
}
What is the result?
"|"是按位或:先判断条件1,不管条件1是否可以决定结果(这里决定结果为true),都会执行条件2;
"||"是逻辑或:先判断条件1,如果条件1可以决定结果(这里决定结果为true),那么就不会执行条件2,具有短路的特点;
题目四
web容器:给处于其中的应用程序组件(JSP,SERVLET)提供一个环境,使 JSP、SERVLET直接与容器中的环境变量交互,不必关注其它系统问题。主要由WEB服务器来实现。例如:TOMCAT、WEBLOGIC、WEBSPHERE等。该容器提供的接口严格遵守J2EE规范中的WEB APPLICATION 标准。我们把遵守以上标准的WEB服务器就叫做J2EE中的WEB容器。
-
EJB容器:Enterprise java bean 容器。更具有行业领域特色。它提供给运行在其中的组件EJB各种管理功能。只要满足J2EE规范的EJB放入该容器,马上就会被容器进行高效率的管理。并且可以通过现成的接口来获得系统级别的服务。例如邮件服务、事务管理。
-
JNDI:(Java Naming & Directory Interface)JAVA命名目录服务。主要提供的功能是:提供一个目录系,让其它各地的应用程序在其上面留下自己的索引,从而满足快速查找和定位分布式应用程序的功能。
-
JMS:(Java Message Service)JAVA消息服务。主要实现各个应用程序之间的通讯。包括点对点和广播。
-
JTA:(Java Transaction API)JAVA事务服务。提供各种分布式事务服务。应用程序只需调用其提供的接口即可。
-
JAF:(Java Action FrameWork)JAVA安全认证框架。提供一些安全控制方面的框架。让开发者通过各种部署和自定义实现自己的个性安全控制策略。
-
RMI / IIOP:(Remote Method Invocation /internet对象请求中介协议)他们主要用于通过远程调用服务。例如,远程有一台计算机上运行一个程序,它提供股票分析服务,我们可以在本地计算机上实现对其直接调用。当然这是要通过一定的规范才能在异构的系统之间进行通信。RMI是JAVA特有的。
错题五
下面的输出结果是什么?
public class Demo {
public static void main(String args[])
{
String str=new String("hello");
if(str=="hello")
{
System.out.println("true");
}
else {
System.out.println("false");
}
}
}
对于引用类型数据,使用
==
比较的是地址值;对于基本类型的数据,==
号比较的是数值;
Java中使用new String("hello")
时,JVM会先使用常量池来管理"hello"常量,再调用String类的构造器创建一个新的String对象,新创建的对象被保存在堆内存中;而直接使用"hello"的字符串常量,JVM会用常量池来管理这些字符串。故上述程序中str=="hello"
返回结果为false;
算法题一
- 给定仅有小写字母组成的字符串数组 A,返回列表中的每个字符串中都显示的全部字符(包括重复字符)组成的列表。例如,如果一个字符在每个字符串中出现 3 次,但不是 4 次,则需要在最终答案中包含该字符 3 次,你可以按任意顺序返回答案:
示例 1:
输入:["bella","label","roller"]
输出:["e","l","l"]
示例 2:
输入:["cool","lock","cook"]
输出:["c","o"]
提示:
1 <= A.length <= 100
1 <= A[i].length <= 100
A[i][j] 是小写字母
自己的做法:
public List<String> commonChars(String[] A) {
//用于存放返回值
ArrayList arrayList = new ArrayList<>();
//1、先把给定的字符串中第一个字符串的所有字符放在结果集中
//2、把索引从1开始的这些字符串存储为一个List,最后将他们整体存入一个List
LinkedList<LinkedList<Character>> lists = new LinkedList<>();
for (int i = 0; i < A.length; i++) {
if (i == 0) {
for (int k = 0; k < A[0].length(); k++) {
arrayList.add(A[0].charAt(k));
}
} else {
LinkedList<Character> characters = new LinkedList<>();
for (int j = 0; j < A[i].length(); j++) {
characters.add(A[i].charAt(j));
}
lists.add(characters);
}
}
//System.out.println(lists);
//[[l, a, b, e, l], [r, o, l, l, e, r]]
//3、把索引为 1 以后的字符串都放在集合里面,如果集合中不能同时拥有结果集中的某个字符,就将这个字符移出结果集
// 如果同时拥有一个字符,就将结果集中的字符保留,然后移除字符串集合中的该字符
for (int i = 0; i < arrayList.size(); i++) {
for (int j = 0; j < lists.size(); j++) {
//如果字符串集合中不包含结果集中的当前字符
if (!lists.get(j).contains(arrayList.get(i))) {
//结果集中需要移除这个字符,然后跳出内循环,直接进行下一个结果集字符的判断
arrayList.remove(arrayList.get(i));
i--;
break;
} else {
lists.get(j).remove(arrayList.get(i));
}
}
}
System.out.println(arrayList);
return arrayList;
}
自己的做法相对来说比较冗余,时间和空间上开销都比较大,学习了官方的解题之后,代码如下:
官网做法:
public static List<String> commonChars1(String[] A) {
int[] minfreq = new int[26];
Arrays.fill(minfreq, Integer.MAX_VALUE);
for (String word : A) {
int[] freq = new int[26];
for (int i = 0; i < word.length(); i++) {
++freq[word.charAt(i) - 'a'];
}
for (int i = 0; i < 26; i++) {
minfreq[i] = Math.min(minfreq[i], freq[i]);
}
}
//System.out.println(Arrays.toString(minfreq));
List<String> list = new ArrayList<>();
for (int i = 0; i < 26; i++) {
for (int j = 0; j < minfreq[i]; j++) {
list.add(String.valueOf((char) (i + 'a')));
}
}
return list;
}
【总结】:
1、定义一个长度为26的整型数组,数组中默认值全部为整型的最小值;
2、遍历给定字符串数组中的每一个字符串,把字符串中出现的字符个数统计到另一个长度为26的整型数组中;
3、比较最小统计个数数组与当前字符串统计字符得到的数组,把最小的值存入最小统计个数的数组,这样下来minfreq数组中存放的是所有字符串中最小的统计个数;
4、最终遍历这个统计数组,将其中的字符个数大于等于1的字符依次添加进结果集集合中;
这个做法很新颖,核心是通过计算字符的在每个字符串中的个数,最终生成结果集;
算法题二
自己的做法:
public static int romanToInt(String s) {
LinkedHashMap<Character, Integer> hashMap = new LinkedHashMap<>();
hashMap.put('I', 1);
hashMap.put('V', 5);
hashMap.put('X', 10);
hashMap.put('L', 50);
hashMap.put('C', 100);
hashMap.put('D', 500);
hashMap.put('M', 1000);
Integer sum = 0;
for (int i = 0; i < s.length(); i++) {
String regx = "IV|IX|XL|XC|CD|CM";
if (i < s.length() - 1 && s.substring(i, i + 2).matches(regx)) {
sum += (hashMap.get(s.charAt(i + 1)) - hashMap.get(s.charAt(i)));
i++;
} else {
sum += hashMap.get(s.charAt(i));
}
}
//System.out.println(sum);
return sum;
}
【思路】:
1、首先使用键值对集合存储罗马数字及其对应的数字大小,这样便于存取;
2、遍历得到的这个字符串,如果他不是倒数第二个字符并且它与后面的字符组成特定的集合,它们的总和就是它们之差;
3、如果不符合上面的条件,让结果+=该罗马字符对应的数字;
4、最终返回总和;
更高效的算法:
public static int romanToInt1(String s) {
int sum = 0;
int preNum = getValue(s.charAt(0));
for (int i = 1; i < s.length(); i++) {
int num = getValue(s.charAt(i));
if (preNum < num) {
sum -= preNum;
} else {
sum += preNum;
}
preNum = num;
}
sum += preNum;
return sum;
}
private static int getValue(char ch) {
switch (ch) {
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
default:
return 0;
}
}
- 按照题目的描述,可以总结如下规则:
1、罗马数字由
I,V,X,L,C,D,M
构成;
2、当小值在大值的左边,则减小值,如IV=5-1=4
;
3、当小值在大值的右边,则加小值,如VI=5+1=6
;
4、由上可知,右值永远为正,因此最后一位必然为正。
算法相对来说很简单,只需要判断当前遍历到的罗马数字和之前的保留数字大小,如果小的在前,大的在后就做减法,否则做加法;