就业培训学习记录-day009
课堂任务
方法
在前面使用的 System.out.println(),具体是什么呢?这句话的意思是调用系统类 System 中的标准输出对象 out 中的方法 println()。方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
方法的优点
- 使程序变得更简短而清晰。
- 有利于程序维护。
- 可以提高程序开发的效率。
- 提高了代码的重用性。
方法的命名规则
- 方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
- 下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test
_ ,例如 testPop_emptyStack。
方法的定义
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
- 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
- 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
- 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 方法体:方法体包含具体的语句,定义该方法的功能。
无参方法
public class Run {
public static void main(String[] args) {
System.out.println("before say hello");
sayHello();
System.out.println("after say hello");
}
public static void sayHello() {
System.out.println("Hello");
}
}
运行结果如下,方法在被调用时,会先把方法内的流程执行完毕,然后再回到被调用处,接着运行后面的代码。
有参方法
public class Run {
public static void main(String[] args) {
System.out.println("before say something");
say("有参方法");
System.out.println("after say someting");
}
public static void say(String content) {
System.out.println(content);
}
}
也可以这样写:
public class Run {
public static void main(String[] args) {
System.out.println("before say something");
String word = "有参方法"; // 先定义一个字符串,并赋值
say(word); // 将刚刚定义的字符串传到say方法中
System.out.println("after say someting");
}
public static void say(String content) {
System.out.println(content);
}
}
方法返回值
public class Run {
public static void main(String[] args) {
int numA = 6, numB = 8, numC;
numC = add(numA, numB); // 用int型的numC来接受add方法的返回值
System.out.println("numC="+numC);
}
public static int add(int num1, int num2) { // 第一个int代表返回值的类型是int,当返回值类型是void时,表示没有返回值
return num1 + num2;
}
}
方法重载
上面使用的add方法仅仅适用于int型数据。但如果你想得到两个浮点类型数据的和呢?解决方法是创建另一个有相同名字但参数不同的方法,如下面代码所示:
public class Run {
public static void main(String[] args) {
int numA = 6, numB = 8, numC;
double numD = 3.14, numE = 6.78, numF;
numC = add(numA, numB); // 用int型的numC来接受add方法的返回值
System.out.println("numC="+numC);
numF = add(numD, numE); // 用double型的numF来接受add方法的返回值
System.out.println("numF="+numF);
}
public static int add(int num1, int num2) {
return num1 + num2;
}
public static double add(double num1, double num2) {
return num1 + num2;
}
}
如果调用add方法时传递的是int型参数,则int型参数的addd方法就会被调用;如果传递的是double型参数,则double类型的add方法体会被调用,这叫做方法重载;就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表。Java编译器根据方法签名判断哪个方法应该被调用。方法重载可以让程序更清晰易读。执行密切相关任务的方法应该使用相同的名字。重载的方法必须拥有不同的参数列表。不能仅仅依据修饰符或者返回类型的不同来重载方法。
数组
Java 提供的数组是用来存储固定大小的同类型元素。声明一个数组变量,如 arr[5] 来代替直接声明 5 个独立变量 arr0,arr1,....,arr4。想要获取数组中的元素值,可以通过元素的下标来获取,数组的下标是从0开始的。
arr[5] | 33 | 21 | 18 | 42 | 86 |
---|---|---|---|---|---|
下标 | 0 | 1 | 2 | 3 | 4 |
创建数组
一般分为动态初始化和静态初始化。
// 动态初始化,新建int数组,长度为5,int类型默认值为0
int[] arr1 = new int[5];
// 静态初始化1
int[] arr2 = {1,2,3,4,5};
// 静态初始化2
int[] arr3 = new int[]{1,2,3,4,5};
通过下标访问数组元素
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
char[] ary = new char[5];
ary[0]='h'; // 通过下标访问数组元素
ary[1]='e';
ary[2]='l';
ary[3]='l';
ary[4]='o';
// 遍历数组
for (int i = 0; i < 5; i++) {
System.out.println("字符数组ary的第"+(i+1)+"个元素是"+ary[i]);
}
System.out.println(Arrays.toString(ary));
}
}
遍历数组
- 数组的length属性是数组的长度
- 数组一旦创建,长度不可变
- 允许长度为0的数组
public class Run {
public static void main(String[] args) {
int[] ary = {1,2,3,4,5};
// 遍历数组
for (int i = 0; i < ary.length; i++) {
System.out.println(ary[i]);
}
}
}
数组工具类Arrays
Arrays类位于 java.util 包中,主要包含了操纵数组的各种方法。使用时需要导包import java.util.Arrays;
- Arrays.toString(Object[] array)
功能:返回数组的字符串形式
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {1,3,5,7,9};
char[] arr2 = {'h','e','l','l','o'};
System.out.println(Arrays.toString(arr));
// 结果为:[1, 3, 5, 7, 9]
System.out.println(Arrays.toString(arr2));
// 结果为:[h, e, l, l, o]
}
}
- Array.sort(Object[] array)
功能:对数组按照升序排序
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {10,3,25,-8,1};
System.out.println("排序前:"+Arrays.toString(arr));
// 排序前:[10, 3, 25, -8, 1]
Arrays.sort(arr);
System.out.println("排序后:"+Arrays.toString(arr));
// 排序后:[-8, 1, 3, 10, 25]
}
}
- Arrays.copyOf(Object[] array, int to_index)
返回一个数组,这个数组就等于数组 array 的前 to_index 个数,也就是 array[0] ~ array[to_index - 1] 。
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {4,6,8,1,3};
int[] arr2 = Arrays.copyOf(arr, 3);
System.out.println(Arrays.toString(arr2)); // [4, 6, 8]
}
}
数组常见操作
- 生成随机数组(值的范围在[1,100],包含边界)
Math.random() 方法用于返回一个随机数,随机数范围为 0.0 <= Math.random < 1.0。
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int arrSize = 10; // 指定数组长度
int[] arr = getRandomArray(arrSize); // 用数组arr接收方法返回的数组
System.out.println(Arrays.toString(arr));
}
public static int[] getRandomArray(int size) {
int[] arr = new int[size]; // 将传入的参数指定为数组的长度
for (int i = 0; i < arr.length; i++) {
// Math.random()生成的随机数范围是[0.0,1.0),乘100再加1,然后取整数部分,即是[1,100]
arr[i] = (int) (Math.random() * 100) + 1;
}
return arr;
}
}
- 数组求和
public class Run {
public static void main(String[] args) {
int[] arr = {4,6,8,1,3};
System.out.println(getSum(arr)); // 21
}
public static int getSum(int[] arr) {
int res = -1;
for (int i = 0; i < arr.length; i++) {
res += arr[i];
}
return res;
}
}
- 数组求最大、最小值
方法1:一个个比较,然后取值
public class Run {
public static void main(String[] args) {
int[] arr = {4,6,8,1,3};
System.out.println("数组最大值是"+getMax(arr)); // 8
System.out.println("数组最小值是"+getMin(arr)); // 1
}
public static int getMax(int[] arr) {
int max = arr[0]; // 最大值初始化为数组第一个元素
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max) {
// 如果某个元素比max还大,那么该元素就是新的最大值
max = arr[i];
}
}
return max;
}
public static int getMin(int[] arr) {
int min = arr[0]; // 最小值初始化为数组第一个元素
for (int i = 0; i < arr.length; i++) {
if (arr[i] < min) {
// 如果某个元素比min还小,那么该元素就是新的最小值
min = arr[i];
}
}
return min;
}
}
方法2:先排序,然后取值
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {4,6,8,1,3};
Arrays.sort(arr);
System.out.println("数组最大值是"+arr[arr.length-1]); // 8
System.out.println("数组最小值是"+arr[0]); // 1
}
}
- 数组求平均值
public class Run {
public static void main(String[] args) {
int[] arr = {4,6,8,1,3};
double avg = getSum(arr) / arr.length; // 21 ÷ 5 = 4.0
double avg1 = getSum(arr) * 1.0 / arr.length; // 21.0 ÷ 5 = 4.2
System.out.println("数组平均值是"+avg1); // 4.2
}
public static int getSum(int[] arr) {
int res = -1;
for (int i = 0; i < arr.length; i++) {
res += arr[i];
}
return res;
}
}
- 数组去重
去除数组中的重复元素,例如:数组 [0,1,1,2,2,3,3,4,4,0] 去重后数组变为 [0,1,2,3,4] 。
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {0, 1, 1, 2, 2, 3, 3, 4, 4, 0};
arr = unique(arr);
System.out.println(Arrays.toString(arr));
}
public static int[] unique(int[] arr) {
// 最好的情况是,所有的元素都不重复,新数组(要返回的数组)与原数组长度相同
int[] temp = new int[arr.length];
// 默认第一个元素不重复
temp[0] = arr[0];
// 记录不重复数据的个数
int count = 1;
// 遍历原数组中的每一项,在此基础上用遍历的第i项去遍历新数组
for (int i = 0; i < arr.length; i++) {
// 标记,表示是否在新数组中找到重复的元素
boolean flag = false;
for (int j = 0; j < temp.length; j++) {
if (arr[i] == temp[j]) {
// 如果元素重复,则更改标记
flag = true;
break;
}
}
// 如果没有元素重复,则往新数组中添加
if (!flag) {
temp[count++] = arr[i];
}
}
// 如果不重复数据的个数与原数组长度不同,即原数组中存在重复元素,则缩短新数组的长度
if (count != arr.length) {
temp = Arrays.copyOf(temp, count);
}
return temp;
}
}
- 删除数组中第n个元素
例如数组{1,2,3,4,5},删除位置为2的元素后,数组变为
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
arr = remove(arr, 2);
System.out.println(Arrays.toString(arr));
}
public static int[] remove(int[] arr, int index) {
// 如果index范围非法,则返回原数组
if (index < 0 || index > arr.length) {
return arr;
}
// 创建一个数组,长度为原数组长度-1
int[] temp = new int[arr.length - 1];
// 选择性复制元素到新数组中
for (int i = 0; i < arr.length - 1; i++) {
if (i < index) {
temp[i] = arr[i];
} else {
temp[i] = arr[i + 1];
}
}
return temp;
}
}
- 往数组中第n个位置新增元素
例如数组{1,2,3,4,5},往位置2添加666,数组变为
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
arr = add(arr, 2, 666);
System.out.println(Arrays.toString(arr));
}
public static int[] add(int[] arr, int index, int element) {
// 如果index范围非法,则返回原数组
if (index < 0 || index > arr.length) {
return arr;
}
// 创建一个数组,长度为原数组长度+1
int[] temp = new int[arr.length + 1];
// 选择性复制元素到新数组中
for (int i = 0; i < arr.length + 1; i++) {
if (i < index) {
temp[i] = arr[i];
} else if (i == index) {
temp[i] = element;
} else {
temp[i] = arr[i - 1];
}
}
return temp;
}
}
递归
递归指的是在函数的定义中使用函数自身的方法。
举个例子:
从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是:“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是:‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是:……’”
再举个例子:
假设你在一个电影院,你想知道自己坐在哪一排,但是前面人很多,你懒得去数了。于是你问前一排的人「你坐在哪一排?」,这样前面的人 (代号 A) 回答你以后,你就知道自己在哪一排了,只要把 A 的答案加一,就是自己所在的排了。不料 A 和你一样懒,他也不想数,于是他也问他前面的人 B「你坐在哪一排?」,这样 A 可以用和你一模一样的步骤知道自己所在的排。然后 B 也如法炮制,直到他们这一串人问到了最前面的一排(或者说问到了知道自己是哪一排的人,预示着调用结束),第一排的人告诉问问题的人「我在第一排」,最后大家就都知道自己在哪一排了。
递归的条件
可以通过递归调用来缩小问题规模,且新问题与原问题有着相同的形式(自身调用)。存在一种情况,可以使递归在该情况下退出(递归出口)。
递归三要素
- 一定有可以退出程序的情况(不能无限递归)
- 总是在尝试将一个问题化简到更小的规模
- 父问题与子问题不能有依赖的部分
- 阶乘问题
计算 n 的阶乘,n < 0时返回-1。
public class Run {
public static void main(String[] args) {
int n = 4; // 计算n的阶乘,这里设置为4
System.out.println(fx(n)); // 4!=4×3×2×1=24
}
public static int fx(int n) {
if (n < 0) {
// 递归边界
return -1;
} else if (n == 0) {
// 递归边界
return 1;
} else {
// 递归,函数自己调用自己
return n * fx(n-1);
}
}
}
- 斐波那契数列
计算斐波那契数列第n项的结果。
斐波那契数列的递推公式为:
F(0) = F(1) = 1 0<=n<=1
F(n) = F(n-1) + F(n-2) n>=2
public class Run {
public static void main(String[] args) {
int n = 4;
System.out.println(Fibonacci(n)); // 5
}
public static int Fibonacci(int n) {
if (n < 0) {
// 递归边界
return -1;
} else if (n == 0 || n == 1) {
// 递归边界
return 1;
} else {
// 递推公式
return Fibonacci(n-1) + Fibonacci(n-2);
}
}
}
排序
使用Arrays.sort()
import java.util.Arrays;
public class Run {
public static void main(String[] args) {
int[] arr = {34,53,12,232,1,20,10,-6,-8,32};
System.out.println("排序前:"+Arrays.toString(arr));
// 排序前:[34, 53, 12, 232, 1, 20, 10, -6, -8, 32]
Arrays.sort(arr);
System.out.println("排序后:"+Arrays.toString(arr));
// 排序后:[-8, -6, 1, 10, 12, 20, 32, 34, 53, 232]
}
}
冒泡排序
冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
算法描述
- 比较相邻的元素。如果第一个比第二个大,就交换它们两个;
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
- 针对所有的元素重复以上的步骤,除了最后一个;
- 重复步骤1~3,直到排序完成。
动图演示
代码实现
public static int[] bubbleSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
// 相邻元素两两对比
if (arr[j] > arr[j+1]) {
// 元素交换
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
选择排序
选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
算法描述
n 个记录的直接选择排序可经过 n-1 趟直接选择排序得到有序结果。具体算法描述如下:
- 初始状态:无序区为 R[1..n] ,有序区为空;
- 第 i 趟排序 (i=1,2,3…n-1) 开始时,当前有序区和无序区分别为 R[1..i-1] 和 R(i..n)。该趟排序从当前无序区中,选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使 R[1..i] 和 R[i+1..n) 分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区;
- n-1 趟结束,数组有序化了。
动图演示
代码实现
public static int[] selectionSort(int[] arr) {
int minIndex, temp;
for (int i = 0; i < arr.length - 1; i++) {
minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
// 寻找最小的数
if (arr[j] < arr[minIndex]) {
// 将最小数的索引保存
minIndex = j;
}
}
// 元素交换
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
算法分析
表现最稳定的排序算法之一,因为无论什么数据进去都是O(n2)的时间复杂度,所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。理论上讲,选择排序可能也是平时排序一般人想到的最多的排序方法了吧。
插入排序
插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
算法描述
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
- 从第一个元素开始,该元素可以认为已经被排序;
- 取出下一个元素,在已经排序的元素序列中从后向前扫描;
- 如果该元素(已排序)大于新元素,将该元素移到下一位置;
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
- 将新元素插入到该位置后;
- 重复步骤2~5。
动图演示
代码实现
public static int[] insertionSort(int[] arr) {
// current代表当前(待排序)项的值,preIndex代表在当前项之前的某个下标
int current, preIndex;
for (int i = 1; i < arr.length; i++) {
// 循环开始时,默认第0项是已经排好的,需要排的是第1项,所以i初值为1
preIndex = i - 1;
current = arr[i];
// 当前项的前一项大于当前项时,交换这两项的位置
while (preIndex >= 0 && arr[preIndex] > current) {
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
// 交换完毕或者没交换,代表当前项之前都是有序的,即将插入的值不会破坏序列
arr[preIndex + 1] = current;
}
return arr;
}
算法分析
插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
快速排序
参考快速排序
查找
顺序查找
顺序查找适合于存储结构为顺序存储或链接存储的线性表。顺序查找的时间复杂度为O(n)。
基本思想
顺序查找也称为线形查找,属于无序查找算法。从数据结构线形表的一端开始,顺序扫描,依次将扫描到的结点关键字与给定值 key 相比较,若相等则表示查找成功;若扫描结束仍没有找到关键字等于 key 的结点,表示查找失败。
代码实现
public static int sequenceSearch(int[] arr, int key) {
for (int i = 0; i < arr.length; i++) {
// 如果找到,则返回所在下标
if (arr[i] == key) {
return i;
}
}
// 如果没找到,则返回-1
return -1;
}
二分查找
参考算法——二分法查找(binarySearch)
二分法查找,也称为折半法,是一种在有序数组中查找特定元素的搜索算法,时间复杂度O(logn)。
算法描述
二分法查找的思路如下:
- 首先,从数组的中间元素开始搜索,如果该元素正好是目标元素,则搜索过程结束,否则执行下一步。
- 如果目标元素大于/小于中间元素,则在数组大于/小于中间元素的那一半区域查找,然后重复步骤 1 的操作。
- 如果某一步数组为空,则表示找不到目标元素。
代码实现
public static int binarySearch(int[] arr, int key, int low, int high) {
// 中间值
int mid = (low + high) / 2;
if (key == arr[mid]) {
// 如果刚好在中间位置,则返回所在下标
return mid;
}
if (key < arr[mid]) {
// 如果大于,则key只可能在后半部分,递归调用
return binarySearch(arr, key, low, mid - 1);
}
if (key > arr[mid]) {
// 如果大于,则key只可能在后半部分,递归调用
return binarySearch(arr, key, mid + 1, high);
}
// 如果没找到,则返回-1
return -1;
}
课后任务
编码实现一个猜字符的游戏
要求如下:
- 系统预先生成好一组(5个)不重复的小写英文字符,游戏开始,初始分值100分
- 用户输入自己猜测的字符数据(不考虑非法输入,如数字、特殊字符等)
- 系统根据用户的输入给出提示:位置对的个数以及字符对的个数
- 如果第3步中,用户输入完全正确(位置和字符),则游戏结束,系统给出猜测的次数和得分。如果没有完全正确,得分每次-5分,重复第2步
效果展示
import java.util.Arrays;
import java.util.Scanner;
public class GuessingCharacters {
public static void main(String[] args) {
// 设置大小
int i, j, size = 5;
char[] characters = new char[size];
characters = generateCharacters(size);
// 显示生成的字符
System.out.println(Arrays.toString(characters));
boolean win = false;
int score = 100, guessTimes = 0, correctPosition, correctCharacters;
// 记录用户输入的数组
char[] guess = new char[size];
Scanner scan = new Scanner(System.in);
while (!win) {
correctPosition = 0;
correctCharacters = 0;
System.out.println("请输入" + size + "个字符(a~z):");
// 接收输入并去重
guess = scan.nextLine().toCharArray();
guess = unique(guess);
// 更新猜的次数
guessTimes++;
// 遍历生成的数组,判断位置和字符是否正确
for (i = 0; i < characters.length; i++) {
// 如果完全正确,则直接退出循环
if (Arrays.toString(characters).equals(Arrays.toString(guess))) {
correctPosition = characters.length;
correctCharacters = characters.length;
win = true;
break;
}
// 遍历输入的数组
for (j = 0; j < guess.length; j++) {
// 如果字符相同,则字符正确数自增
if (characters[i] == guess[j]) {
// 字符相同并且位置相同,则位置正确数自增
if (i == j) {
correctPosition++;
}
correctCharacters++;
}
}
}
if (!win) {
// 没完全猜对,更新得分并给出相应提示
score -= 5;
System.out.println("字符对:" + correctCharacters + "个,位置对:" + correctPosition + "个");
}
}
// 关闭流并且显示得分
scan.close();
System.out.println("猜对了,猜了" + guessTimes + "次,得分:" + score);
}
/**
* 随机生成size大小的不重复小写字符数组,size的合理范围为[1,26]
* @param size
* @return char[]
*/
public static char[] generateCharacters(int size) {
if (size < 0 || size > 26) {
return null;
}
char[] characters = new char[size];
int i, random, counts = 0;
char a = 'a', newChar;
while (counts != size) {
// 生成[0,100)的整数
random = (int) (Math.random() * 100);
// 小写字母有26个,生成的数大于26就会出错,所以大于26时取余 但是这样会导致生成每个字母的概率不是平等的
if (random >= 26) {
random %= 26;
}
newChar = (char) (a + random);
// 遍历生成的字符,确保生成的字符不重复
for (i = 0; i < counts; i++) {
if (characters[i] == newChar) {
break;
}
}
// 如果循环顺利结束,即没有重复字符时,i=counts
if (i == counts) {
characters[counts++] = newChar;
}
}
return characters;
}
/**
* 字符数组去重
* @param arr
* @return char[]
*/
public static char[] unique(char[] arr) {
// 最好的情况是,所有的元素都不重复,新数组(要返回的数组)与原数组长度相同
char[] temp = new char[arr.length];
// 默认第一个元素不重复
temp[0] = arr[0];
// 记录不重复数据的个数
int count = 1;
// 遍历原数组中的每一项,在此基础上用遍历的第i项去遍历新数组
for (int i = 0; i < arr.length; i++) {
// 标记,表示是否在新数组中找到重复的元素
boolean flag = false;
for (int j = 0; j < temp.length; j++) {
if (arr[i] == temp[j]) {
// 如果元素重复,则更改标记
flag = true;
break;
}
}
// 如果没有元素重复,则往新数组中添加
if (!flag) {
temp[count++] = arr[i];
}
}
// 如果不重复数据的个数与原数组长度不同,即原数组中存在重复元素,则缩短新数组的长度
if (count != arr.length) {
temp = Arrays.copyOf(temp, count);
}
return temp;
}
}