//LinearSearch2.java
//線形探索
import java.util.Scanner;
public class LinearSearch2 {
//配列aの要素からKeyと一致する最も先頭の要素を線形探索
static int linearSearch(int[] a, int key){
for(int i = 0; i < a.length; i++)
if(a[i] == key)
return i; //探索成功
return -1; //探索失敗
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数:");
int num = stdIn.nextInt();
int[] x = new int[num];
for(int i = 0; i < num; i++){
System.out.print("x[" + i + "]:");
x[i] = stdIn.nextInt();
}
System.out.print("探す値:");
int ky = stdIn.nextInt();
int idx = linearSearch(x, ky);
if(idx == -1)
System.out.println("その値の要素は存在しません。");
else
System.out.println("その値はx[" + idx + "]にあります。");
stdIn.close();
}
}
線形探索を行うのが、linearSearch2 メソッドです。配列 a から key と一致する要素の中から最も先頭側に位置する要素を線形探索します。探索に成功した場合は、見つけた要素のインデックスを返し、失敗した場合は、 -1 を返します。
使い捨ての配列
以下のプログラムを考えてみましょう。(k は適当な値)
int[] a = (1, k, K + 5, 2 * k);
int[] i = linearSearch(a,3); //値が3である要素を探す
先頭から順に、初期化された配列 a の要素中に値3が存在するかどうか調べます。ここでは、値3があるか調べるだけであり、終わったら配列 a が不要になります。このような使い捨ての配列にわざわざ参照する配列変数を割り当てる必要はないです。以下のように実現できるからです。
int i = linearSearch(new int[](1, k, k + 5, 2 + k), 3);
配列の要素の並びを逆転する
配列の要素の並びを逆転する独立したメソッドを実現したプログラムを作りましょう。
//ReverseArray2.java
//配列の要素に値を読み込んで並びを反転する
import java.util.Scanner;
public class ReverseArray2 {
//配列の要素a[idx1]とa[idx2]を交換
static void swap(int[] a, int idx1, int idx2){
int t = a[idx1]; a[idx1] = a[idx2]; a[idx2] = t;
}
//配列aの要素の並びを逆転
static void reverse(int[] a){
for(int i = 0; i < a.length / 2; i++)
swap(a, i ,a.length - i - 1);
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数:");
int num = stdIn.nextInt();
int[] x = new int[num];
for(int i = 0; i < num; i++){
System.out.print("x[" + i + "]:");
x[i] = stdIn.nextInt();
}
reverse(x);
System.out.println("要素の並びを逆転しました。");
for(int i = 0; i < num; i++)
System.out.println("x[" + i + "] = " + x[i]);
stdIn.close();
}
}
//GenIdxArray.java
//全要素がインデックスと同じ値を持つ配列の生成
import java.util.Scanner;
public class GenIdxArray {
//全要素がインデックスと同じ値をもつ要素数nの配列を生成して返却
static int[] idxArray(int n){
int[] a = new int[n];
for(int i = 0; i < n; i++)
a[i] = i;
return a;
}
public static void main(String[] args) {
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数は:");
int n = stdIn.nextInt();
int [] x = idxArray(n);
for(int i = 0; i < n; i++)
System.out.println("x[" + i + "] = " + x[i]);
stdIn.close();
}
}
メソッド idxArrayは、仮引数 n にint型整数値を受け取ります。メソッド本体で行うのは以下のことです。
//MaxOverload.java
//2値と3値の最大値を求めるメソッド(多重定義)
import java.util.Scanner;
public class MaxOverload {
//a、bの最大値を返却
static int max(int a, int b){
return a > b ? a : b;
}
//a、b、cの最大値を返却
static int max(int a, int b, int c){
int max = a;
if(b > max) max = b;
if(c > max) max = c;
return max;
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("xの値:"); int x = stdIn.nextInt();
System.out.print("yの値:"); int y = stdIn.nextInt();
System.out.print("zの値:"); int z = stdIn.nextInt();
System.out.println("x、yの最大値は" + max(x, y) + "です。");
System.out.println("x、y、zの最大値は" + max(x, y, z) + "です。");
stdIn.close();
}
}
& はビット論理積演算子(bitwise and operator)、| はビット論理和演算子(bitwise inclusive or operator)、^ はビット排他的論理和演算子(bitwise exclusive or operator)、~ はビット単位の補数演算子(bitwise complement operator)と呼ばれます。これらの演算子で行われる論理演算の真理値表が以下になります。
2つの整数を読み込んで、ビット単位の論理演算を行った結果を表示するプログラムを以下に示します。
//BitwiseOperation.java
//int型整数のビット単位の論理積・論理和・排他的論理和・補数を表示
import java.util.Scanner;
public class BitwiseOperation {
//int型のビット構成を表示
static void printBits(int x){
for(int i = 31; i >= 0; i--)
System.out.print(((x >>> i & 1) == 1) ? '1' : '0');
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.println("2つの整数を入力してください。");
System.out.print("a:"); int a = stdIn.nextInt();
System.out.print("b:"); int b = stdIn.nextInt();
System.out.print("a = "); printBits(a);
System.out.print("\nb = "); printBits(b);
System.out.print("\na & b = "); printBits(a & b);
System.out.print("\na | b = "); printBits(a | b);
System.out.print("\na ^ b = "); printBits(a ^ b);
System.out.print("\n~a = "); printBits(~a);
System.out.print("\n~b = "); printBits(~b);
stdIn.close();
}
}
//Max3Method.java
//3つの整数値の最大値を求める(メソッド)
import java.util.Scanner;
public class Max3Method {
static int max(int a, int b, int c){
int max = a;
if(b > max) max = b;
if(c > max) max = c;
return max;
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("整数a:"); int a = stdIn.nextInt();
System.out.print("整数b:"); int b = stdIn.nextInt();
System.out.print("整数c:"); int c = stdIn.nextInt();
System.out.println("最大値は" + max(a, b, c) + "です。");
stdIn.close();
}
}
//Power.java
//べき乗をもとめる
import java.util.Scanner;
public class Power {
//xのn乗を返す
static double power(double x, int n){
double tmp = 1.0;
for(int i = 1; i <= n; i++)
tmp *= x;
return tmp;
}
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.println("aのb乗を求めます。");
System.out.print("実数a:"); double a = stdIn.nextDouble();
System.out.print("整数b:"); int b = stdIn.nextInt();
System.out.println(a + "の" + b + "乗は" + power(a, b) + "です。" );
stdIn.close();
}
}
nが整数ですから、xをn回掛け合わせた値がxのn乗です。メソッドをpowerでは、1.0で初期化された変数tmpに対して、xの値をn回掛けています。for文が終了した時に最終的な値がtmpに渡されます。このように引数として値がやり取りされるメカニズムを値渡し(pass by value)と呼ばれます。
max = a[0];
if(a[1] > max) max = a[1];
if(a[2] > max) max = a[2];
このif文をより柔軟に書き換えた形が以下になります。
max = a[0];
for(int i = 1; i < a.length; i++)
if(a[i] > max) max = a[i];
このように配列の要素1つずつ順になぞっていく手続きを走査(traverse)と呼びます。
キーボードから読み込んだ値から最高点を求めるプログラムを走査を使って作成しましょう。
//HighScore.java
//点数を読み込んで最高値を表示
import java.util.Scanner;
public class HighScore {
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
final int num = 5;
int[] score = new int[num];
System.out.println(num + "人分の点数を入力してください。");
for(int i = 0; i < num; i++){
System.out.print((i + 1) + "番の点数:");
score[i] = stdIn.nextInt();
}
int max = score[0];
for(int i = 1; i < score.length; i++)
if(score[i] > max) max = score[i];
System.out.println("最高点は" + max + "点です。");
stdIn.close();
}
}
//ArraySumForIn.java
//配列の全要素の和を求めて表示(拡張for文)
public class ArraySumForIn {
public static void main(String[] args){
double[] a = {1.0, 2.0, 3.0, 4.0, 5.0};
for(int i = 0; i < a.length; i++)
System.out.println("a[" + i + "] =" + a[i]);
double sum = 0;
for(double i : a)
sum += i;
System.out.println("全要素の和は" + sum + "です。");
}
}
このfor文は以下のように理解しましょう。
配列 a の先頭から末尾までの全要素を1個ずつ走査します。ループ本体では、現在着目している要素を i と表現します。
//ReverseArray.java
//配列の要素の順序を逆順に並べて表示
import java.util.Random;
import java.util.Scanner;
public class ReverseArray {
public static void main(String[] args){
Random rand = new Random();
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数:");
int n = stdIn.nextInt();
int[] a = new int[n];
for(int i = 0; i < n; i++){
a[i] = 10 + rand.nextInt(90);
System.out.println("a[" + i + "] :" + a[i]);
}
for(int i = 0; i < n / 2; i++){
int t = a[i];
a[i] = a[n - i - 1];
a[n - i - 1] = t;
}
System.out.println("要素の並びを逆にしました。");
for(int i = 0; i < n; i++)
System.out.println("a[" + i + "] :" + a[i]);
stdIn.close();
}
}
//CoppyArray.java
//配列の全要素をコピー
import java.util.Scanner;
public class CoppyArray {
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数:");
int n = stdIn.nextInt();
int[] a = new int[n];
int[] b = new int[n];
for(int i = 0; i < n; i++){
System.out.print("a[" + i + "] = ");
a[i] = stdIn.nextInt();
}
for(int i = 0; i < n; i++)
b[i] = a[i];
System.out.println("aの全要素を配列bにコピーしました。");
for(int i = 0; i < n; i++)
System.out.println("b[" + i + "] = " + b[i]);
stdIn.close();
}
}
配列のコピーを行うのが、以下の部分です。これにより、a[0]をb[0]にa[1]をb[1]にと i の数だけコピーしていくことができます。
//PointSumAve.java
//点数を読み込んで合計点、平均点を表示
import java.util.Scanner;
public class PointSumAve {
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
int sum = 0;
System.out.println("5人の点数を入力してください。");
System.out.print("1番の点数:");
int akane = stdIn.nextInt();
sum += akane;
System.out.print("2番の点数:");
int baba = stdIn.nextInt();
sum += baba;
System.out.print("3番の点数:");
int cocone = stdIn.nextInt();
sum += cocone;
System.out.print("4番の点数:");
int docomo = stdIn.nextInt();
sum += docomo;
System.out.print("5番の点数:");
int eita = stdIn.nextInt();
sum += eita;
System.out.println("合計は" + sum + "点です。");
System.out.println("平均は" + (double)sum / 5 + "点です。");
stdIn.close();
}
}
//IntArray2.java
//配列の各要素に1,2,3,4,5を代入表示
public class IntArray2 {
public static void main(String[] args){
int[] a = new int[5];
for(int i = 0; i < a.length; i++)
a[i] = i + 1;
for(int i = 0; i < a.length; i++)
System.out.println("a[" + i + "] = " + a[i]);
}
}
//IntArrayScan.java
//配列の全要素に値を読み込んで表示
import java.util.Scanner;
public class IntArrayScan {
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
System.out.print("要素数:");
int n = stdIn.nextInt();
int[] a = new int[n];
for(int i = 0; i < n; i++){
System.out.print("a[" + i + "] = ");
a[i] = stdIn.nextInt();
}
System.out.println("");
for(int i = 0; i < n; i++)
System.out.println("a[" + i + "] =" + a[i]);
stdIn.close();
}
}
//IntArrayInit.java
//配列の各要素を数字で初期化表示
public class IntArrayInit {
public static void main(String[] args){
int[] a = {1,2,3,4,5};
for(int i = 0; i < a.length; i++)
System.out.println("a[" + i + "] = " + a[i]);
}
}
//PointSumAveArray.java
//点数を読み込んで合計点、平均点を表示
import java.util.Scanner;
public class PointSumAveArray {
public static void main(String[] args){
Scanner stdIn = new Scanner(System.in);
int sum = 0;
final int num = 5;
int[] score = new int[num];
System.out.println(num + "人分の点数を入力してください。");
for(int i = 0; i < num; i++){
System.out.print((i + 1) + "番の点数:");
score[i] = stdIn.nextInt();
sum += score[i];
}
System.out.println("合計は" + sum + "点です。");
System.out.println("平均は" + (double)sum / num + "点です。");
stdIn.close();
}
}
//CarriageReturn.java
//復帰の出力によって表示済み文字を書き換える
public class CarriageReturn{
public static void main(String[] args){
System.out.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
System.out.println("\r12345");
}
}