質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.78%

単語の種類がいくつあるか表示する方法を教えてください。

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 926

jahaa

score 12

与えられたファイル中の必ず単語で区切ってある単語で、toLowerCaseで大文字小文字の区別をなくし、重複している単語を除いて単語の種類がいくつあるかを表示するプログラムを教えていただきたいです。よろしくお願いします。

import java.io.BufferedReader;
import java.io.FileReader;

public class FileReadLine {
    public static void main(String[] args) throws Exception{
            String str = "";
            BufferedReader br = new BufferedReader( new FileReader( "reya.txt" ) );
            while( br.ready() ){
                str += br.readLine() + " ";
            }
            br.close();

            String [] word = str.split("[\\p{Blank}|\\.|,]++");

            System.out.println( "単語数は:" + word.length );

    }
}


追記:ご指摘いただいた皆様ありがとうございます。
The objective of the department is to perform basic scientific
research and education in the field of Information Science and
Engineering, whose importance as a research field is continuously
increasing in recent days. In particular, applying of mathematical
methodologies towards information processing and their systems, as
well as exploring basic mathematical disciplines in computer science,
are strongly deemed as immediate research needs.
このような英文の単語の種類を知りたいです。現在の状況では、重複した単語を削除できずにいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mather

    2019/05/24 17:33

    日本語を自分で読み直して、実現したいことを丁寧に説明してください。
    - reya.txt の内容を(サンプルでもいいので)記載する。改行区切りの単語一覧なのか、普通の文章が入っているのかわからない。
    - 現在のコードでは何が問題なのか書く。
    - 期待される結果はどのようなものか書く。

    キャンセル

  • 退会済みユーザー

    2019/05/24 18:28

    複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という意見がありました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

  • sage

    2019/05/24 23:06

    (1) 単語の種類って、名詞、動詞、形容詞、・・・ではないですね?
    (2) 重複の定義は? (名詞の単複の違い、動詞の時制・活用形の違いをどう扱うか。同一と扱うのならば辞書が必要)

    キャンセル

回答 2

+3

重複を削除する方法として有力なのは大きく2つ。
「Setを利用する」か「Stream#distinctを使う」です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/24 22:08

    ありがとうございます!さっそく試してみます!

    キャンセル

+2

swordoneさんの有力候補が望ましいのかもしれませんが、一応書いておきます。


追記読みました。

まず、jahaaさん、コードじゃなくて、普通に人間として問題文を解くとするならどうしますか?

コードを組む・アルゴリズムを考えるetc.のようなコンピュータからは離れているとして。

私なら、

The objective of the department is to perform basic scientific
research and education in the field of Information Science and
Engineering, whose importance as a research field is continuously
increasing in recent days. In particular, applying of mathematical
methodologies towards information processing and their systems, as
well as exploring basic mathematical disciplines in computer science,
are strongly deemed as immediate research needs.

ですので、最初に The を読む。The は今のところ1回目(だって最初だし) なので
The: 1
となります。
次のobjective も同様に +1 して
objective: 1
になりますね。

...and education in the field of Information...

の部分で二回目のthe が出てきます。
よって、the を +1 して
the: 2
とします。

これをneeds.まで行います。

これをコード化するにはどうすればいいでしょうか?

まず一つ目の疑問。

「どうやって初めてかどうかがわかるか」。

二つ目の疑問。

「どうやって+1していくのか」。

ですね。

一つ目の疑問は、リスト構造か何かに入れておいて、そこにないなら「新規」、あるなら「既存」と考えられる。
そして、個数を数えるために、カウンタを用意したい。

そこで、私なら、C言語でいう構造体か、クラスを用意します。

少なくとも「データ自体」と「カウンタ」を持つクラスだとします。

一応JavaなのでできるだけOOPでやりたいなぁってことで、

私なら

public class Word{
       // コンストラクタ
       public Word( String key ){
               key_ = key;
               counter_ = 0; // 0で初期化しておく
       }
       private String key_;
       private int counter_;
}

みたいにします。
でもこれではprivateなメンバは操作できないので、カウンタを操作するメンバを追加します。

(今回は) -1したり、+3 したりとかはないので、単に +1 するメソッドを追加します。

public class Word{
       // コンストラクタ
       public Word( String key ){
               key_ = key;
               counter_ = 0; // 0で初期化しておく
       }
       // カウンタ操作系
       public void up(){ counter_++; }

       private String key_;
       private int counter_;
}

このままだとカウントだけして、結果がわからないので、結果を表示するメソッドか、get系を追加します。
(できればオブジェクト自身ができればいいんですがねぇ。)

(追記2: swordoneさんからご指摘を受けました。すみません、勘違いしていました。問題文では、「単語数を調べる」ですが、私は「それぞれの単語の出現回数を調べる」だと思っていたので... 単語数のほうなら「upメソッドとかそういうの」は不要になりますね。一応、考え方としての意味でそのままにしておきますね。)

(追記2.1: 単に単語数を数えたいならクラスや構造体にする必要は...ないですね。大雑把なロジックは一緒ですが、単純に Stringのリストか配列を用意すればいいだけですし。)

public class Word{
       // コンストラクタ
       public Word( String key ){
               key_ = key;
               counter_ = 0; // 0で初期化しておく
       }
       // カウンタ操作系
       public void up(){ counter_++; }

       // keyと tokenが一致するかどうか
       public bool isMatch( String token ){
                   return ...; // todo: ここの処理はご自分で!
       }
    
       // 文字列にして返す
       public String toResultString(){
               return (key_ + ":" + counter_);
       }

       private String key_;
       private int counter_;
}

としておけば、

// 文字列を分解してList<String> tokensに入れているとして。
// そして、仮に the だけを数えていくとするなら。( Word the だとして )
for( int i = 0; i < tokens.length(); i++ ){
      if( the.isMatch( tokens[i] ) ){
           the.up();
      }
}
... // ほかの処理

System.out.println( the.toResultString() );

みたいにできます。

例では"the"だけですが、List<Word> words とかに入れてやっていくとか。

これはあくまで、私が何となく思いついたものです。

なので、おかしな部分もあると思います。

そこは修正してください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/05/26 12:37

    細かいですが、種類数だけカウントするなら「+1」の操作はいらないと思います。
    重複があったら無視するだけで十分かと。
    もちろん、「各単語が出てきた回数」まで必要なら必要ですが。

    キャンセル

  • 2019/05/26 13:43

    swordoneさん。
    ああ! 確かに!
    っていうか、私、勘違いしていました...
    ( マジで「それぞれの単語の出現回数」を調べると今まで思っていました... )

    ちょっと修正しますね。

    キャンセル

  • 2019/05/26 21:42

    ご丁寧にありがとうございます。
    早速試してみます。

    キャンセル

  • 2019/05/28 10:55

    質問者さんへ。

    あと、活用はどうするかっていう問題もありますね。
    例えばmake - made - made (そして making) は一つとみなすのか、
    それぞれ別のものとみなすのか...
    別物とするのなら、私が書いた方法でも普通にできます。
    しかし、ひとつとみなす場合は工夫が必要だと思います。

    例えば「定義ファイル」なるものを用意し、
    makeグループ: make, made, making
    と書いていく。
    そのグループ内にあるなら +1 的なチェック。
    という具合に。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る