(R)ベクトルの探索

初項2,公差3,末項44,項数15の等差数列を考えます。

> data <- seq(2,44,3)
> data
 [1]  2  5  8 11 14 17 20 23 26 29 32 35 38 41 44
  • ある数字(例えば26)が含まれているかどうかだけが知りたい場合
> data[data==26]
[1] 26

で調べることが可能です。26はベクトルに含まれるのでそのまま26が出力されています。

> data[data<10]
[1] 2 5 8

で10未満の数字が出力されるのと同じ理屈です。
含まれない場合、例えば27だと

> data[data==27]
numeric(0)

のようにnumeric(0)が返ってきます。なのである数字が含まれているかどうかはlength(data[data==○○])が0なのか1なのかで判定出来ます。

  • ある数字(例えば26)が含まれているか知った上で、その数字の添字を知りたい場合
> which(data==26)
[1] 9

で調べることが可能です。26はベクトルの9番目にあるので9が出力されています。
同様にこんなこともできます。

> which(data<10)
[1] 1 2 3

10未満の数字の添字が出力されています。
探索する数字が含まれない場合、上と同様に

> which(data==27)
integer(0)

整数型のinteger(0)が返ってきます。

(Java)BufferedReaderとScanner

標準入力データをそのまま表示し、"break"と入力されたら終わるプログラム

Scannerを用いた場合

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner stdIn = new Scanner(System.in);
		String line = "";
		while(!line.equals("break")){
			line = stdIn.next();
			System.out.println(line);
		}
	}
}

BufferedReaderを用いた場合

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String line = "";
		try{
			while(!line.equals("break")){
				line = br.readLine();
				System.out.println(line);
			}
		}catch(IOException e){
			System.out.println(e);
		}
	}
}

機能は同じですが、例外処理が必須な分BufferedReaderの方が文量が多くなります。
しかし処理速度はBufferedReaderの方が速いそうです。

(Java)プログラムの一時的な実行中止

sleepの引数に待機時間(ミリ秒)を指定します。

Date d = new Date();
System.out.println(d);
try{
	Thread.sleep(10000);
}catch (InterruptedException e){
}
d = new Date();
System.out.println(d);

出力

Sun May 26 11:35:27 JST 2013
Sun May 26 11:35:37 JST 2013

あれこれインポートせずに使えるので便利ですね。(上の例だとjava.util.Dateが必要です)

(Java)keySetとentrySet

HashMapのデータアクセスにkeySetを使う方法とentrySetを使う方法があります。

Map<String,Integer> hm = new HashMap<String,Integer>();
  • keySetを使う場合
for(String s : hm.keySet()){
	System.out.println(s+":"+hm.get(s));
}

直感的に分かり易いのですが、この記法(主にgetを用いること)は良くないらしいです。
keySetはkeyの情報だけが必要な場合に、key・value共に必要な場合はentrySetを用います。

  • entrySetを使う場合
for (Map.Entry<String, Integer> entry : hm.entrySet()) {
	System.out.println(entry.getKey()+":"+entry.getValue());
}

※補足 さらにiteratorを使う場合

Set<Map.Entry<String,Integer>> set = hm.entrySet();
Iterator<Map.Entry<String,Integer>> it = set.iterator();
while(it.hasNext()){
	Map.Entry<String,Integer> entry = it.next();
	System.out.println(entry.getKey()+":"+entry.getValue());
}

(Java)HashMapとIterator

Iteratorを使ってHashMapの全データにアクセスする方法をメモ

まず次のようなデータが格納されているHashMapを考えます。

Map<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1, "AAA");
hm.put(2, "BBB");
hm.put(3, "CCC");
hm.put(4, "DDD");

ネットでよく見かける方法はこんな感じ

Set s = hm.keySet();
Iterator it = s.iterator();
while(it.hasNext()){
	Object o = it.next();
	System.out.println(o + " ⇒ " + hm.get(o));
}

この方法で問題はないのですが、s,itの宣言部分できちんとパラメータ化しろと警告が出るのであまり気分はよくありません。なので以下のように記述するのが理想かと思います。(※HashMapのデータアクセスについて)

Set<Integer> s = hm.keySet();
Iterator<Integer> it = s.iterator();
while(it.hasNext()){
	int i = it.next();
	System.out.println(i + " ⇒ " + hm.get(i));
}

出力

1 ⇒ AAA
2 ⇒ BBB
3 ⇒ CCC
4 ⇒ DDD

(Java)List,Set,Mapの種類まとめ

List
|-- ArrayList   検索が多い場合に高速
`-- LinkedList   挿入・削除が多い場合に高速

Set(重複不可・順序保証なしのList)
|-- HashSet    最高速
`-- TreeSet    自動ソート

Map(キーが重複した場合は後に追加された値に置き換えられる)
|-- HashMap    最高速
`-- TreeMap    キー自動ソート

その他LinkedHashSet、LinkedHashMap等様々なクラスがありますがメジャーなのはこの辺でしょうか。

List,Set,Mapの3つはコレクションフレームワークとして一括りにされますが、厳密にはMapはCollectionインターフェースと関わりがないので注意が必要です。
図 http://www.javaroad.jp/java_collection1.htm

(Java)拡張for文とソート

メモ

  • 配列
int[] array = {3,2,5,1,4};
for(int i : array)	System.out.print(i+" ");
Arrays.sort(array);
System.out.println();
for(int i : array)	System.out.print(i+" ");

出力

3 2 5 1 4 
1 2 3 4 5
List<Character> al = new ArrayList<Character>();
al.add('C'); al.add('B'); al.add('E'); al.add('A'); al.add('D');
for(char c : al)	System.out.print(c+" ");
Collections.sort(al);
System.out.println();
for(char c : al)	System.out.print(c+" ");

出力

C B E A D 
A B C D E
  • HashSet
Set<Double> set = new HashSet<Double>();
set.add(3.); set.add(2.); set.add(5.); set.add(1.); set.add(4.); set.add(5.);//重複は後に入力したデータが残る
for(double d : set)	System.out.print(d+" ");
set = new TreeSet<Double>(set);
System.out.println();
for(double d : set)	System.out.print(d+" ");

出力

3.0 2.0 1.0 4.0 5.0 
1.0 2.0 3.0 4.0 5.0 

これなら最初からTreeSet使ったほうがいいかも。

  • HashMap
Map<String,Integer> hm = new HashMap<String,Integer>();
hm.put("C",1); hm.put("B",2); hm.put("E",3); hm.put("A",4); hm.put("D",5); 
for(String s : hm.keySet())	System.out.print(s+":"+hm.get(s)+" ");
hm = new TreeMap<String,Integer>(hm);
System.out.println();
for(String s : hm.keySet())	System.out.print(s+":"+hm.get(s)+" ");

出力

D:5 E:3 A:4 B:2 C:1 
A:4 B:2 C:1 D:5 E:3 

これも最初からTreeMap使ったほうがいいかも。(※HashMapのデータアクセスについて)


拡張for文があるとIteratorを使わなくて良いので楽ですね。
拡張forのメモを兼ねているので上のような出力方法にしていますが、下のようにまとめて書くこともできます。

System.out.println(Arrays.toString(array));
System.out.println(al);
System.out.println(set);
System.out.println(hm);

出力

[1, 2, 3, 4, 5]
[A, B, C, D, E]
[1.0, 2.0, 3.0, 4.0, 5.0]
{A=4, B=2, C=1, D=5, E=3}