目次
3. Java 配列
3.1 アレイの概要
配列(Array)とは、同じ種類の複数のデータを一定の順序で並べたもので、という名前が付けられ、これらのデータは番号付けによって一元管理されます。
- 配列自体は参照データ型であり、配列内の要素は、プリミティブ データ型や参照データ型を含む任意のデータ型にすることができます。
- 配列オブジェクトを作成すると、メモリ内に連続空間全体が開かれ、配列名はこの連続空間の最初のアドレスを参照します。
- 配列の長さが決定されると、それを変更することはできません。
- 添字(またはインデックス)によって指定された位置にある要素を直接呼び出すことができ、非常に高速です。
- 配列の分類:
次元による: 1 次元配列、2 次元配列、3 次元配列、...
要素のデータ型による: 基本データ型要素の配列、参照データ型要素の配列 (つまり、 、オブジェクト配列)
3.2 1 次元配列の使用
① 1次元配列の宣言方法
type var[] または type[] var;
例えば:
int a[];
int[] a1;
double b[];
String[] c; //引用类型变量数组
Java 言語で配列を宣言する場合、その長さ (配列内の要素の数)を指定することはできません(例: int a[5]; //Illegal)
②1次元配列の初期化
-
動的初期化:配列の宣言と配列要素のスペースの割り当て、および代入操作は個別に実行されます。
int[] arr = new intr[3]; arr[0] = 3; arr[1] = 9; arr[2] = 8; String names[]; names =new =String[3]; names[0] = "钱学森"; names[1] = "邓稼先"; names[2] = "袁隆平";
-
静的初期化:配列を定義するときに、スペースを割り当て、配列要素に値を割り当てます。
int arr[] = new int []{3,9,8}; int [] arr = {3,9,8}; String names[] = { "李四光”,"茅以升","华罗庚" }
③配列要素参照
- 演算子を定義して使用する新しいスペースを割り当てた後、配列内の各要素を参照できます。
- 配列要素の参照方法: 配列名 [配列要素の添字]
配列要素の添字には、整数定数または整数式を指定できます。a[3]、b[i]、c[6*i] など、
配列要素の添字は 0 から始まります。長さが n の配列の有効な添字値の範囲は0 —>n-1などです。 int a[] =new int[3]; 参照できる配列要素は a[0]、a[1]、a[2] - 各配列には、その長さを示す属性 length があります。例: a.length は、配列 a の長さ (要素の数) を示します。
配列が初期化されると、その長さは不変になります。
④ 配列要素のデフォルトの初期化値配列は参照型であり、その要素はクラスのメンバ変数
に相当するため、配列内に空間が確保されると、その中の各要素もメンバと同様に暗黙的に初期化されます。変数。例えば:
public class Test {
public static void main(String args[]){
int a[]= new int[5];
System.out.println(a[3]); //a[3]的默认值为0
}
}
>对于基本数据类型而言,默认初始化值各有不同
>对于引用数据类型而言,默认初始化值为null(注意与0不同!)
配列要素の型 | 要素のデフォルトの初期値 |
---|---|
バイト | 0 |
短い | 0 |
整数 | 0 |
長さ | 0L |
浮く | 0.0F |
ダブル | 0.0 |
文字 | 0 または次のように記述されます: '\u0000' (空として表現) |
ブール値 | 間違い |
参照型 | ヌル |
⑤ 基本的なデータ型の配列を作成する
- Java でのキーワードの使用新しい配列を作成するには
- 以下は、基本的なデータ型要素の 1 次元配列を作成します。
public class Tset{
public static void main(String args[]){
int[] s; //处内存状态
s = new int[10];
for(int i=0;i<10;i++){
s[i] = 2*i+1;
System.out.println(s[i]);
}
}
}
public class Test{
public static void main(String args[]){
int[] s;
s = new int[10]; //处内存状态
//int[] s=new int[10];
//基本数据类型数组在显式赋值之前,Java会自动给他们赋默认值。
for ( int i=0; i<10; i++ ) {
s[i] =2*i+1;
System.out.println(s[i]);
}
}
}
public class Test{
public static void main(String args[]){
int[] s;
s = new int[10];
for ( int i=0; i<10; i++ ) {
s[i] =2*i+1; //处内存状态
System.out.println(s[i]);
}
}
}
練習
/*
从键盘输入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序
*/
import java.util.Scanner;
class Test
{
public static void main(String[] args) {
//1.使用scanner,读取学生个数
Scanner scanner=new Scanner(System.in);
System.out.println("请输入学生人数:");
int number=scanner.nextInt();
//2.创建数组,存储学生成绩;动态初始化
int[] scores=new int[number];
//3.给数组中的元素赋值
System.out.println("请输入"+number+"个学生成绩:");
int maxScore=0;
for (int i = 0; i < scores.length; i++) {
scores[i]=scanner.nextInt();
//4.获取数组中的元素最大值:最高分
if (maxScore<scores[i]){
maxScore=scores[i];
}
}
//5.根据每个学生成绩与最高分的差值,得到每个学生的等级,并输出等级和成绩
char level;
for (int i = 0; i < scores.length; i++) {
if (maxScore-scores[i]<=10){
level='A';
}else if (maxScore-scores[i]<=20){
level='B';
}else if (maxScore-scores[i]<=30){
level='C';
}else {
level='D';
}
System.out.println("student "+i+"score is "+scores[i]+",gread is "+level);
}
}
}
>运行结果
请输入学生人数:
5
请输入5个学生成绩:
55
77
67
59
81
student 0score is 55,gread is C
student 1score is 77,gread is A
student 2score is 67,gread is B
student 3score is 59,gread is C
student 4score is 81,gread is A
3.3 多次元配列の使用
- Java 言語は、多次元配列をサポートする構文を提供します。
- 1 次元配列がジオメトリの線形グラフィックスとみなせる場合、2 次元配列は、右の Excel のテーブルのようなテーブルと同等になります。
- 2 次元配列を理解するには、1 次元配列 array1 が別の 1 次元配列 array2 の要素として存在することがわかります。実際、配列の基本的な動作メカニズムの観点から見ると、実際には多次元配列は存在しません。
練習
/*1.获取arr数组中所有元素的和。*/
package test1j.ava;
public class shuzu {
public static void main(String[] args) {
int [][] arr = new int[][] {
{
3,5,8},{
12,9},{
7,0,6,4}};
int num = 0;
for(int i=0;i<arr.length;i++){
for(int j=0;j<arr[i].length;j++){
num += arr[i][j];
}
}
System.out.println(num);
}
}
>运行结果 54
/*2.使用二维数组打印一个 10 行杨辉三角*/
package test1j.ava;
public class yanghui {
public static void main(String[] args) {
int n = 10; // 控制打印的行数
int[][] arr = new int[n][];
for (int i = 0; i < n; i++) {
arr[i] = new int[i + 1];
arr[i][0] = 1;
arr[i][arr[i].length - 1] = 1;
// 计算该行的数据
for (int j = 1; j < arr[i].length - 1; j++) {
arr[i][j] = arr[i - 1][j - 1] + arr[i - 1][j];
}
}
// 打印杨辉三角
for (int i = 0; i < n; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}
>运行结果
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
/*3.创建一个长度为6的int型数组,要求数组元素的值都在1-30之间,且是随机赋值。同时,要求元素的值各不相同。*/
package test1j.ava;
import java.util.Random;
public class randnumber {
public static void main(String[] args) {
int[] nums = new int[6]; // 创建一个长度为6的int型数组
Random rand = new Random(); // 创建一个伪随机数生成器
// 循环生成一个数字,直到符合要求为止(1-30之间,且和数组中已有的数字不同)
for (int i = 0; i < nums.length; i++) {
int num;
do {
num = rand.nextInt(30) + 1;
} while (contains(nums, num, i));
nums[i] = num; // 将符合条件的数字赋值给数组
}
// 打印数组的元素
System.out.print("随机生成的数组为{");
for (int s=0;s<6;s++) {
if(s==5){
System.out.print(nums[s]);
}else
System.out.print(nums[s]+",");
}System.out.print("}");
}
// 判断一个数字是否已存在于数组中
private static boolean contains(int[] nums, int num, int length) {
for (int i = 0; i < length; i++) {
if (nums[i] == num) {
return true;
}
}
return false;
}
}
>运行结果
随机生成的数组为{
9,15,13,17,21,11}
3.4 配列に関連する一般的なアルゴリズム
- 配列要素の代入(陽輝三角形、丸数など)
- 数値配列内の要素の最大値、最小値、平均値、合計などを検索します。
- 配列コピー、反転、検索(線形探索、二分探索)
- 配列要素をソートするアルゴリズム
アルゴリズムの紹介
アルゴリズムの5つの特徴
特徴 | 意味 |
---|---|
入力 | 0 個以上の入力データがあります。これらの入力は明確に説明および定義する必要があります |
出力 | 少なくとも 1 つ以上の出力結果。出力結果がないことは許可されません |
有限性 (有限性) | アルゴリズムは無限ループなしで有限数のステップの後に自動的に終了し、各ステップは許容可能な時間内に完了できます。 |
明確性 | アルゴリズムの各ステップには、曖昧さのない明確な意味があります。 |
実現可能性(有効性、有効性) | アルゴリズムの各ステップは明確かつ実行可能であり、ユーザーはペンと紙を使って答えを計算できます。 |
練習
/*定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
要求:所有随机数都是两位数。*/
package test1j.ava;
import java.util.Random;
public class suanfa1 {
public static void main(String[] args ){
int[] arr = new int [10];// 创建一个长度为10的int型数组
Random rand = new Random(); // 创建一个伪随机数生成器
// 循环生成一个数字,直到符合要求为止(两位数,>=10&&<=99)
for(int i = 0;i<10;i++){
int num = rand.nextInt(90)+10;
arr[i] = num;
}
// 求出所有元素的最大值,最小值,和值,平均值
int max = arr[0], min = arr[0], sum = 0;
for (int num : arr) {
//遍历数组快捷方式
if (num > max) {
max = num;
}
if (num < min) {
min = num;
}
sum += num;
}
double average = (double) sum / arr.length;
// 输出结果
System.out.println("数组元素为:");
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
System.out.println("最大值为:" + max);
System.out.println("最小值为:" + min);
System.out.println("和值为:" + sum);
System.out.println("平均值为:" + average);
}
}
>运行结果
数组元素为:
83 26 95 85 49 38 37 94 72 19
最大值为:95
最小值为:19
和值为:598
平均值为:59.8
①二分探索アルゴリズム
//二分法查找:要求此数组必须是有序的。
package test1j.ava;
public class erfen {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr3 = new int[]{
-99,-54,-2,0,2,33,43,256,999};
boolean isFlag = true;
int number = 256;
//int number = 25;
int head = 0;//首索引位置
int end = arr3.length - 1;//尾索引位置
while(head <= end){
int middle = (head + end) / 2;
if(arr3[middle] == number){
System.out.println("找到指定的元素,索引为:" + middle);
isFlag = false;
break;
}else if(arr3[middle] > number){
end = middle - 1;
}else{
//arr3[middle] < number
head = middle + 1;
}
}
if(isFlag){
System.out.println("未找打指定的元素");
}
}
}
>运行结果
找到指定的元素,索引为:7
②ソートアルゴリズム
ソート:
n個のレコードを含む配列を{R1, R2,...,Rn}とし、それに対応するキー配列を{K1, K2,...,Kn}とする。対応するキー値が条件 Ki1<=Ki2<=...<=Kin を満たすように、これらのレコードを {Ri1, Ri2,...,Rin} に並べ替えます。このような操作をソートと呼びます。
一般に、並べ替えの目的は、すばやく見つけることです。
並べ替えアルゴリズムの長所と短所を測定します。
- 時間計算量: キーワードの比較数とレコードの移動数を分析します。
- 空間の複雑さ: ソート アルゴリズムに必要な補助メモリの量を分析します。
- 安定性: 2 つのレコード A と B のキー値が等しいが、ソート後も A と B の順序が変わらない場合、ソート アルゴリズムは安定していると言われます。
ソートアルゴリズムの分類: 内部ソートと外部ソート。
- 内部ソート: ソート プロセス全体は外部ストレージ (ディスクなど) を必要とせず、すべてのソート操作はメモリ内で完了します。
- 外部並べ替え: 並べ替えには多くのデータが含まれ、データ量が非常に大きいため、コンピューターは並べ替えプロセス全体をメモリ内で完了することができず、外部ストレージ (ディスクなど) に依存する必要があります。最も一般的な外部ソートは、多方向マージ ソートです。外部ソートは複数の内部ソートから構成されていると考えることができます。
トップ 10 の並べ替えアルゴリズム
- 選択ソート
直接選択ソート、ヒープソート - スワップソート
バブルソート クイックソート - インサーションソート
ダイレクトインサートソート、ハーフインサートソート、シェルソート - マージソート
- バケットソート
- 基数ソート
③バブルソート
はじめに:
バブル ソートの原理は非常に単純で、ソート対象の配列を繰り返し訪問し、一度に 2 つの要素を比較し、順序が間違っている場合は要素を交換します。
アイデアを並べ替える:
- 隣接する要素を比較します。最初の値が 2 番目の値よりも大きい場合 (昇順)、両方を入れ替えます。
- 隣接する要素の各ペアに対して、最初の最初のペアから最後の最後のペアまで同じことを行います。このステップが完了すると、最後の要素が最大の数値になります。
- 最後の要素を除くすべての要素に対して上記の手順を繰り返します。
- 比較する数値のペアがなくなるまで、要素の数を減らしながら上記の手順を繰り返します。
④クイックソート
はじめに:
クイック ソートは通常、同じ O(nlogn) の他のアルゴリズムよりも大幅に高速であるため、頻繁に使用されます。また、クイック ソートは分割統治の考え方を採用しているため、クイック ソートの影がよく見られます。多くの筆記試験の面接で。クイックソートをマスターすることの重要性がわかります。
チューリング賞受賞者のトニー ホアによって発明されたクイック ソートは、20 世紀のトップ 10 アルゴリズムの 1 つとしてリストされており、すべての内部ソート アルゴリズムの中で最も高速です。交換ソートの一種であるバブルソートのバージョンアップ版。クイックソートの時間計算量は次のとおりです。O(nlog(n))。
アイデアを並べ替える:
- シーケンスから「ピボット」(ピボット)と呼ばれる要素を選択します。
- シーケンスを並べ替えます。基準値より小さいすべての要素は基準値の前に配置され、基準値より大きいすべての要素は基準値の後ろに配置されます (同じ数値をどちらの側にも配置できます)。この分割が終了すると、ベンチマークはシーケンスの途中になります。これをパーティション操作と呼びます。//前が大きくて後ろが小さい
- 基本値より小さい要素を含む部分配列と、基本値より大きい要素を含む部分配列を再帰的に並べ替えます。
- 再帰の最も低いケースは、シーケンスのサイズが 0 または 1 である、つまりシーケンスが常にソートされているということです。再帰的に実行されていますが、各反復 (反復) で少なくとも 1 つの要素が最後の位置に配置されるため、このアルゴリズムは必ず終了します。
⑤ソートアルゴリズムの性能比較
- 平均時間の観点から言えば、クイックソートが最適です。ただし、最悪の場合、時間パフォーマンスはヒープ ソートやマージ ソートほど良くありません。
- アルゴリズムの単純さの観点から: 直接選択ソート、直接挿入ソート、バブルソートのアルゴリズムは比較的単純であるため、単純なアルゴリズムと見なされます。シェル ソート、ヒープ ソート、クイック ソート、およびマージ ソート アルゴリズムの場合、それらのアルゴリズムはより複雑であり、複雑なソートとみなされます。
- 安定性の観点から見ると、直接挿入ソート、バブルソート、マージソートは安定していますが、直接選択ソート、クイックソート、シェルソート、ヒープソートは不安定なソートです。
- ソートするレコード数 n のサイズから、n が小さい場合は単純なソートを使用する必要があり、n が大きい場合は改良されたソートを使用する必要があります。
ソートアルゴリズムの選択
- n を比較する場合小さい(n≤50 など)、使用できます直接挿入するまた直接選択ソート。
レコード サイズが小さい場合は、直接挿入ソートの方が適していますが、そうでない場合は、直接選択により移動されるレコード数が直接挿入よりも少ないため、直接選択ソートを選択する必要があります。 - 基本的にファイルの初期状態が秩序ある、選択する必要があります挿入、バブル、またはランダムなクイックソート適切な;
- n を比較する場合大きい、時間計算量が O(nlgn) のソート方法を採用する必要があります。クイックソート、ヒープソート、またはマージソート
3.5 配列の使用における一般的な例外
3.6 配列ツールクラスの使用
java.util.Arrays クラスは、配列を操作するためのツール クラスであり、配列を操作するためのさまざまなメソッド (並べ替えや検索など) が含まれています。