こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

トラックバック先のURLの抽出でループを避けたい

ブログのトラックバック先のURLを取得するプログラムを作っています。

例えば、ブログAの記事に、B,Cのブログがトラックバックをして
ブログBにブログaが、ブログCにはブログbがトラックバックをしていて、
さらにブログaにはブログ1がトラックバックをしていたとします。

このとき、ブログB,C,a,b,1のURLを取得するプログラムをこちらのご回答を参考にしながら、以下のように作りました。

public class BlogTB {
public static void main(String[] args) {
ArrayList al = new ArrayList();
String url = args[0];
addUrl(al, url);
String[] TBURL = (String[])al.toArray(new String[0]);
for(int i = 0 ; i < TBURL.length ; i++) {
System.out.println(TBURL[i]);
}
}
private static void addUrl(ArrayList al, String url) {
al.add(url);
String[] TBURL = HTMLTB.getHTMLtb(url);
if (TBURL[0].equals("")) return;
for(int i = 0 ; i < TBURL.length ; i++) {
addUrl(al, TBURL[i]);
}
}
}

HTMLTB.getHTMLtbでは、トラックバック先のURLを取得する処理を行い、その一覧をTBURLに格納します。

この操作を再帰的に繰り返して、トラックバック先のURLを取得させています。

ここで、もし上記のケースで、
ブログ1がブログaにトラックバックをしていた場合(トラックバック返し)や、
ブログ1がブログAにトラックバックをしていた場合などでは、
上記のプログラムを走らせると、ループになっていまいます。

登録しようとしているurlがalに既に登録済みかどうかのチェックなど、
重複するURLをTBURLに登録しないようにして、
ループを防ぐためには、プログラムをどのように改正すればいいでしょうか?

よろしくお願いします。

投稿日時 - 2005-11-13 00:53:13

QNo.1775490

すぐに回答ほしいです

質問者が選んだベストアンサー

重複チェックなら、HashSetがいいと思います。
URL登録先をArrayListからHashSetに変えてみました。
addUrlの最初に、URLがすでに登録されているか見て、
登録されていればその先の処理をしないようにしています。
(ただしHashSetを使うと、順序は保証されません)

--------------------------

import java.util.HashSet;
import java.util.Iterator;

public class BlogTB {
  public static void main(String[] args) {
    HashSet hs = new HashSet();
    String url = args[0];
    addUrl(hs, url);
    Iterator it = hs.iterator();
    while(it.hasNext() == true) {
      System.out.println((String)it.next());
    }
  }
  
  private static void addUrl(HashSet hs, String url) {
    if(hs.contains(url) == true) {
      return;
    }
    hs.add(url);
    String[] TBURL = HTMLTB.getHTMLtb(url);
    if (TBURL[0].equals("")) return;
    for(int i = 0 ; i < TBURL.length ; i++) {
      addUrl(hs, TBURL[i]);
    }
  }
}

投稿日時 - 2005-11-13 13:31:11

お礼

ご回答ありがとうございます。

ご回答を参考にプログラムを動かし、
無事、ループせずにURLを取得できました。

ところで、HashSetを使うと、順序は保証されないとのことですが、
できれば取得した順序そのままで配列に格納したいのですが、
この場合はどのようにすればいいでしょうか?

投稿日時 - 2005-11-13 16:23:45

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

>取得した順序そのままで配列に格納したいのですが、
順序が大事な場合、vectorかArrayListに格納してやればいいでしょう。
vectorやArrayListにすでに登録されているかどうかは、indexOfを使って調べることができます。
リストが長くなると、重複登録のチェックに時間がかかるようになるので、登録チェックのためにはHashSetを使うというように混用してもいいかと思います。

投稿日時 - 2005-11-14 04:21:09

お礼

ご回答ありがとうございます。

>vectorやArrayListにすでに登録されているかどうかは、indexOfを使って調べることができます。

>登録チェックのためにはHashSetを使うというように混用してもいいかと思います。

具体的にはどのようにプログラムを組めばよろしいでしょうか?

投稿日時 - 2005-11-15 23:39:41

ANo.1

クラス変数でハッシュなどを使って、登録されていない場合に登録する(&再帰的に探しに行く)
というような感じすればいいでしょう
例えば、HashSetで
add(E)の返値を調べればハッシュに追加ができたかどうかで
新しく登録できたかどうかがわかります。

投稿日時 - 2005-11-13 02:06:53

お礼

ご回答ありがとうございます。

投稿日時 - 2005-11-13 16:19:29

あなたにオススメの質問