1.定义读入对象
static Scanner sc=new Scanner(System.in);
2.数据类型转换
int x=123;
String sx=String.valueOf(x);
String sy="321";
int y=Integer.parseInt(sy);
String str="abc";
char[] s=str.toCharArray();
String ss=String.valueOf(s);
3.String常用操作
- public char charAt(int index):返回字符串中第index个字符;
- public int length():返回字符串的长度;
- public int indexOf(String str):返回字符串中第一次出现str的位置;
- public int indexOf(String str,int fromIndex):返回字符串从fromIndex开始第一次出现str的位置;
- public String substring(int beginIndex):返回该字符串从beginIndex开始到结尾的子字符串;
- public String substring(int beginIndex,int endIndex):返回该字符串从beginIndex开始到endsIndex结尾的子字符串
- public int compareTo(String str):比较字符串的大小,小于返回负数,大于返回正数,相等返回0
- public boolean equals(String str):判断字符串是否一样
- public char[] toCharArray () :将此字符串转换为新的字符数组
- public String[] split(String regex):将一个字符串按照指定的分隔符分隔,返回分隔后的字符串数组
split() 方法根据匹配给定的正则表达式来拆分字符串。
注意: . 、 | 和 * 等转义字符,必须得加 \\。
注意:多个分隔符,可以用 | 作为连字符。
String[] s=str.split(" +"); String[] s=str.split("\\s+"); 以一个或多个空格分割
- public String replace (CharSequence target, CharSequence replacement) :将与target匹配的字符串使用replacement字符串替换。
- String replaceAll(String regex, String replacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串
String ss=str.replaceAll(" +",","); String ss=str.replaceAll("\\s+",","); 二者都能把一个或多个空格换成逗号,没有学过正则表达式,具体区别并不懂
- String类型不可改变,如果需要改变可以使用StringBuilder
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
String s="abc def ghi";
String[] a=s.split(" ");//a[0]=abc a[1]=def a[2]=ghi
for(int i=0;i<a.length;i++) {
System.out.print("a["+i+"]="+a[i]+" ");
}
System.out.println();
String str="abcabc";
char[] ch=str.toCharArray();
//ch[0]=a ch[1]=b ch[2]=c ch[3]=a ch[4]=b ch[5]=c
for(int i=0;i<ch.length;i++) {
System.out.print("ch["+i+"]="+ch[i]+" ");
}
System.out.println();
System.out.println(str.indexOf("b"));//1
System.out.println(str.indexOf("b",3));//4
System.out.println(str.substring(3));//abc
System.out.println(str.substring(3,5));//ab
System.out.println(str.compareTo("abc"));//3
System.out.println(str.compareTo("abcabcabc"));//-3
System.out.println(str.compareTo("abcabc"));//0
System.out.println(str.equals("abcabc"));//true
System.out.println(str.equals("abc"));//false
System.out.println(str.replace("abc","ac"));//acac
System.out.println(str.toLowerCase());//abcabc
System.out.println(str.toUpperCase());//ABCABC
}
}
4.StringBuilder
- 创建Stringbuilder对象:StringBuilder strB = new StringBuilder();
- append(String str) / append(Char c):字符串连接
- toString():返回一个与构建起或缓冲器内容相同的字符串
- setCharAt(int i, char c):将第 i 个代码单元设置为 c(可以理解为替换)
- insert(int offset, String str) / insert(int offset, Char c):在指定位置之前插入字符(串)
- delete(int startIndex,int endIndex):删除起始位置(含)到结尾位置(不含)之间的字符串
- length():获得长度
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
public static void main(String[] args) {
//输入abc
StringBuilder strB=new StringBuilder(sc.next());
System.out.println(strB.toString());//abc
//输入def
strB.append(sc.next());
System.out.println(strB.toString());//abcdef
//将第2个代码单元设置为m
strB.setCharAt(2,'m');
System.out.println(strB.toString());//abmdef
//在第4个代码单元之前插入pq
strB.insert(4,"pq");
System.out.println(strB.toString());//abmdpqef
//删除下标[2,5)之间的字符串
strB.delete(2,5);
System.out.println(strB.toString());//abqef
}
}
5. Java使用class实现结构体及其排序
例题:按分数从高到低输出上线考生的考号与分数,若有多名考生分数相同,则按他们考号的升序输出。
Comparator(类似与c++ cmp函数的写法)
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static class student{
String ID;
int score;
public student(String ID,int score) {
this.ID=ID;
this.score=score;
}
}
static student[] stu=new student[1005];
static Comparator cmp=new Comparator<student>() {
public int compare(student a,student b) {
if(a.score!=b.score) return b.score-a.score;//分数从高到低
else return a.ID.compareTo(b.ID);//字典序从小到大
}
};
static int mp[]=new int[15];
public static void main(String[] args) {
int N,M,G;
while(sc.hasNext()) {
N=sc.nextInt();
if(N==0) break;
M=sc.nextInt();
G=sc.nextInt();
for(int i=1;i<=M;i++) mp[i]=sc.nextInt();
int cnt=0;
for(int i=1;i<=N;i++) {
String s=sc.next();
int m=sc.nextInt();
int sum=0;
for(int j=1;j<=m;j++) {
sum+=mp[sc.nextInt()];
}
if(sum>=G)
stu[cnt++]=new student(s,sum);
}
Arrays.sort(stu,0,cnt,cmp);
System.out.println(cnt);
for(int i=0;i<cnt;i++) {
System.out.println(stu[i].ID+" "+stu[i].score);
}
}
}
}
Comparable(类似于C++ 重载小于号)
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static class student implements Comparable<student>{
String ID;
int score;
public student(String ID,int score) {
this.ID=ID;
this.score=score;
}
public int compareTo(student other) {
if(this.score!=other.score) return other.score-this.score;
else return (this.ID).compareTo(other.ID);
}
}
static student[] stu=new student[1005];
static int mp[]=new int[15];
public static void main(String[] args) {
int N,M,G;
while(sc.hasNext()) {
N=sc.nextInt();
if(N==0) break;
M=sc.nextInt();
G=sc.nextInt();
for(int i=1;i<=M;i++) mp[i]=sc.nextInt();
int cnt=0;
for(int i=1;i<=N;i++) {
String s=sc.next();
int m=sc.nextInt();
int sum=0;
for(int j=1;j<=m;j++) {
sum+=mp[sc.nextInt()];
}
if(sum>=G)
stu[cnt++]=new student(s,sum);
}
Arrays.sort(stu,0,cnt);
System.out.println(cnt);
for(int i=0;i<cnt;i++) {
System.out.println(stu[i].ID+" "+stu[i].score);
}
}
}
}
6.List
ArrayList:可变大小数组
- ArrayList底层是用数组实现的,可以认为ArrayList是一个可改变大小的数组。随着越来越多的元素被添加到ArrayList中,其规模是动态增加的。
- 查询和修改较快,增添和删除较慢
LinkedList:链表
- LinkedList底层是通过双向链表实现的。
- 增添和删除较快,查询和修改较慢
Vector:不建议使用(Vector使用synchronized,必然会影响效率)
- Vector和ArrayList一样,都是通过数组实现的,但是Vector是线程安全的。和ArrayList相比,其中的很多方法都通过同步(synchronized)处理来保证线程安全。
- 二者之间还有一个区别,就是扩容策略不一样。在List被第一次创建的时候,会有一个初始大小,随着不断向List中增加元素,当List认为容量不够的时候就会进行扩容。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList增长原来的50%。
常用方法:
- boolean add(Object e):在末尾插入元素
- void add (int index, Object element):在指定位置插入元素,以前元素通通后移一位
- Object set (int index,Object element):修改指定位置的元素
- Object get (int index):返回指定位置的元素
- Object remove (int index):删除指定位置的元素,后面元素通通前移一位
注意:
- 遍历ArrayList用for循环快一点
- 遍历LinkedList用forEach会快好多
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static List<Integer> arraylist=new ArrayList<Integer>();
static List<Integer> linkedlist=new LinkedList<Integer>();
static void query() {//查询
for(int i=0;i<arraylist.size();i++) {
System.out.print(arraylist.get(i)+" ");
}
System.out.println();
for(int i=0;i<linkedlist.size();i++) {
System.out.print(linkedlist.get(i)+" ");
}
System.out.println();
// forEach循环
for(Integer x:arraylist) {
System.out.print(x+" ");
}
System.out.println();
for(Integer x:linkedlist) {
System.out.print(x+" ");
}
System.out.println();
}
public static void main(String[] args) {
//增 --在末尾增
for(int i=0;i<=10;i++) {
arraylist.add(i);
linkedlist.add(i);
}
query();//0 1 2 3 4 5 6 7 8 9 10
//删 --把第0个元素删掉
arraylist.remove(0);
linkedlist.remove(0);
query();//1 2 3 4 5 6 7 8 9 10
//增 --在下标1处增一个元素0
arraylist.add(1,0);
linkedlist.add(1,0);
query();//1 0 2 3 4 5 6 7 8 9 10
//改 --把下标为1的那个元素改为2
arraylist.set(1,2);
linkedlist.set(1,2);
query();//1 2 2 3 4 5 6 7 8 9 10
}
}
二维ArrayList
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static int INF=0x3f3f3f3f;
static int N=200005;
static char s[]=new char[N];
static ArrayList[] pos=new ArrayList[N];
static void init() {
for(int i=0;i<26;i++) {
pos[i]=new ArrayList<Integer>();
}
}
public static void main(String[] args) {
init();
int n=sc.nextInt();
int k=sc.nextInt();
String string=sc.next();
s=string.toCharArray();
for(int i=0;i<n;i++) {
pos[s[i]-'a'].add(i);
}
int ans=INF;
for(int i=0;i<26;i++) {
int len=pos[i].size();
for(int j=0;j+k-1<len;j++) {
int a=
ans=Math.min(ans,(int)pos[i].get(j+k-1)-(int)pos[i].get(j)+1);
}
}
if(ans==INF) ans=-1;
System.out.println(ans);
}
}
7.Map
定义:
- TreeMap: static Map<String,Integer> map=new TreeMap<String,Integer>();
- HashMap: static Map<String,Integer> map=new HashMap<String,Integer>();
常用操作:
- V put(K key,V value):添加元素。这个其实还有另一个功能?替换
如果键是第一次存储,就直接存储元素,返回null
如果键不是第一次存在,就用值把以前的值替换掉,返回以前的值
- void clear():移除所有的键值对元素
- V remove(Object key):根据键删除键值对元素,并把值返回
- int size():返回集合中的键值对的对数
- V get(Object key):根据键获取值
- boolean containsKey(Object key):判断集合是否包含指定的键
- boolean containsValue(Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
- Set<Map.Entry<K,V>> entrySet(): 返回一个键值对的Set集合
- Set keySet():获取集合中所有键的集合
- Collection values():获取集合中所有值的集合
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static Map<String,Integer> map=new TreeMap<String,Integer>();
// static Map<String,Integer> map=new HashMap<String,Integer>();
static void query() {
//forEach:通过Map.entrySet遍历key和value(效率高?)
for(Map.Entry<String,Integer> entry:map.entrySet()) {
System.out.print(entry.getKey()+":"+entry.getValue()+" ");
}
System.out.println();
//forEach:利用 keyset 集合遍历map
for(String key:map.keySet()) {
System.out.print(key+":"+map.get(key));
}
System.out.println();
//通过Iterator
}
public static void main(String[] args) {
map.put("ac",1);
map.put("wa",0);
query();//ac:1 wa:0
map.put("ac",666);
System.out.println(map.get("ac"));//666
query();//ac:666 wa:0
System.out.println(map.size());//2
map.remove("wa");
query();//ac:666
System.out.println(map.size());//1
}
}
8.Set
定义:
- TreeSet: static Set<Integer> set=new TreeSet<Integer>();
- Hashset:static Set<Integer> set=new HashSet<Integer>();
常用操作
- add( ) : 向集合中添加元素
- clear( ):去掉集合中所有的元素
- contains( ): 判断集合中是否包含某一个元素
- isEmpty( ):判断集合是否为空
- remove( ) :从集合中去掉特定的对象
- size( ) : 返回集合的大小
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static Set<Integer> set=new TreeSet<Integer>();
// static Set<Integer> set=new HashSet<Integer>();
public static void main(String[] args) {
set.add(1);
set.add(2);
set.add(3);
System.out.println(set.contains(1));//true
System.out.println(set.size());//3
set.remove(1);
System.out.println(set.size());//2
System.out.println(set.contains(1));//false
//forEach遍历 输出结果为:2 3
for(Integer x:set) {
System.out.print(x+" ");
}
}
}
9.Queue
定义
- Queue: static Queue<Integer> q=new LinkedList<Integer>();
- PriorityQueue:static PriorityQueue<Integer> pq=new PriorityQueue<Integer>();
常用操作
- boolean offer(E e):添加一个元素并返回true 如果队列已满,则返回false
- E poll():移除并返问队列头部的元素 如果队列为空,则返回null
- E peek():返回队列头部的元素 如果队列为空,则返回null
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static Queue<Integer> q=new LinkedList<Integer>();
static PriorityQueue<Integer> pq=new PriorityQueue<Integer>();
public static void main(String[] args) {
/*--Queue--*/
//添加
q.offer(0);
q.offer(3);
q.offer(2);
q.offer(1);
//删除队首并返回队首的值
System.out.println(q.poll());//0
//返回队首值
System.out.println(q.peek());//3
//forEach 输出结果为:3 2 1
for(Integer x:q) {
System.out.print(x+" ");
}
System.out.println();
/*--PriorityQueue--*/
//添加
pq.offer(0);
pq.offer(3);
pq.offer(2);
pq.offer(1);
//删除队首并返回队首的值
System.out.println(pq.poll());//0
//forEach 输出结果为:1 3 2(用forEach并不会排序输出)
for(Integer x:pq) {
System.out.print(x+" ");
}
System.out.println();
//返回队首值
System.out.println(pq.peek());//1
//while循环单个输出 输出结果为:1 2 3
while(!pq.isEmpty()) {
System.out.print(pq.poll()+" ");
}
}
}
10.Stack
定义:static Stack<Integer> s=new Stack<Integer>();
常用操作:
- Object peek( ):查看堆栈顶部的对象,但不从堆栈中移除它。
- Object pop( ):移除堆栈顶部的对象,并作为此函数的值返回该对象。
- Object push(Object element):把项压入堆栈顶部。
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static Stack<Integer> s=new Stack<Integer>();
public static void main(String[] args) {
s.push(1);
s.push(2);
s.push(3);
System.out.println(s.peek());//3
System.out.println(s.pop());//3
System.out.println(s.peek());//2
s.push(3);
//forEach 输出结果:1 2 3(不符合后进先出)
for(Integer x:s) {
System.out.print(x+" ");
}
System.out.println();
//while 输出结果:3 2 1
while(!s.isEmpty()) {
System.out.print(s.pop()+" ");
}
}
}
11.全排列
import java.util.*;
public class Main {
static Scanner sc=new Scanner(System.in);
static char s[]=new char[15];
static void swap(char s[],int i,int j) {//交换函数
char tmp=s[i];
s[i]=s[j];
s[j]=tmp;
}
static void reverse(char s[],int begin,int end) {//逆序函数
while(begin<end) {
char tmp=s[begin];
s[begin]=s[end-1];
s[end-1]=tmp;
begin++;
end--;
}
}
static void fullsort(char s[],int begin,int end) {//递归实现全排列
if(begin==end) {
System.out.println(s);
return ;
}
for(int i=begin;i<end;i++) {
swap(s,i,begin);
fullsort(s,begin+1,end);
swap(s,i,begin);
}
}
static boolean next_permutation(char s[],int begin,int end) {//下一个字典序
int i=end-1;
while(i>begin&&s[i-1]>=s[i]) i--;
if(i==begin) return false;
i--;
int j=end-1;
while(j>i&&s[j]<=s[i]) j--;
swap(s,i,j);
reverse(s,i+1,end);
return true;
}
public static void main(String[] args) {
String str=sc.next();
s=str.toCharArray();
Arrays.sort(s);
do {
System.out.println(s);
}while(next_permutation(s,0,s.length));
}
}
12.双端队列
定义:Deque<Integer> q=new LinkedList<Integer>();
常用方法:
- offerFirst(Object e);队首插入
- offerLast(Object e); 队尾插入
- pollFirst();队首删除
- pollLast();队尾删除
- peekFirst();队首获取
- peekLast();队尾获取
/*
滑动窗口的最大值
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。
例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,
他们的最大值分别为{4,4,6,6,6,5};
针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个:
{[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1},
{2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。
*/
import java.util.*;
public class Solution {
public ArrayList<Integer> maxInWindows(int [] num, int size)
{
ArrayList<Integer> ans=new ArrayList<Integer>();
if(size==0) return ans;
Deque<Integer> q=new LinkedList<Integer>();
for(int i=0;i<size-1;i++){
while(q.peekLast()!=null&&num[q.peekLast()]<=num[i]){
q.pollLast();
}
q.offerLast(i);
}
for(int i=size-1;i<num.length;i++){
while(q.peekFirst()!=null&&i-q.peekFirst()+1>size){
q.pollFirst();
}
while(q.peekLast()!=null&&num[q.peekLast()]<=num[i]){
q.pollLast();
}
q.offerLast(i);
ans.add(num[q.peekFirst()]);
}
return ans;
}
}