この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
広告
posted by fanblog
2019年10月28日
Java API Arrays.binarySearchを使った二分探索
二分探索法のアルゴリズムを覚えていなくても
「Arrays.binarySearch」メソッドで二分探索を行い
目的のデータを探索することができます。
public class Demo {
public static void main(String[] args) {
int[] num = { 5, 30, 10, 20, 70, 90 };
Arrays.sort(num); //配列をソート
System.out.println(Arrays.toString(num)); //ソートした配列を出力
int result = Arrays.binarySearch(num, 30);
System.out.println("インデックス:" + result);
}
}
========== 実行結果 ==========
[5, 10, 20, 30, 70, 90]
インデックス:3
==============================
Arrays.binarySearchも二分探索で目的のデータを探索するので
探索前に配列がソートされている必要があります。
† 地球の末路!? †
「Arrays.binarySearch」メソッドで二分探索を行い
目的のデータを探索することができます。
public class Demo {
public static void main(String[] args) {
int[] num = { 5, 30, 10, 20, 70, 90 };
Arrays.sort(num); //配列をソート
System.out.println(Arrays.toString(num)); //ソートした配列を出力
int result = Arrays.binarySearch(num, 30);
System.out.println("インデックス:" + result);
}
}
========== 実行結果 ==========
[5, 10, 20, 30, 70, 90]
インデックス:3
==============================
Arrays.binarySearchも二分探索で目的のデータを探索するので
探索前に配列がソートされている必要があります。
† 地球の末路!? †
2019年10月27日
Java 二分探索法のアルゴリズム
目的のデータと配列の中央のデータを比較しながら
目的のデータを探索する探索法が二分探索法です。
二分探索法は、探索前に配列のデータをソートする必要があります。
中央のデータを除き、探索範囲を縮小して探索をします。
public class Example4 {
public static void main(String[] args) {
int[] num = { 5, 30, 10, 20, 70, 90 };
Arrays.sort(num);
System.out.println(Arrays.toString(num)); //ソートした配列を出力
System.out.println("インデックス:" + search(num, 30));
}
public static int search(int[] data, int target) {
int result = -1;
int left = 0; //配列のインデックスは0から始まるから左端は0
int right = data.length - 1; //右端はインデックスが要素-1になるから
while(left <= right) {
int middle = (left + right) / 2; //中央のデータを求める
if(data[middle] == target) {
return middle;
}else if(data[middle] < target) {
left = middle + 1;
}else {
right = middle - 1;
}
}
return result;
}
}
===== 実行結果 =====
[5, 10, 20, 30, 70, 90]
インデックス:4
====================
中央のデータと目的のデータが一致した場合は、中央の値をreturn。
目的のデータが大きい場合は「middle + 1」して探索範囲を縮小。
目的のデータが小さい場合は「middle - 1」して探索範囲を縮小。
「0,1,2,3,4,5,6」
中央が「3」だとします。「3」を基準として大小関係を調べて
目的のデータが中央のデータと同じ場合は「return 3」。
目的のデータが大きい場合、0〜3には目的のデータは存在しない。
なので、探索範囲を縮小するために
中央のデータに+1して中央のデータを除いた4〜6を探索します。
この時、新たに「int middle = (left + right) / 2」で
中央のデータが設定されます。
大きい場合だと、4〜6に探索範囲が縮小されると
中央の値は「(4 + 6) / 2」で5になります。
逆に、目的のデータが小さい場合、3〜6には目的のデータは存在しない。
なので、探索範囲を縮小するために
中央のデータに-1して中央のデータを除いた0〜2を探索します。
この時、新たに「int middle = (left + right) / 2」で
中央のデータが設定されます。
小さい場合だと、0〜2に探索範囲が縮小されると
中央の値は「(0 + 2) / 2」で1になります。
最後に、int型となっているので少数点以下は切り捨てられます。
APIで用意されているメソッドを使用した二分探索もあります。
それは、また次回に。
† 地球の末路!? †
目的のデータを探索する探索法が二分探索法です。
二分探索法は、探索前に配列のデータをソートする必要があります。
中央のデータを除き、探索範囲を縮小して探索をします。
public class Example4 {
public static void main(String[] args) {
int[] num = { 5, 30, 10, 20, 70, 90 };
Arrays.sort(num);
System.out.println(Arrays.toString(num)); //ソートした配列を出力
System.out.println("インデックス:" + search(num, 30));
}
public static int search(int[] data, int target) {
int result = -1;
int left = 0; //配列のインデックスは0から始まるから左端は0
int right = data.length - 1; //右端はインデックスが要素-1になるから
while(left <= right) {
int middle = (left + right) / 2; //中央のデータを求める
if(data[middle] == target) {
return middle;
}else if(data[middle] < target) {
left = middle + 1;
}else {
right = middle - 1;
}
}
return result;
}
}
===== 実行結果 =====
[5, 10, 20, 30, 70, 90]
インデックス:4
====================
中央のデータと目的のデータが一致した場合は、中央の値をreturn。
目的のデータが大きい場合は「middle + 1」して探索範囲を縮小。
目的のデータが小さい場合は「middle - 1」して探索範囲を縮小。
「0,1,2,3,4,5,6」
中央が「3」だとします。「3」を基準として大小関係を調べて
目的のデータが中央のデータと同じ場合は「return 3」。
目的のデータが大きい場合、0〜3には目的のデータは存在しない。
なので、探索範囲を縮小するために
中央のデータに+1して中央のデータを除いた4〜6を探索します。
この時、新たに「int middle = (left + right) / 2」で
中央のデータが設定されます。
大きい場合だと、4〜6に探索範囲が縮小されると
中央の値は「(4 + 6) / 2」で5になります。
逆に、目的のデータが小さい場合、3〜6には目的のデータは存在しない。
なので、探索範囲を縮小するために
中央のデータに-1して中央のデータを除いた0〜2を探索します。
この時、新たに「int middle = (left + right) / 2」で
中央のデータが設定されます。
小さい場合だと、0〜2に探索範囲が縮小されると
中央の値は「(0 + 2) / 2」で1になります。
最後に、int型となっているので少数点以下は切り捨てられます。
APIで用意されているメソッドを使用した二分探索もあります。
それは、また次回に。
† 地球の末路!? †
2019年10月23日
Java 線形探索法のアルゴリズム
そもそもアルゴリズムって?
アルゴリズムは何らかの問題を有限の時間で解くための手順。
「これと、これをこうやって、こうして」みたいな感じの手順を
コンピュータに与えるプログラムのこと。
線形探索法は、配列の先頭から目的のデータを探索する方法。
不規則に配列されているデータの中から
目的のデータを探し出すのには適しているのですが
データが多くなると探索に時間がかかります。
class Demo{
public static void main(String[] args) {
int[] num = {60, 20, 80, 10, 30, 50, 120, 70, 5};
System.out.println("インデックス:" + search(num, 120) );
}
public static int search(int[] data, int target) {
int result = -1;
for(int i = 0; i < data.length; i++) {
if(data[i] == target) {
result = i ;
}
}
return result;
}
}
========== 実行結果 ==========
インデックス:6
==============================
targetが見つからない場合は-1を返します。
見つかった場合にはインデックスをreturnします。
† 地球の末路!? †
アルゴリズムは何らかの問題を有限の時間で解くための手順。
「これと、これをこうやって、こうして」みたいな感じの手順を
コンピュータに与えるプログラムのこと。
線形探索法は、配列の先頭から目的のデータを探索する方法。
不規則に配列されているデータの中から
目的のデータを探し出すのには適しているのですが
データが多くなると探索に時間がかかります。
class Demo{
public static void main(String[] args) {
int[] num = {60, 20, 80, 10, 30, 50, 120, 70, 5};
System.out.println("インデックス:" + search(num, 120) );
}
public static int search(int[] data, int target) {
int result = -1;
for(int i = 0; i < data.length; i++) {
if(data[i] == target) {
result = i ;
}
}
return result;
}
}
========== 実行結果 ==========
インデックス:6
==============================
targetが見つからない場合は-1を返します。
見つかった場合にはインデックスをreturnします。
† 地球の末路!? †
2019年10月17日
Java 最大値を求めるアルゴリズム
配列の中から最大値を求めるアルゴリズムです。
maxメソッドは要素の大小比較するメソッドになります。
このメソッドをmainメソッド側で配列を渡して呼び出しています。
public class Demo {
public static void main(String[] args) {
int[] num = {60, 70, 30, 10, 50, 40, 20};
System.out.println(max(num));
}
public static int max(int[] data) {
int max = data[0];
for(int i = 1; i < data.length; i++) {
if(max < data[i]) {
max = data[i];
}
}
return max;
}
}
data[0]に格納されている要素を仮の最大値として変数maxに代入します。
forが1から始まるのは、インデックス0を仮の最大値としているから。
比較しても意味がないということです。
インデックス0の仮の最大値よりインデックス1以降の要素が大きければ
変数maxの値を上書きしてif文とfor文から出てmaxをreturnします。
maxメソッドの引数の変数dataは
渡された配列を受け取るための変数なので変数名は何でもOKです。
それから、もう一つ。
maxメソッドをstaticにしているかというとオブジェクトを生成しなくてもいいから。
staticでない時「max(num)」ではメソッドにアクセスすることはできないので
オブジェクトを生成してアクセスする必要があります。こんな感じで。
public class Demo {
public static void main(String[] args) {
int[] num = {60, 70, 30, 10, 50, 40, 20};
Demo demo = new Demo();
System.out.println(demo.max(num));
}
public int max(int[] data) {
int max = data[0];
for(int i = 1; i < data.length; i++) {
if(max < data[i]) {
max = data[i];
}
}
return max;
}
}
† 地球の末路!? †
maxメソッドは要素の大小比較するメソッドになります。
このメソッドをmainメソッド側で配列を渡して呼び出しています。
public class Demo {
public static void main(String[] args) {
int[] num = {60, 70, 30, 10, 50, 40, 20};
System.out.println(max(num));
}
public static int max(int[] data) {
int max = data[0];
for(int i = 1; i < data.length; i++) {
if(max < data[i]) {
max = data[i];
}
}
return max;
}
}
data[0]に格納されている要素を仮の最大値として変数maxに代入します。
forが1から始まるのは、インデックス0を仮の最大値としているから。
比較しても意味がないということです。
インデックス0の仮の最大値よりインデックス1以降の要素が大きければ
変数maxの値を上書きしてif文とfor文から出てmaxをreturnします。
maxメソッドの引数の変数dataは
渡された配列を受け取るための変数なので変数名は何でもOKです。
それから、もう一つ。
maxメソッドをstaticにしているかというとオブジェクトを生成しなくてもいいから。
staticでない時「max(num)」ではメソッドにアクセスすることはできないので
オブジェクトを生成してアクセスする必要があります。こんな感じで。
public class Demo {
public static void main(String[] args) {
int[] num = {60, 70, 30, 10, 50, 40, 20};
Demo demo = new Demo();
System.out.println(demo.max(num));
}
public int max(int[] data) {
int max = data[0];
for(int i = 1; i < data.length; i++) {
if(max < data[i]) {
max = data[i];
}
}
return max;
}
}
† 地球の末路!? †
2019年09月08日
Queue(キュー) add、poll、peek
Queueは格納した値を、格納した順に取り出します。
両方に穴の開いた筒の左側から1、2・・・5とピンポン玉を順番に入れると
右側から入れた時と同じ順番で1、2・・5と出てきます。Queueはこんな感じです。
難しいことは無しにしてプログラムで書くとこんな感じになります。
add:値を追加
poll:値を取り出して削除
peek:値を参照
class Demo {
public static void main(String[] args) {
String[] s = {"Orange", "Apple", "Kiwi", "Strawberry", "Remon"};
Queueq = new LinkedList ();
for(int i = 0; i < s.length; i++) {
q.add(s[i]);
}
System.out.println(q.peek());
System.out.println(q);
System.out.println();
System.out.println();
System.out.println(q.poll());
System.out.println(q);
}
}
===== 実行結果 =====
Orange
[Orange, Apple, Kiwi, Strawberry, Remon]
Orange
[Apple, Kiwi, Strawberry, Remon]
====================
pollは値を参照するだけなのでQueueの値は削除されていません。
逆に、peekは値を取り出して、取り出した値が削除されています。
† 地球の末路!? †
両方に穴の開いた筒の左側から1、2・・・5とピンポン玉を順番に入れると
右側から入れた時と同じ順番で1、2・・5と出てきます。Queueはこんな感じです。
難しいことは無しにしてプログラムで書くとこんな感じになります。
add:値を追加
poll:値を取り出して削除
peek:値を参照
class Demo {
public static void main(String[] args) {
String[] s = {"Orange", "Apple", "Kiwi", "Strawberry", "Remon"};
Queue
for(int i = 0; i < s.length; i++) {
q.add(s[i]);
}
System.out.println(q.peek());
System.out.println(q);
System.out.println();
System.out.println();
System.out.println(q.poll());
System.out.println(q);
}
}
===== 実行結果 =====
Orange
[Orange, Apple, Kiwi, Strawberry, Remon]
Orange
[Apple, Kiwi, Strawberry, Remon]
====================
pollは値を参照するだけなのでQueueの値は削除されていません。
逆に、peekは値を取り出して、取り出した値が削除されています。
† 地球の末路!? †
2019年09月04日
int型の配列3 値を変更する
配列はインデックスを使って値を取り出したり
変更したりすることができます。
class Demo{
public static void main(String[] args) {
int[] num = {100, 200, 300};
//インデックス2の値の取り出し
System.out.println(num[2]);
//インデックス1の値を変更
num[1] = 500;
System.out.println();
System.out.println();
//forで出力
for(int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
System.out.println();
System.out.println();
//拡張forで出力
for(int j: num) {
System.out.println(j);
}
}
}
===== 実行結果 =====
300
100
500
300
100
500
300
====================
† 地球の末路!? †
変更したりすることができます。
class Demo{
public static void main(String[] args) {
int[] num = {100, 200, 300};
//インデックス2の値の取り出し
System.out.println(num[2]);
//インデックス1の値を変更
num[1] = 500;
System.out.println();
System.out.println();
//forで出力
for(int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
System.out.println();
System.out.println();
//拡張forで出力
for(int j: num) {
System.out.println(j);
}
}
}
===== 実行結果 =====
300
100
500
300
100
500
300
====================
† 地球の末路!? †
2019年09月03日
int型の配列2
配列は大きく分けると3つ宣言方法があります。
1つ目は
「int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;」
2つ目は「int[] num = new int[]{100, 200, 300};」
3つ目は「int[] num = {100, 200, 300};」
実行結果はint型の配列1と同じになります。
† 地球の末路!? †
1つ目は
「int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;」
2つ目は「int[] num = new int[]{100, 200, 300};」
3つ目は「int[] num = {100, 200, 300};」
実行結果はint型の配列1と同じになります。
† 地球の末路!? †
2019年09月02日
int型の配列1
配列はインデックス(添え字)は1からではなく0から始まるので注意して下さい。
下記のように要素数を3つ宣言した場合、インデックスは0、1、2となります。
class Demo{
public static void main(String[] args) {
int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;
//forで出力
for(int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
System.out.println();
System.out.println();
//拡張forで出力
for(int j: num) {
System.out.println(j);
}
}
}
===== 実行結果 =====
100
200
300
100
200
300
====================
「int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;」
こんな感じで値を格納するのは結構面倒・・・と
そんな時には、forを使って値をnumに格納することも。
for(int i = 0; i < num.length; i++){
num[i] = (i + 1) * 100;
}
要素数が3つだけなので「int[] num = {}100, 200, 300;」にした方がもっと楽かな。
でも、キーボードで入力するのが面倒なほど要素数が増えると別だけど・・・
† 地球の末路!? †
下記のように要素数を3つ宣言した場合、インデックスは0、1、2となります。
class Demo{
public static void main(String[] args) {
int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;
//forで出力
for(int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
System.out.println();
System.out.println();
//拡張forで出力
for(int j: num) {
System.out.println(j);
}
}
}
===== 実行結果 =====
100
200
300
100
200
300
====================
「int[] num = new int[3];
num[0] = 100;
num[1] = 200;
num[2] = 300;」
こんな感じで値を格納するのは結構面倒・・・と
そんな時には、forを使って値をnumに格納することも。
for(int i = 0; i < num.length; i++){
num[i] = (i + 1) * 100;
}
要素数が3つだけなので「int[] num = {}100, 200, 300;」にした方がもっと楽かな。
でも、キーボードで入力するのが面倒なほど要素数が増えると別だけど・・・
† 地球の末路!? †
2019年08月27日
コレクションSetは要素の重複不可
Setは要素を順番に格納しないのでバラバラに取り込んだような順不同になります。
また、要素の重複不可なので重複している要素は取り込まれません。
class Demo{
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("リンゴ");
set.add("オレンジ");
set.add("キウイ");
set.add("リンゴ");
for(String s: set) {
System.out.println(s);
}
}
}
========== 実行結果 ==========
リンゴ
キウイ
オレンジ
==============================
要素の重複不可なので最後に格納した「リンゴ」は変数のsetに格納されていません。
forのところをIteratorに換えても出力することもできます。実行結果は同じです。
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
† 地球の末路!? †
また、要素の重複不可なので重複している要素は取り込まれません。
class Demo{
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("リンゴ");
set.add("オレンジ");
set.add("キウイ");
set.add("リンゴ");
for(String s: set) {
System.out.println(s);
}
}
}
========== 実行結果 ==========
リンゴ
キウイ
オレンジ
==============================
要素の重複不可なので最後に格納した「リンゴ」は変数のsetに格納されていません。
forのところをIteratorに換えても出力することもできます。実行結果は同じです。
Iterator<String> iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
† 地球の末路!? †