deleteメソッドを呼ぶ直前と直後に、dump_hashtableメソッドを呼ぶと 以下のような結果が出力される。
0: 1: 2: 3:xyz 4:abc 5:yyy 6: 7: 8: 9: 0: 1: 2: 3:DELETED 4:abc 5:yyy 6: 7: 8: 9: 0: 1: 2: 3:zyx 4:abc 5:yyy 6:bbb 7: 8: 9:
ハッシュ表の3にxyzが格納されていたのが、削除することで、DELETEDに変え られ、その後、zyxが格納されていることが分かる。
ハッシュ表の中で一度削除した部分に再び違うデータが格納される例を考え
る課題:
例えば、runメソッド内に以下のように記述する。
set("fff");
set("efg");
dump_hashtable();
delete("fff");
dump_hashtable();
set("feg");
dump_hashtable();
実行すると以下のような結果を得る(5〜8のみ示す)。
5: 6:fff 7:efg 8: 5: 6:DELETED 7:efg 8: 5: 6:feg 7:efg 8:
runメソッド内に以下のように記述する。
set("fff");
dump_hashtable();
delete("fff");
set("DELETED");
dump_hashtable();
set("feg");
set("yyy");
dump_hashtable();
実行すると以下のような結果を得る(3〜7のみ示す)。
3: 4: 5: 6:fff 7: 3:DELETED 4: 5: 6:DELETED 7: 3:DELETED 4:yyy 5: 6:feg 7:
まず、fffはハッシュ表の6に格納された。次にfffを削除し、ハッシュ表の 6に削除を示すDELETED(変数deletedの値)が格納された。文字列DELETEDの ハッシュ値は3となり、ハッシュ表の3に格納された。 次にfegをハッシュ表に格納しようとすると、ハッシュ値である6の場所には、 削除を示すDELETEDが入っており、そこにfegが格納された。 yyyを格納しようとすると、ハッシュ値である3の場所には、set("DELETED") で格納した文字列データが入っており、そこには格納されず、その1つ下の 4にyyyが格納された。このように、削除を示すDELETEDと、set("DELETED") でハッシュ表に格納したデータが区別されていることが分かる。
public class HashData {
public String key;
public String name;
public int math;
public int english;
public String email;
}
Hash5.java
public class Hash5 {
final int size = 10;
HashData hashtable[] = new HashData[size];
String deleted = new String("DELETED");
// String deleted = new String("DELETED");
public static void main(String args[]) {
Hash5 s = new Hash5();
s.run();
}
public void run() {
// ハッシュ表をクリア(全部null)
for(int i = 0; i < hashtable.length; i++) {
hashtable[i] = null;
}
set("s03881", "山田太郎", 80, 85, "yamada@hogehoge.example");
set("s03872", "松田二郎", 70, 87, "matsuda@hogehoge.example");
dump_hashtable(); // ハッシュ表の内容を表示する
print_exist("s03881"); // "abc"というデータは存在するか?
print_exist("s03882"); // "abc"というデータは存在するか?
}
int hash(String key) {
int s = 0;
for (int i = 0; i < key.length(); i++) {
s += key.charAt(i);
}
return s % size;
}
void set(String key, String name, int math, int english, String email) {
int hashcode = hash(key);
HashData d = new HashData();
d.key = key;
d.name = name;
d.math = math;
d.english = english;
d.email = email;
while(hashtable[hashcode] != null &&
hashtable[hashcode].key != deleted) {
hashcode++;
}
hashtable[hashcode] = d;
}
boolean delete(String key) {
int hashcode = hash(key);
while(hashtable[hashcode] != null) {
if (hashtable[hashcode].key == key) {
hashtable[hashcode].key = deleted;
return true;
}
hashcode++;
}
return false;
}
void print_exist(String key) {
int hashcode = hash(key);
while(hashtable[hashcode] != null) {
HashData d = hashtable[hashcode];
if (d.key == key) {
System.out.println(key + "は存在します" +
"(" + d.key + "," + d.name + "," +
d.math +"," + d.english + "," + d.email + ")");
return;
}
hashcode++;
}
System.out.println(key + "は存在しません");
}
void dump_hashtable() {
for (int i = 0; i < hashtable.length; i++) {
System.out.print(i + ":");
HashData d = hashtable[i];
if (d == null) {
System.out.println();
} else {
System.out.println(d.key + "," + d.name + "," +
d.math +"," + d.english + "," + d.email);
}
}
}
}
public class HashData {
private String key;
private String name;
private int math;
private int english;
public String getKey() { return key; }
public String getName() { return name; }
public int getMath() { return math; }
public int getEnglish() { return english; }
public void setKey(String k) { key = k; }
public void setName(String n) { name = n; }
public void setMath(int m) { math = m; }
public void setEnglish(int e) { english = e; }
}
Hash5.java
public class Hash5 {
final int size = 10;
HashData hashtable[] = new HashData[size];
String deleted = new String("DELETED");
// String deleted = new String("DELETED");
public static void main(String args[]) {
Hash5 s = new Hash5();
s.run();
}
public void run() {
// ハッシュ表をクリア(全部null)
for(int i = 0; i < hashtable.length; i++) {
hashtable[i] = null;
}
set("s03881", "山田太郎", 80, 85);
set("s03872", "松田二郎", 70, 87);
dump_hashtable(); // ハッシュ表の内容を表示する
print_exist("s03881"); // "abc"というデータは存在するか?
print_exist("s03882"); // "abc"というデータは存在するか?
}
int hash(String key) {
int s = 0;
for (int i = 0; i < key.length(); i++) {
s += key.charAt(i);
}
return s % size;
}
void set(String key, String name, int math, int english) {
int hashcode = hash(key);
HashData d = new HashData();
d.setKey(key);
d.setName(name);
d.setMath(math);
d.setEnglish(english);
while(hashtable[hashcode] != null &&
hashtable[hashcode].getKey() != deleted) {
hashcode++;
}
hashtable[hashcode] = d;
}
boolean delete(String key) {
int hashcode = hash(key);
while(hashtable[hashcode] != null) {
if (hashtable[hashcode].getKey() == key) {
hashtable[hashcode].setKey(deleted);
return true;
}
hashcode++;
}
return false;
}
void print_exist(String key) {
int hashcode = hash(key);
while(hashtable[hashcode] != null) {
HashData d = hashtable[hashcode];
if (d.getKey() == key) {
System.out.println(key + "は存在します" +
"(" + d.getKey()+ "," + d.getName() + "," +
d.getMath() +","+ d.getEnglish() + ")");
return;
}
hashcode++;
}
System.out.println(key + "は存在しません");
}
void dump_hashtable() {
for (int i = 0; i < hashtable.length; i++) {
System.out.print(i + ":");
HashData d = hashtable[i];
if (d == null) {
System.out.println();
} else {
System.out.println(d.getKey() + "," + d.getName() + "," +
d.getMath() +"," + d.getEnglish());
}
}
}
}
HashData.javaに以下のメソッドを追加する。
public int getTotal() { return math+english; }
また、Hash5.javaのprint_exist,dump_hashtableメソッドを 以下のように修正する。
void print_exist(String key) {
int hashcode = hash(key);
while(hashtable[hashcode] != null) {
HashData d = hashtable[hashcode];
if (d.getKey() == key) {
System.out.println(key + "は存在します" +
"(" + d.getKey() + "," + d.getName() + "," +
d.getMath() +"," + d.getEnglish() +
"," + d.getTotal() + ")");
return;
}
hashcode++;
}
System.out.println(key + "は存在しません");
}
void dump_hashtable() {
for (int i = 0; i < hashtable.length; i++) {
System.out.print(i + ":");
HashData d = hashtable[i];
if (d == null) {
System.out.println();
} else {
System.out.println(d.getKey() + "," + d.getName() + "," +
d.getMath() +"," + d.getEnglish() +"," +
d.getTotal());
}
}
}