ToDo:
まて。Map は実装じゃないし、TreeMap はその名のとおり木だ。主要プログラミング言語におけるハッシュテーブルの実装
- JavaにおけるMap、HashMap、TreeMap、LinkedHashMap、Hashtable クラス(またはインタフェース)
ハッシュテーブル - Wikipedia
Wikipediaのハッシュテーブルの項目書いた人は、キーと値を対応付ける抽象データ型(マップなどの名前で呼ばれる)と、それを実装するためのデータ構造の一つであるハッシュテーブルの区別がついてないんだろうなあ。というわけで、抽象データ型とデータ構造の区別は大事ですよ、と。
あと、メジャーなスクリプト言語(Perl, Rubyなど)で、マップのことをハッシュと呼ぶことが多いことも誤解に拍車をかけている気がする(別にこれらスクリプト言語の作者がこの辺のことを理解してないと思っているわけではない。念のため。たぶん、標準ではマップの実装がハッシュテーブルによるもののみであることが多いから、そう呼んでいるだけなのだと思う)。
きしだのはてなより:
で、今回は「int型の配列を並べ替えて表示」
つまり
print(new int[]{14, 13, 71, 2, 24, 19}); print(new int[]{3, 2}); print(new int[]{5}); print(new int[]{}); print(null);とすると
2 13 14 19 24 71 2 3 5 空です nullですと表示するprintメソッド。
で、今回の制限は
- while, if, switch, try, throws, 3項演算子は使わない
- forは1回だけ。形は問わない。使わないほうがえらい
- APIはjava.langの範囲で。System.out.println/print/printfはOKです。
- できたコードが面白くなるなら上記の制約は無し。
とのこと。面白そうなので、自分も書いてみた。ソートアルゴリズムについては特に指定は無いが、とりあえずバブルソートでやることにする。メソッドはいくつ作っても良いようだが、それだと再帰を使えばどうとでもなるので、メソッドはmainメソッドとお題のprintメソッド以外は作らない事にする。
いきなり条件を満たすコードを書くのは面倒なので、まずは、ifやforを2つ以上使った、正攻法から。
import static java.lang.System.*;
public class SortPrint {
static void print(int[] a) {
if(a == null){
out.printf("nullです%n");
return;
}
if(a.length == 0){
out.printf("空です%n");
return;
}
for(int i = 0; i < a.length; i++){
for(int j = a.length - 1; j > i; j--){
if(a[j - 1] > a[j]){
int tmp = a[j - 1];
a[j - 1] = a[j];
a[j] = tmp;
}
}
out.printf("%d ", a[i]);
}
out.printf("%n");
}
public static void main(String[] args){
print(new int[]{14, 13, 71, 2, 24, 19});
print(new int[]{3, 2});
print(new int[]{5});
print(new int[]{});
print(null);
}
}
まずは一番内側の比較とswapを行っている箇所のif文を除去する。3項演算子が使えないので、&&演算子を使うことにする。Javaの場合、通常の演算子だけから成る式は式文になれないため、やや面倒だが、それ以外はさほど難しく無い。
static void print(int[] a) {
if(a == null){
out.printf("nullです%n");
return;
}
if(a.length == 0){
out.printf("空です%n");
return;
}
for(int i = 0; i < a.length; i++){
for(int j = a.length - 1; j > i; j--){
boolean c = a[j - 1] > a[j] && (t = a[j - 1]) == t
&& (a[j - 1] = a[j]) == a[j - 1]
&& (a[j] = t) == a[j];
}
out.printf("%d ", a[i]);
}
out.printf("%n");
}
次に、null判定と配列の長さが0かどうか判定している箇所のif文を除去する。ここでは、return文を使っているため、上の例ほど直接的に置き換えることはできないが、基本的には同じ。
static void print(int[] a) {
boolean b = a == null && out.printf("nullです") != null
&& (a = new int[0]) != null
|| a.length == 0 && out.printf("空です") != null;
int i = a.length;
b = a != null && (i = 0) == i ;
for(i = 0; i < a.length; i++){
for(int j = a.length - 1; j > i; j--){
boolean c = a[j - 1] > a[j] && (t = a[j - 1]) == t
&& (a[j - 1] = a[j]) == a[j - 1]
&& (a[j] = t) == a[j]
}
out.printf("%d ", a[i]);
}
out.printf("%n");
}
最後に、内側のforループを除去して、終了。
static void print(int[] a) {
boolean b;
b = a == null && out.printf("nullです") != null
&& (a = new int[0]) != null
|| a.length == 0 && out.printf("空です") != null;
int i = a.length, j = 0;
b = a != null && (i = 0) == i
&& (j = a.length - 1) == j;
for(;i < a.length;){
int t;
boolean c;
c = j > i && a[j - 1] > a[j]
&& (t = a[j - 1]) == t
&& (a[j - 1] = a[j]) == a[j - 1]
&& (a[j] = t) == a[j];
j--;
c = j <= i && out.printf("%d ", a[i]) != null
&& i++ != -1
&& (j = a.length - 1) == j;
}
out.printf("%n");
}
上のプログラムを作るために調べていて初めて知ったんだが、
java.io.PrintStream#printf(String format, Object... args)
の返り値って、そのPrintStream自身(this)だったのね。printとかprintlnの返り値がvoidだったから、てっきりprintfの返り値もvoidかと思ってた…。他にもformatやappendもthisを返すようだ。たぶん、
out.printf("public class %s {%n", class_name)
.printf(" public static void main(String[] args) {%n")
.printf(" }%n")
.printf("}%n");
みたいな使い方をするためなんだろうなあ。
_ ささだ [おお、PPL2007。いいなぁ。]
_ しゅ [急遽行くことに>PPL2007]
_ みずしま [>ささださん 今からでも遅くないので(ry。いや、嘘ですが。 >しゅ さん おお。当日お会いしたらよろしく..]