笔试题内容比较多,所以采用一期试题,一期答案解析的形式。
这么久了,来回顾上期试题。
一.编程题 1.二分查找法
即从有序数组中使用二分查找法查找关键字
public static int recursionBinarySearch(int [] arr,int key,int low,int high){
int mid = (high - low)/2 + low;
if(key < arr[mid] && mid !=low){
high = mid - 1;
return recursionBinarySearch(arr, key, low, high);
}else if(key > arr[mid] && mid !=high){
low = mid + 1;
return recursionBinarySearch(arr, key, low, high);
}else if(key == arr[mid]){
return mid;
}
return -1;
}
public static int commonBinarySearch(int[] arr, int key) {
int low = 0;
int high = arr.length - 1;
int mid = 0;
if(key < arr[low] || key > arr[high] || low > high){
return -1;
}
while (low <= high) {
mid = (high - low) / 2 + low;
if (arr[mid] < key) {
low = mid + 1;
} else if (arr[mid] > key) {
high = mid - 1;
}else{
return mid;
}
}
return -1;
}
是否有疑问求mid值时使用mid = (high - low)/2 + low
,而不是mid = (high + low)/2
,这是为了防止int溢出
2.给定一些线段,计算出覆盖的长度,重复部分只计算一次 例如,以下五条线段[1,5] [1.5,4] [2,6] [7,9] [10,10.5]
参考答案:
/**
* 线段类
* @author WK
*
*/
public class Line {
BigDecimal start;
BigDecimal end;
Line( BigDecimal start, BigDecimal end){
this.start = start;
this.end = end;
}
@Override
public String toString() {
return "LineCount{" +
"start=" + start +
", end=" + end +
'}';
}
}
/**
* 计算线段长度
* @author WK
*
*/
public class LineCount {
public static void main(String[] args){
countLength(new ArrayList<Line>(){{add(new Line(new BigDecimal("1"),new BigDecimal("5")));
add(new Line(new BigDecimal("1.5"),new BigDecimal("4")));
add(new Line(new BigDecimal("2"),new BigDecimal("6")));
add( new Line(new BigDecimal("7"),new BigDecimal("9")));
add(new Line(new BigDecimal("10"),new BigDecimal("10.5")));}});
}
public static BigDecimal countLength(List<Line> lineList){
System.out.println("------------计算总长度-------------");
BigDecimal total = BigDecimal.ZERO;
sortList(lineList);
BigDecimal start = lineList.get(0).start;
for(int i = 1;i < lineList.size();i++){
if(isRelative(lineList.get(i-1),lineList.get(i))){
//不相连且不是最后一段
if(i != lineList.size()-1){
continue;
}else{//最后一段
total = total.add(lineList.get(i).end.subtract(start));
}
}else {
total = total.add(lineList.get(i-1).end.subtract(start));
start = lineList.get(i).start;
//最后一段线与前面的不相连
if(i == lineList.size()-1){
total = total.add(lineList.get(i).end.subtract(start));
}
}
}
System.out.println("------------总长度-------------"+total);
return total;
}
/**
* 判断两线段是否相连
* @param line1
* @param line2
* @return
*/
private static boolean isRelative(Line line1, Line line2){
//线段2的start大于等于线段1的start且小于等于线段1的end,即表明线段2与线段1相连
if((line2.start.compareTo(line1.start) == 0 ||
line2.start.compareTo(line1.start) ==1) &&
(line2.start.compareTo(line1.end) == -1 ||
line2.start.compareTo(line1.end) == 0)){
return true;
}
return false;
}
/**
* 冒泡排序,以start的大小,从小到大排序(若start相等,用end对比,小的放前面)
* @param lineList
*/
static private void sortList(List<Line> lineList){
System.out.println("排序前:"+lineList);
for (int i = 0; i < lineList.size()-1; i++) {
for(int j = i+1; j < lineList.size(); j++){
//对比start大小,小的放前面
if (lineList.get(i).start.compareTo(lineList.get(j).start) == 1){
Line temp = lineList.get(j);
lineList.set(j,lineList.get(i));
lineList.set(i,temp);
}
//start相等,用end对比,小的放前面
else if(lineList.get(i).start.compareTo(lineList.get(j).start) == 0 &&
lineList.get(i).end.compareTo(lineList.get(j).end) == 1){
}
}
}
System.out.println("排序后:"+lineList);
}
}
3.编写一个程序,按输入字符串的字符按如下规则排序。 规则1:英文字母从A到Z排列,不区分大小写。 如,输入:Type 输出:epTy
规则2:同一个英文字母的大小写同时存在时,按照输入顺序排序。 如,输入BabA 输出:aABb
规则3:非英文字母的其他字符串保持原来的位置 样例: 输入: A Famous Saying:Much Ado About Nothing(2012/8). 输出: A aaAAbc dFgghh:iimM nNn oooos Sttuuuy(2012/8).
参考答案: 解题思路 1.提取所有字母 2.将字母排序 3.用已排序字母替换原来的字母
public class CharacterSort {
public static void main(String[] args) {
Scanner aScanner = new Scanner(System.in);
String input = aScanner.nextLine();
//记录字母
ArrayList<Character> list = new ArrayList<Character>();
//记录字母所在位置
ArrayList<Integer> index_list = new ArrayList<Integer>();
for (int i = 0; i < input.length(); i++) {
if (Character.isUpperCase(input.charAt(i))
|| Character.isLowerCase(input.charAt(i))) {
list.add(input.charAt(i));
index_list.add(i);
}
}
//字母不区分大小写,按照A到Z排序
Collections.sort(list, new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
// TODO Auto-generated method stub
return String.valueOf(o1).toLowerCase()
.compareTo(String.valueOf(o2).toLowerCase());
}
});
StringBuffer sb =new StringBuffer(input);
for (int j = 0; j < index_list.size(); j++) {
//替换字母,其他字符不需要管
sb.replace(index_list.get(j), index_list.get(j)+1, list.get(j).toString());
}
System.out.println(sb);
}
}
4.写出以下SQL语句 表A
orderId | skuid | skuNum(订单包含的Sku数量) | userName | isSuccess(订单是否成功) |
---|---|---|---|---|
1 | 1 | 3 | 张三 | 1 |
2 | 2 | 10 | 李四 | 1 |
3 | 1 | 30 | 张三 | 0 |
4 | 1 | 6 | 张三 | 1 |
5 | 3 | 7 | 张三 | 1 |
表B
skuId | skuPrice |
---|---|
1 | 100 |
2 | 200 |
3 | 300 |
4 | 400 |
5 | 500 |
1.统计某段日期内每个用户成功购买的商品情况,以如下格式列出
userName | skuid | skuNum |
---|---|---|
张三 | 1 | 9 |
张三 | 3 | 7 |
李四 | 2 | 10 |
参考答案:
SELECT userName,skuId,SUM(skuNum) skuNum FROM a where isSuccess =1
group by skuId
ORDER BY CONVERT(substr(userName,1,1) USING GBK) desc;
很多人就忽略掉ORDER BY CONVERT(substr(userName,1,1) USING GBK) desc
这部分sql,为什么需要这部分?
有没有注意到两行的张三排在一起
?再看看原来的列表,李四在第二行,group by是不会进行排序的,所一定是人为进行了排序
userName,skuid,skuNum这三个字段,根据skuid,skuNum这两个字段排序都不可能有这个结果,所以只能是根据userName排序,张三,李四拼音首字母分别为Z,L,所以明显是倒序
已知myslq中数据表采用utf8字符集
时,中文不能直接按照拼音排
,所以得进行转义,转成GBK编码
,再进行排序,所以使用了CONVERT转换格式
瞎比比了…哈哈哈~我觉得答案是这样子的,但感觉不会考得这么变态吧
2.统计某段日期内每个Sku的销售情况,包括总需求数量,成功成交金额,以如下格式列出
skuId | totalSaleNum | totalAmout |
---|---|---|
1 | 39 | 900 |
2 | 10 | 2000 |
3 | 7 | 2100 |
参考答案(两种方式):
Answer1:
SELECT b.skuId,totalSaleNum,totalAmout FROM b
join (select skuId,sum(skuNum) totalSaleNum from a GROUP BY a.skuId) t1 on t1.skuId = b.skuId
join (select a.skuId,sum(skuNum)*skuPrice totalAmout from a,b
where a.skuId=b.skuId and isSuccess =1 GROUP BY a.skuId) t2 on t2.skuId = b.skuId
这里应该以表B为主表,且使用join
而不是left join
,否则会把skuId
为4,5的都显示出来了,自己可以操作一波哈
Answer2:
SELECT a.skuid,
(SELECT SUM(a.skuNum) FROM a WHERE a.skuid = b.skuId GROUP BY a.skuid) totalSaleNum,
SUM(a.skuNum)*b.skuPrice totalAmout
FROM a,b
WHERE a.skuid = b.skuId AND a.isSuccess = 1
GROUP BY a.`skuid`;
应该还可以其他的方法,都可以动手尝试一下~
以上均为参考答案,若有错误请指正,感谢!