算法练习总结
- 简单——算法训练
- 02、课堂上布置的作业
- 1、创建方法,输入指定目录,删除目录
- 2、拷贝某个文件夹到另一个文件夹
- 3、实现读取文件反转
- 4、多线程读取文件
- 5、编写方法实现把指定图片拷贝到指定目录下(10分)
- 6、使用随机文件流类RandomAccessFile将一个文本文件(不包含中文)倒置读出。(10分)
- 7、使用流统计一个文件(不包含中文)中各个字母出现次数,打印结果为:(A(8),B(16),C(10)...Z(2),a(12),b(10),c(3)....,z(1))括号内代表字符出现次数;(10分)
- 8、写一个查询隐藏文件的方法,传入文件夹,查询该文件夹和下面的所有子文件的隐藏文件并打印出绝对路径(10分), 查询隐藏文件包括子文件,并打印出隐藏文件的绝对路径
- 9、使用合适的流把一个包含26个字母的文件,前10个字母替换成任意的大写字母,把后最后10个字母替换为任意的数字
简单——算法训练
01计算水仙花数
~~~public class Daffodils01Test {
public static void main(String[] args) {
//个、十、百位值
int bits,ten,hundred;
for (int i=100;i<1000;i++){
hundred = i/100;
ten = (i%100)/10;
bits = (i%100)%10;
if (i==(Math.pow(ten,3)+Math.pow(bits,3)+Math.pow(hundred,3))){
System.out.println(i);
}
}
}
}
02输入一行字符,分别统计出其中英文字母、数字、空格和其他字符的个数。
import java.util.Scanner;
public class Statistical02 {
public static void main(String[] args) {
/** 分别对应的ASCLLIL值
* a 97
* z 122
* A 65
* Z 90
*
* 1 49
* 2 57
* 英文字母 65-90 97-122
* 数字 49-57
* 空格 32
*/
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
char[] chars = str.toCharArray();
//对应索引分别统计:0:是英文 1:是数字 2:是空格 3:是其它字符
int[] count = new int[4];
//给初始值
for (int i = 0; i < count.length; i++) {
count[i]=0;
}
for (int i = 0; i < chars.length; i++) {
//英文字母的判断 数字的判断 空格判断 其它字符的判断
if((chars[i]>=65&&chars[i]<=90)||(chars[i]>=97&&chars[i]<=122)){
count[0]++;
}else if(chars[i]>=49&&chars[i]<=57){
count[1]++;
}else if(chars[i]==32){
count[2]++;
}else {
count[3]++;
}
}
for (int i = 0; i < count.length; i++) {
System.out.print(count[i]+" ");
}
}
}
03、排序两种算法
import java.util.Arrays;
public class SortTest {
public static void main(String[] args) {
int[] num = {3,2,1,9,10};
// bubbling(num);//冒泡排序
selectionSort(num);//选择排序
System.out.println(Arrays.toString(num));
}
/**
* 选择排序:
* 遍历找到比初始最大值得索引,并记录该最大值的索引,然后进行交换
*/
public static void selectionSort(int[] num){
//获取数组的最值
for (int i = 1 ; i < arr.length ;i++){
//定义变量,保存数组的第一个元素
int min = arr[i-1]; //[1-1 = 0]
//定义记录最小值索引
int minIndex = i-1;
for(int j = i ; j < arr.length ; j++){
if (min > arr[j]){
//记录的索引
minIndex = j;
//记录最小值
min= arr[j];
}
}
//位置交换
if (minIndex != (i-1)){
int temp = arr[i-1];
arr[i-1] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
/**
* 冒泡排序
* 每一轮找到一个最大值,然后冒泡冒出去
* @param num
*/
public static void bubbling(int[] num){
//外层控制比较轮次,i,内层j控制比较次数
for (int i = 0;i<num.length;i++){
for (int j = 0; j <num.length-i-1 ; j++) {
if(num[j]>num[j+1]){
int temp = num[j];
num[j] = num[j+1];
num[j+1]=temp;
}
}
}
}
}
04、数组的二分查找(折半查找)
说明:数组的基本搜索法 : 判断一个元素是否存在于数组中
遍历数组,查找就可以
二分搜索法提高效率 : 前提是数组必须是有序的.
/**
* 数组的二分搜索法
* 返回查找的元素在数组中的索引,没有呢返回负数
*/
public static int binarySearch(int[] arr,int key){
int min = 0 ; //数组的最小索引
int max = arr.length - 1; //数组的最大索引
int mid ;//数组折半后的,中间位置的索引
//循环折半,次数不定,while循环
//条件,,最小索引不能超过最大索引
while (min <= max){
//折半
mid = (min + max) / 2;
//折半后的mid作为索引,取出数组的元素,和关键字比较
if (key > arr[mid])
//移动最小索引
min = mid + 1;
else if (key < arr[mid])
//移动最大索引
max = mid - 1;
else {
//查找到了,返回索引
return mid;
}
}
return -1;
}
05、两个算法:对称,统计字母
package com.qf.ran.homework;
/**
* @author Ran
* @since JDK 1.8
*
* 1.编写方法判断字符串是否对称(不使用反转)
*
* 2.v82r20hFfwewfp130ungoihvAFQVCsvqa
* 判断以上字符串有多少数字,小写字母,大写字母
*/
public class Demo01 {
public static void main(String[] args) {
String str = "abbba";
boolean b = symmetry(str);//判断字符串是否对称
System.out.println("是否堆成 : " + b);
String str2 = "v82r20hFfwewfp130ungoihvAFQVCsvqa";
countMeorth(str2);//判断有多少数字、小写字母、大写字母
}
/**
* 判断指定字符串中有的数字、小写字母、大写字母
*
*/
public static void countMeorth(String str){
char[] chars = str.toCharArray();//将字符串转换成字符串数组,方便遍历
//分别定义统计数字、小写字母、大写字母的变量并全部初始化全为0
int countNum=0,countLower=0,countUpper=0;
//循环判断每个字符所对应的字符
for (int i = 0; i < chars.length; i++) {
//为数字的时候统计
if((chars[i]>='0')&&(chars[i]<='9')){
countNum++;
}else if(chars[i]>='A'&&chars[i]<='Z'){//字符为大写字母的时候统计
countUpper++;
}else if(chars[i]>='a'&&chars[i]<='z'){//字符为小写字母的时候统计
countLower++;
}
}
//统计好之后分别输出
System.out.println("countNum = " + countNum);
System.out.println("countUpper = " + countUpper);
System.out.println("countLower = " + countLower);
}
/**
* 判断字符串是否堆成
* @param str
* @return
*/
public static boolean symmetry(String str){
char[] chars = str.toCharArray();//将字符串转成字符数组
int length = chars.length-1;//辅助遍历,定义一个记录数组的最后一个值
//组开始遍历,从两头开始,第一个和数组得最后一个值,同时遍历进行比较,如果值能对得上到结束,就返回true;如果对不上就返回false;
for (int i = 0; i < chars.length/2; i++) {
if(chars[i]!=chars[length--]){
return false;
}
}
return true;
}
}
06、字符匹配的两种算法
暴力匹配与KMP匹配
package datastructure.Kmp;
import java.util.Arrays;
public class KMPTest {
public static void main(String[] args) {
String str1 = "BBC ABCDAB ABCDABDCDABDE";
String str2 = "ABCDABD";
int[] next = kmpNext("ABCDABD");
int index = kmpSearch(str1,str2,next);
System.out.println("index = " + index);
System.out.println(Arrays.toString(next));
}
//写出搜索算法
/**
*
* @param str1 源字符串
* @param str2 子串
* @param next 部分匹配表,是子串对应的部分匹配表
* @return 如果是-1就是没有匹配到,否则返回第一个匹配的位置
*/
public static int kmpSearch(String str1,String str2,int[] next){
//遍历
for (int i = 0,j=0;i<str1.length();i++){
//需要处理str1.charAt(i) !=str2.charAt(j)情况
//KMP算法核心
while (j>0&&str1.charAt(i)!=str2.charAt(j)){
j = next[j-1];
}
if(str1.charAt(i) ==str2.charAt(j)){
j++;
}
if (j==str2.length()){
return i-j+1;
}
}
return -1;
}
//获取到一个字符串(子串)的部分匹配表
public static int[] kmpNext(String dest){
//创建一个next 数字保存部分匹配值
int[] next = new int[dest.length()];
next[0] = 0;//如果字符串长度为1,部分匹配值就是0
for (int i = 1,j=0; i < dest.length(); i++) {
//当dest.charAt(i)!=dest.charAt(j),我们需要从next[j-1]获取新的i
//直到我们发现est.charAt(i)==dest.charAt(j)才退出
//这是Kmp算法的核心点
while (j>0&&dest.charAt(i)!=dest.charAt(j)){
j = next[j-1];
}
//当dest.charAt(i) == dest.charAt(j)满足时,部分匹配值+1
if(dest.charAt(i) == dest.charAt(j)){
j++;
}
next[i] = j;
}
return next;
}
}
07、数组扩容
package com.qianfeng.day13;
public class Dilatation {
public static void main(String[] args) {
int[] arr = {1,2,4,6};
//扩容后的数组重新指向
arr = grow(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println("arr[i] = " + arr[i]);
}
}
/**
* 数组扩容为原来的1.5倍
* @param arr
* @return 新的数组长度
*/
public static int[] grow(int[] arr){
int[] newArr = new int[arr.length+(arr.length>>1)];//新建一个数组,数组为arr原来数组的1.5倍
System.out.println("newArr.length = " + newArr.length);
//将旧数组的数据迁移到新的数组
for (int i = 0; i < arr.length; i++) {
newArr[i] = arr[i];
}
return newArr;
}
}
08、LinkedList遍历的四种方式
package com.qianfeng.day13;
import java.util.Iterator;
import java.util.LinkedList;
public class LinklistTest {
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println("--for循环遍历--");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("--foreach循环遍历--");
for(Object ob:list){
System.out.println(ob);
}
System.out.println("--迭代器循环遍历--");
Iterator it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("--lambda表达--");
list.forEach(obj-> System.out.println(obj));
}
}
02、课堂上布置的作业
1、创建方法,输入指定目录,删除目录
package com.qianfeng.homeword.day16;
import org.junit.Test;
import java.io.File;
import java.util.Arrays;
import java.util.Scanner;
/**
* 创建方法,输入指定目录,删除目录
* 思路
* 1、控制台接收一个路径
* 2、递归将所有目录内的文件给删除
* 删除目录的条件:就是该文件是一个空文件。
*/
public class Rmdir {
public static void main(String[] args) {
//输入路径传入路径
Scanner sc = new Scanner(System.in);
String dir = sc.next();
delDir(new File(dir));
}
public static void delDir(File dir) {
File[] dirArray = dir.listFiles();
//删除递归过后的第三层空文件夹
if (dirArray.length==0){
dir.delete();
}
//遍历文件夹
for (int i = 0; i < dirArray.length; i++) {
//判断是否是目录,是目录就遍历,不是目录就删除。
if(dirArray[i].isDirectory()){
delDir(dirArray[i]);
//删除第一层文件夹
dirArray[i].delete();
}else {
System.out.println(dirArray[i]);
dirArray[i].delete();
}
}
//删除给定路径的最后一个问价夹
dir.delete();
}
}
2、拷贝某个文件夹到另一个文件夹
package com.qianfeng.homeword.day17;
import com.qianfeng.day17.IOutility;
import org.junit.Test;
import java.io.*;
/**
* 作业
* 1、给定一个指定的路径目录,拷贝其目录文件(视频、图片、文本),目录内呈现成什么样,拷贝到新的文件夹也需遥呈现出什么样
* 思路:
* 1)、要判断文件内是否存在目录
* 2)、Buffice,用缓冲字节流进行拷贝
* 3)、进到一个文件夹创建一个文案夹的名字
* 这需要单独获取文件名:getName;
*思路过程:
* 给定一个拷贝的路径
* 放到指定的路径中的文件夹中去
*/
//获取文件夹名字>创建文件夹>将相同文件夹名字拷贝到对应的文件夹
/**
* C:\Users\DXboys\Desktop\entre
* getName():entre
* mkdir():创建目录:entre
*C:\Users\DXboys\Desktop\entre\3.txt
* createNewFile()//创建指定文件夹,3.txt;
*/
public class Copy{
public static void main(String[] args) {
File source = new File("C:\\Users\\DXboys\\Desktop\\Source");//拷贝文件源
File target = new File("C:\\Users\\DXboys\\Desktop\\target");//拷贝的指定路径
copyDir(source,target);
}
/**
* 源数组的遍历
* @param
* 源路径,目标路径
*/
//拷贝文件
public static void copyFile(File source,File target){
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(source);//创建输入流
fos = new FileOutputStream(target);//创建输出流
//创建数据缓冲区
byte[] b = new byte[1024];
int len;
//循环写入新的文件
while ((len=fis.read(b))!=-1){
fos.write(b,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
IOutility.closeAll(fis,fos);
}
}
/**
* 复制目录
* @param source 源路径
* @param target 目标路径
*/
public static void copyDir(File source,File targetDir){
//创建文件夹,
new File(String.valueOf(targetDir)).mkdirs();
//获取文件所在的列表
File[] pathArray = source.listFiles();
for (int i = 0; i < pathArray.length; i++) {
//判断是否是文件,是文件的话直接拷贝到当前的路径
if(pathArray[i].isFile()){
copyFile(pathArray[i],new File(targetDir,pathArray[i].getName()));
}
//如果是目录,调用文件
if(pathArray[i].isDirectory()){
copyDir(pathArray[i],new File(targetDir,pathArray[i].getName()));
}
}
}
}
3、实现读取文件反转
package com.qianfeng.homeword.day18.readTheReverse;
import org.junit.Test;
import java.io.*;
import java.lang.reflect.Field;
public class ReadReverse {
@Test
public void readReverse(){
/**
* 使用随机访问流实现,读取文件字符反转
* 字符中有中文、也有英文
* 中文 占3个字节
* 英文、数字 占1个字节
*/
RandomAccessFile ran = null;
try {
//创建输入访问流
ran = new RandomAccessFile(new File("2.txt"),"r");
//得到该文件的长度,也就是末尾指针
int lenght = (int)ran.length();
String sb = new String();
while (lenght>0){
lenght--;//末尾指针后移一位
//设置初始偏移量为后移1位
ran.seek(lenght);
//用一个字节接收
int in = ran.readByte();
//ascil值在0-255之间的数据数字后者英文字母,否则属于文字字节
if(in>=0&&in<=255){
System.out.print((char)in);
}else {
//因为一个中文占3个字节
lenght =lenght-2;
//偏移3个到第三个字节
ran.seek(lenght);
//数据缓冲
byte[] buffer = new byte[3];
//1次读取3个字节
ran.read(buffer,0,3);
//将buffer转换成string输出
System.out.print(new String(buffer));
}
}
System.out.println();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (ran!=null){
try {
ran.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4、多线程读取文件
package com.qianfeng.homeword.day18.readTheReverse;
import org.junit.Test;
import java.io.*;
import java.lang.reflect.Field;
public class ReadReverse {
@Test
public void readReverse(){
/**
* 使用随机访问流实现,读取文件字符反转
* 字符中有中文、也有英文
* 中文 占3个字节
* 英文、数字 占1个字节
*/
RandomAccessFile ran = null;
try {
//创建输入访问流
ran = new RandomAccessFile(new File("2.txt"),"r");
//得到该文件的长度,也就是末尾指针
int lenght = (int)ran.length();
String sb = new String();
while (lenght>0){
lenght--;//末尾指针后移一位
//设置初始偏移量为后移1位
ran.seek(lenght);
//用一个字节接收
int in = ran.readByte();
//ascil值在0-255之间的数据数字后者英文字母,否则属于文字字节
if(in>=0&&in<=255){
System.out.print((char)in);
}else {
//因为一个中文占3个字节
lenght =lenght-2;
//偏移3个到第三个字节
ran.seek(lenght);
//数据缓冲
byte[] buffer = new byte[3];
//1次读取3个字节
ran.read(buffer,0,3);
//将buffer转换成string输出
System.out.print(new String(buffer));
}
}
System.out.println();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (ran!=null){
try {
ran.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
public class Lassock extends Thread {
private static int meshNumber;
//重写父类run
@Override
public void run() {
while (true){
// try {
// Thread.sleep(1);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
synchronized(Ticket.class){
if (meshNumber<1000){
System.out.println("第"+Thread.currentThread().getName()+"个女孩卖完第"+(++meshNumber)+"盒火柴");
}else {
System.out.println("第"+Thread.currentThread().getName()+"个小女孩说卖完");
break;
}
}
}
}
}
5、编写方法实现把指定图片拷贝到指定目录下(10分)
package com.topic01;
import java.io.*;
/**
* 1.编写方法实现把指定图片拷贝到指定目录下(10分)
* 处理目录 File
* 拷贝 读和写 字节流
*/
public class Topic01 {
public static void main(String[] args) throws IOException {
//定义指定图片路径
File file1 = new File("C:\\Users\\DXboys\\Desktop\\week\\toc1\\toc1.jpg");
//拷贝的指定路径
File file2 = new File("C:\\Users\\DXboys\\Desktop\\week\\toc1\\toc2.jpg");
copyImg(file1,file2);
}
/**
* 创建拷贝的方法
*/
public static void copyImg(File file1, File file2) throws IOException {
//创建输入流
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);//创建文件输出流
//数据缓冲区
byte[] b = new byte[1024];
//读取ascll值
int len;
//将从toc1图片中循环读到toc2h中
while ((len=fis.read(b))!=-1){
fos.write(b,0,len);
}
fis.close();
fos.close();
}
}
6、使用随机文件流类RandomAccessFile将一个文本文件(不包含中文)倒置读出。(10分)
package com.topic02;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.RandomAccess;
/**
* 2. 使用随机文件流类RandomAccessFile将一个文本文件(不包含中文)倒置读出。(10分)
*
*/
public class Topic02 {
public static void main(String[] args) throws Exception {
//创建一个文件随机流,只是读
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\DXboys\\Desktop\\week\\toc2\\toc2.txt","r");
//获取文件的字节数
long length = raf.length();
int as;
while (length>0){
//偏移量后移一位
length--;
//设置偏移量
raf.seek(length);
//每次只读一个字节
as = raf.read();
System.out.print((char)as);
}
raf.close();
}
}
7、使用流统计一个文件(不包含中文)中各个字母出现次数,打印结果为:(A(8),B(16),C(10)…Z(2),a(12),b(10),c(3)…,z(1))括号内代表字符出现次数;(10分)
package com.topic03;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.HashMap;
import java.util.Set;
/**
* 3. 使用流统计一个文件(不包含中文)中各个字母出现次数,打印结果为:(A(8),B(16),C(10)...Z(2),a(12),b(10),c(3)....,z(1))
* 括号内代表字符出现次数;(10分)
* 思路:
* 文件内读取字母进行判断》对应字母统计。
* 用2数组分别存贮大写,小写字母出现的次数
* 对应ASCLL值
* A-Z 65-90
* a-z 97-122
* 0 1 2 3 4
* 用随机访问流读取数据
*/
public class Topic03 {
public static void main(String[] args) throws IOException {
meth02();
meth02();
}
//第二种方法,使用HashMap
public static void meth02() throws IOException{
//创建一个随机访问流
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\DXboys\\Desktop\\week\\toc3\\toc3.txt","r");
//创建一个HashMap
HashMap<Character, Integer> hash = new HashMap<>();
Set set;
int len;
char ch;
while ((len=raf.read())!=-1){
//属于字母的才读取进来
if((len>=65&&len<=90)||(len>=97&&len<=122)){
ch = (char)len;
//如果不存在该键值,则添加,存在该键值,则获取原来对应的键值加1
if(hash.containsKey(ch)){
hash.put(ch,hash.get(ch)+1);
}else {
hash.put(ch,1);
}
}
}
System.out.println(hash);
}
//第一种方法:用数组
public static void metho1() throws IOException {
//创建一个随机访问流
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\DXboys\\Desktop\\week\\toc3\\toc3.txt","r");
int[] countUpper = new int[26];//大写字母统计
int[] countLower = new int[26];//小写字母统计
int len;
while ((len=raf.read())!=-1){
//判断字符属于大写字母还是小写
if(len>=65&&len<=90){
countUpper[len%65]++;
}else if(len>=97&&len<=122){
countLower[len%97]++;
}
}
// 打印大写字母的次数
for (int i = 0; i < countUpper.length; i++) {
System.out.print(((char) (65+i)+"("+countUpper[i]+")"+","));
}
System.out.println();
//打印小写字母初心的次数
for (int i = 0; i < countLower.length; i++) {
System.out.print(((char) (97+i)+"("+countLower[i]+")"+","));
}
System.out.println();
//关流
raf.close();
}
}
8、写一个查询隐藏文件的方法,传入文件夹,查询该文件夹和下面的所有子文件的隐藏文件并打印出绝对路径(10分), 查询隐藏文件包括子文件,并打印出隐藏文件的绝对路径
package com.topic04;
import java.io.File;
/**
* 4.编写一个查询隐藏文件的方法,传入文件夹,查询该文件夹和下面的所有子文件的隐藏文件并打印出绝对路径(10分),
* 查询隐藏文件包括子文件,并打印出隐藏文件的绝对路径
*/
public class Topic04 {
public static void main(String[] args) {
hide(new File("C:\\Users\\DXboys\\Desktop\\week\\toc4\\"));
}
public static void hide(File hide) {
File[] listFile = hide.listFiles();
for (int i = 0; i < listFile.length; i++) {
//判断是否是文件夹
if (listFile[i].isDirectory()){
//在判断是否是否是隐藏文件夹,是显示文件则在进行判断
if (listFile[i].isHidden()){
//打印隐藏文件夹
System.out.println("*"+listFile[i]);
//递归进入到隐藏子文件夹
hide(listFile[i]);
}else {
hide(listFile[i]);
}
}else {
//文件如果是隐藏文件则打印出来
if (listFile[i].isHidden()){
System.out.println("*"+listFile[i]);
}
}
}
}
}
9、使用合适的流把一个包含26个字母的文件,前10个字母替换成任意的大写字母,把后最后10个字母替换为任意的数字
package com.topic05;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.Random;
/**
* 5.使用合适的流把一个包含26个字母的文件,前10个字母替换成任意的大写字母,把后最后10个字母替换为任意的数字(10分)
*/
public class topic05 {
public static void main(String[] args) throws Exception {
Random ran = new Random();
int numUpper;
int num;
//创建随机读取流
RandomAccessFile raf = new RandomAccessFile("C:\\Users\\DXboys\\Desktop\\week\\toc5\\toc5.txt","rw");
System.out.println(raf.length());
//指定前10个位置替换成10个任意大写字母
for (int i = 0; i < 10; i++) {
//用随机数得到任意的大写字母
numUpper = ran.nextInt(26)+65;
raf.write(numUpper);
}
//修改后10个,为任意数字
raf.seek(raf.length()-10);
for (int i = 0; i < 10; i++) {
//用随机数得到任意的大写字母
num = ran.nextInt(10)+48;
raf.write(num);
}
//关闭流
raf.close();
}
}