数学类
选择题
11,81,343,625,243,( 1)
11的1次方,9的2次方,7的3次方,5的4次方,3的5次方
1的6次方,就是1
规定字符串内有很多正整数,要求对这些整数进行排序,然后返回排序后的字符串
排序要求:按照每个正整数的后三位数字组成的整数进行从小到大排序?
- 如果不足三位,则按照实际位数组成的整数进行比较?
- 如果相等或重复,则按照入字符串中的原始顺序排序
- 不可便用语自身排序方法和有相似效果的方式
说明(以下内容考生无须检查,调用者保证)
- 字符串内正整数之间以单个空格分隔,字符串首尾没有空格2. 正整数格式为十进制,大小:1-1000000正整数的数字非零开始
- 内置方法只能用字符串截取
示例
如字符串内容
1223 16 1016 1016 85965 15625 1568 22 3232 14753 1565 9856
按规定排序后
16 1016 1016 22 1223 3232 1565 1568 15625 14753 9856 85965
/**
* 面试题字符串排序
*
* @author dzh
*
*/
public class Sort {
/*
* 排序要求:
* 按照每个正整数的后三位数字组成的整数进行从小到大排序
* 1) 如果不足三位,则按照实际位数组成的整数进行比较
* 2) 如果相等或者重复,则按照输入字符串中的原始顺序排序
* 3) 不可使用语言自身排序方法和有相似效果的方式
*
* 说明(以下内容考生无需检查,调用者保证)
* 1) 字符串内正整数之间以单个空格分隔,字符串首尾没有空格
* 2) 正整数格式为十进制,大小:1~1,000,000,正整数的数字非零开始
* 3) 内置方法只能使用字符串截取和获取
* 实例:
* 如字符串内容:
* 1223 16 1016 1016 85965 15625 1568 22 3232 14753 1565 9856
* 按照规定排序后
* 16 1016 1016 22 1223 3232 1565 1568 15625 14753 9856 85965
* */
public static void main(String[] args) {
// 待排序字符串
String string = "1223 16 1016 1016 85965 15625 1568 22 3232 14753 1565 9856";
// 要求排序后结果
String string2 = "16 1016 1016 22 1223 3232 1565 1568 15625 14753 9856 85965";
String regex = " ";
System.out.println("原始字符串:" + string);
String result = sortString(string, regex);
System.out.println("排序后结果:" + result);
System.err.println("是否符合排序后要求:" + (result.equals(string2) ? "符合" : "不符合"));
}
/* @param string 待排序字符串
* @param regex 分割标识<例如空格,逗号等>
* @return java.lang.String 返回排序后字符串
* @author dzh
* @date 2019/5/6 13:54
*/
public static String sortString(String string, String regex) {
if (string.length() < 2) {
return string;
}
// 给定截取条件分割字符串为字符数组
String[] strings = string.split(regex);
// 创建等同长度整数型数组
int[] ints = new int[strings.length];
// 临时变量
int temp;
// 采用冒泡排序
for (int i = 0; i < strings.length-1; i++) {
ints[i] = Integer.parseInt(strings[i]);
}
for (int j = 0; j < ints.length; j++) {
for (int k = 0; k < ints.length - 1 - j; k++) {
// 取余后三位正整数(满足题目要求,不足三位按照实际位数进行比较)
if ((ints[k + 1] % 1000) < ints[k] % 1000) {
temp = ints[k + 1];
ints[k + 1] = ints[k];
ints[k] = temp;
}
}
}
// 返回排序后字符串
StringBuilder stringBuilder = new StringBuilder();
for (int num : ints) {
stringBuilder.append(num + regex);
}
return stringBuilder.toString().trim();
}
}
4. 1~100共一百个自然数,放入一个99个元素的数组a[99],找出没有放入的那个元素
int sumArr = 0;
int[] arr = new int[99];
for (int i = 0; i < 99; i++) {
// Math.random() 返回一个值为包0不包1的double
// nextInt(int n): 产生一个包含0,不包含n范围内的整数,没有参数产生正负21亿以内的整数
arr[i] = (int) ((Math.random() * 100) + 1);
for (int j = 0; j < i; j++) {
if (arr[j] == arr[i]) {
//如果随机生成的元素在数组中存在,则数组下标减一返回到此级重复判断
i--;
break;
}
}
}
for (int i = 0; i < arr.length; i++) {
sumArr += arr[i];
System.out.print(arr[i] + ",");
}
// 1~100的自然数之和减去99个数组元素之和就是剩下的那个数
System.out.println((1 + 100) * 50 - sumArr);
}
5. 九九乘法表
// 正三角九九乘法表
for (int i = 1; i <= 9 ; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + (j*i)+" " );
if (j==i){
System.out.println();
}
}
// 倒三角九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = i; j <= 9; j++) {
System.out.print(j + "*" + i + "=" + (j*i)+" " );
}
System.out.println();
}
6. 阿拉伯数字的金额转换成中国传统的形式
public static void main(String[] args) {
System.out.println(toUpcaseMoney(convert(100215)));
}
private static String toUpcaseMoney(String money) {
return new StringBuilder(money).toString().replaceAll("零[拾佰仟]", "零").replaceAll("零+万", "万")
.replaceAll("零+元", "元").replaceAll("零+", "零");
}
public static String convert(int money) {
char[] data = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};
char[] units = {'元', '拾', '佰', '仟', '万', '拾', '佰', '仟', '亿'};
StringBuffer sbf = new StringBuffer();
int unit = 0;
while (money != 0) {
sbf.insert(0, units[unit++]);
int number = money % 10;
sbf.insert(0, data[number]);
money /= 10;
}
return sbf.toString();
}
算法类
1. 冒泡排序
介绍
解释
什么是稳定?
相同两个数不会变换位置,张三的成绩是60,李四的成绩也是60,但是排序之前张三在李四的前面,排序之后如果张三还是在李四的前面,那么就是稳定,否则就是不稳定。
6个数,比完5次,最后一个数就是最大的数
5个数,再比4次,倒数第二个数就是二大的数
怎么比,用第一轮举例,
34和4比,调换位置,
34和56比,不调换位置,
56和17比,调换位置,
56和90比,不调换位置,
90和56比,调换位置
public void bubbleSort(int[] arr) {
// 外循环控制轮数
for(int i=0; i<arr.length-1; i++) { // 比较的轮数等于数组的长度-1
for(int j=0; j<arr.length-1-i; j++) { // 每轮比较的次数
if(arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
2. 选择排序
介绍
把0索引的元素,和索引1以后的元素都进行比较,第一次完毕,最小值出现在了0索引。
同理,其他的元素就可以排好。
第一轮,34和4比,4小,4和之后的所有元素比,还是4小,所以4和34交换位置,
第二轮,34和56比,34小,34和17比,17小,17依次和之后的所有元素比,还是17小,17和34交换位置
public static void selectSort(int[] arr) {
// 外循环控制轮数
for(int i=0; i<arr.length-1; i++) {
for(int j=i+1; j<arr.length; j++) {
if(arr[j] < arr[i]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
冒泡排序和选择排序的区别
冒泡排序通过比较相邻的元素来工作,每一轮遍历可能导致多次元素交换。这种频繁的交换使得冒泡排序在数据移动方面相对不那么高效。
选择排序则是通过在整个数列中寻找最小(或最大)元素来工作,每一轮遍历只会导致一次元素交换(即将找到的最小或最大元素放到正确的位置上)。这种差异使得选择排序在数据移动方面相对更加高效。
布隆过滤器的简单原理
还有更深入的原理,暂时先不了解
判断重复是没问题的,但是可能会漏掉一些数据(因为由于算法的原因,不同的初始数据可能会在经过算法后被判定为相同)
位数组的长度越大,误判的可能性就越低。
线程类
1. 设计4个线程,其中两个线程每次对j增加1,另外两个线程对j每次减少1。写出程序。
注:因为这4个线程共享J,所以线程类要写到内部类中。加线程:每次对j加一。减线程:每次对j减一
public class TestThreads {
private int j = 1;
// 加线程
private class Inc implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
inc();
}
}
}
// 减线程
private class Dec implements Runnable {
public void run() {
for (int i = 0; i < 10; i++) {
dec();
}
}
}
// 加1
private synchronized void inc() {
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
// 减1
private synchronized void dec() {
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
}
// 测试程序
public static void main(String[] args) {
TestThreads test = new TestThreads();
// 创建两个线程类
Thread thread = null;
Inc inc = test.new Inc();
Dec dec = test.new Dec();
// 启动4个线程
for (int i = 0; i < 2; i++) {
thread = new Thread(inc);
thread.start();
thread = new Thread(dec);
thread.start();
}
}
}
2. main函数和线程
package com.aihangxunxi.uc.common;
public class Note {
public static void main(String[] args) {
Thread t = new Thread(){
public void run(){
world();
}
};
// 这如果用run,就是worldhello,因为run()就是普通方法
// start()是启动线程,而main函数是入口,是主线程,所以必定是helloworld
t.start();
System.out.println("hello");
}
public static void world(){
System.out.println("world");
}
}
java类
1. Jdbc连Oracle的程序,并实现数据查询
package hello.ant;
import java.sql.*;
public class jdbc
{
String dbUrl="jdbc:oracle:thin:@127.0.0.1:1521:orcl";
String theUser="admin";
String thePw="manager";
Connection c=null;
Statement conn;
ResultSet rs=null;
public jdbc()
{
try{
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
c = DriverManager.getConnection(dbUrl,theUser,thePw);
conn=c.createStatement();
}catch(Exception e){
e.printStackTrace();
}
}
public boolean executeUpdate(String sql)
{
try
{
conn.executeUpdate(sql);
return true;
}
catch (SQLException e)
{
e.printStackTrace();
return false;
}
}
public ResultSet executeQuery(String sql)
{
rs=null;
try
{
rs=conn.executeQuery(sql);
}
catch (SQLException e)
{
e.printStackTrace();
}
return rs;
}
public void close()
{
try
{
conn.close();
c.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
ResultSet rs;
jdbc conn = new jdbc();
rs=conn.executeQuery("select * from test");
try{
while (rs.next())
{
System.out.println(rs.getString("id"));
System.out.println(rs.getString("name"));
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
2. switch之break穿透
// 如果是2的话,值是10
// 当case=2之后下面的case就不需要判断了,直接执行代码
public static int getValue(int i){
int result = 0;
switch (i){
case 1:
result = result + i;
case 2:
result = result + i * 2;
case 3:
result = result + i * 3;
}
return result;
}
3. i++
// ++,--单独使用都是+1或者-1
// 与赋值 运算符 打印等一起使用就是先输出n,再对n执行++,--
public static void main(String[] args) {
int n = 999;
n--;
++n;
System.out.println(n++);
}
4. 用栈实现括号匹配检验
{ 必须对应一个 }
[ 必须对应一个 ]
( 必须对应一个 )
E push(E item)
把项压入堆栈顶部。
E pop()
移除堆栈顶部的对象,并作为此函数的值返回该对象。
E peek()
查看堆栈顶部的对象,但不从堆栈中移除它。
boolean empty()
测试堆栈是否为空。
int search(Object o)
返回对象在堆栈中的位置,以 1 为基数。
package sience;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Stack;
public class KuoHaoPiPeiJianYan {
/**
* 在我们日常的代码中,代码编辑器经常帮我们校验括号的闭合性,即
* <p>
* { 必须对应一个 }
* [ 必须对应一个 ]
* ( 必须对应一个 )
* 思路很简单,如果是左边括号入栈,
* 如果是右边括号与栈顶部也就是左边的括号进行匹配
* 匹配成功就弹栈,这样如果最后栈中还有元素,那么括号就是不闭合的
*/
public static void main(String[] args) throws Exception {
String expression = "{((1+3)+2+4)+9*7}";
String expression2 = "{b*a[1]+d*(c-d)}";
String expression3 = "object.call(2]";
String expression4 = "person.do(a[2)]";
System.out.println("请输入一个表达式:");
checkout();
}
public static void checkout() throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
Stack<Character> stack = new Stack<>();
//读入一行表达式
String str = reader.readLine();
//把表达式转换成字符数组,便于后面操作
char[] ch = str.toCharArray();
for (int i = 0; i < ch.length; i++) {
//判断是否是右括号,如果不是就进栈
if(ch[i] == '{' || ch[i] =='[' || ch[i] =='('){
stack.push(ch[i]);
}
if (ch[i] == '}' && stack.peek() == '{') {
stack.pop();
} else if (ch[i] == ']' && stack.peek() == '[') {
stack.pop();
} else if (ch[i] == ')' && stack.peek() == '(') {
stack.pop();
}
}
//如果栈最后是空的,表明所有的括号,都匹配正确了
if (stack.empty()) {
System.out.println("正确!");
} else {
System.out.println("不正确!");
}
}
}
5. 给定一个没有重复数字的列表,输出打印所有可能的顺序(这个实在不好理解啊,有时间再看吧)
public static void generate(int[] numbers, Stack<Integer> usedStack, List<List<Integer>> resultList) {
//循环终止条件,栈长为数组长
if (usedStack.size() == numbers.length) {
List<Integer> curResList = new ArrayList<>(usedStack);
resultList.add(curResList);
return;
}
for (int i = 0; i < numbers.length; i++) {
int curNumber=numbers[i];
//当前数不在栈内
if (!usedStack.contains(curNumber)) {
//当前数入栈
usedStack.push(curNumber);
generate(numbers, usedStack, resultList);
//最后入栈的数出栈
// 上面的return之后,就会走到这
// 就类似于大房子里面有小房子,小房子走出去就是大房子了,这也就是小方法走出去后就走大方法,
// 这么想会明白一些
usedStack.pop();
}
}
}
// permute排列
public static List<List<Integer>> permute(int[] numbers) {
List<List<Integer>> resultList = new ArrayList<>();
generate(numbers, new Stack<>(), resultList);
return resultList;
}
public static void main(String[] args) {
System.out.println(permute(new int[]{1, 2, 3}));
System.out.println("------------");
System.out.println(permute(new int[]{1, 2, 3, 4}));
}
找到链表的第n个节点和最后一个节点
package sience.LinkedList;
/**
* 链表中的节点类
*/
public class Node {
int data;
Node next;
public Node(int data)
{
this.data=data;
}
}
package sience.LinkedList;
public class ListNode {
public static Node getSingleList(){
Node head=new Node(3);
Node node1=new Node(6);
Node node2=new Node(8);
Node node3=new Node(6);
Node node4=new Node(2);
head.next=node1;
node1.next=node2;
node2.next=node3;
node3.next=node4;
node4.next=null;
return head;
}
public static void printList(Node node){
System.out.print("List:");
while(node!=null){
System.out.print(node.data+"-->");
node=node.next;
}
System.out.println();
}
// 快速创建链表
private static Node buildLinkList(int[] array){
Node head = new Node(array[0]);
Node p = head;
for(int i=1; i<array.length; i++){
p.next = new Node(array[i]);
p = p.next;
}
return head;
}
}
package sience.LinkedList;
/**
* 链表
*/
public class LinkedList {
public static void main(String[] args) {
Node head = ListNode.getSingleList();
ListNode.printList(head);
// int num = 3;
// Node node = new LinkedList().searchNum(head, num);
// System.out.println("第" + num + "个节点的元素为:" + id.data);
// Node node = new LinkedList().searchNumLast(head);
// System.out.println("该链表的最后一个节点为:" + node.data);
}
/**
* 找到该链表的第m个节点
*
* @param head
* @param num
* @return
*/
public Node searchNum(Node head, int num) {
if (head != null && num > 0) {
for (int i = 1; i < num; i++) {
if (head.next == null) {
return new Node(-1);
}
head = head.next;
}
}
return head;
}
/**
* 找到该链表的最后一个节点
*
* @param head
* @return
*/
public Node searchNumLast(Node head) {
Node node = new Node(-1);
if (head == null) return node;
while (head.next != null) {
head = head.next;
}
node = head;
return node;
}
}
部分知识引用自
https://www.cnblogs.com/huiyi0521/p/10819580.html
https://blog.csdn.net/elice_/article/details/84314334
诚实是一封见不得人的情书,压藏在枕头下面,却无意识露出一个信封的直角,像是在引诱人把它抽出来偷看。
房思琪的初恋乐园
林奕含