0

私は次のコードを持っています。私は言語を学び始めたばかりであり、そのようなものはかなり簡単な演習を探していることを覚えておいてください。コーディングのエチケットと批評家は大歓迎です。

import java.util.*;
import java.io.*;

public class Tron
{
    public static void main(String[] args) throws Exception
    {
        int x,z,y = 0;
        File Tron= new File("C:\\Java\\wordtest.txt");
        Scanner word = new Scanner(Tron);
        HashMap<String, Integer> Collection = new HashMap<String, Integer>();
        //noticed that hasNextLine and hasNext both work.....why one over the other?
        while (word.hasNext())
        {
            String s = word.next();
            Collection.get(s);
            if (Collection.containsKey(s))
            {
                Integer n = Collection.get(s);
                n = n+1;
                Collection.put(s,n);
                //why does n++ and n+1 give you different results
            }else
            {
                Collection.put(s,1);
            }       
        }
        System.out.println(Collection);


    }   
}

を使用せずに、useDelimiter()私が持っているファイルに基づいて希望の出力を取得します。

Far = 2, ran = 4, Frog = 2, Far = 7, fast = 1, etc...

useDelimiter次のようにメソッドを挿入します

Scanner word = new Scanner(Bible);
word.useDelimiter("\\p{Punct} \\p{Space}");

以下に示すテキストファイルに表示される次の出力を提供します。

カエルカエル

走った

走った走った走った

速い、速い速い

遠い、遠い、遠い遠い遠い遠い

useDelimiter句読点の新しい行などを説明することになっているのに、なぜこのような出力の違いがあるのでしょうか。おそらくかなり単純ですが、プログラムでの最初のショットです。アドバイスをよろしくお願いします。

4

2 に答える 2

2

実際には、句読点文字とそれに続くスペース、その後に別の空白文字word.useDelimiter("\\p{Punct} \\p{Space}")で構成される区切り文字を探すようにスキャナに指示しています。おそらく、代わりにこれらのうちの 1 つ (および 1 つだけ) を使用したいと考えていました。これは、次のような方法で実現できます。

word.useDelimiter("\\p{Punct}|\\p{Space}");

またはこれらの少なくとも 1 つ、次のようになります

word.useDelimiter("[\\p{Punct}\\p{Space}]+");

アップデート

@Andrzejはコードコメントの質問にうまく答えましたが(私は忘れていました)、彼は私が展開したい/ここにまっすぐ入れたい小さな詳細を1つ見逃しました。

n++ と n+1 で異なる結果が得られるのはなぜですか

これは明らかに次の行に関連しています

            n = n+1;

私の推測では、あなたが試した代替案は

            n = n++;

これは確かに紛らわしい結果をもたらします(つまり、最終結果はインクリメントさnません)。

その理由は、n++(正規名による後置インクリメント演算子n) の値をインクリメントしますが、式の結果は!の元の値になるためです。nしたがって、それを使用する正しい方法は単純です

            n++;

その結果は と同等n = n+1です。

これは、これらの演算子がどのように機能するかをよりよく理解するのに役立つことを願っているコード例のスレッドです。

于 2012-05-09T11:46:14.497 に答える
0

ピーターは正規表現について正しいです。文字のクラスではなく、非常に特定のシーケンスに一致しています。

ソースコメントからの質問に答えることができます:

hasNextLine と hasNext の両方が機能することに気付きました...なぜ一方が他方よりも優れているのでしょうか?

Scannerクラスは実装するように宣言されていIterator<String>ます (文字列を提供する任意のものを必要とするあらゆる状況で使用できるようにするため)。そのため、Iteratorインターフェースはメソッドを宣言するhasNextため、スキャナーはまったく同じ署名でこれを実装する必要があります。一方、hasNextLineは Scanner が自発的に実装するメソッドです。

インターフェースを実装するクラスが、「一般的な名前の」インターフェース メソッドとよりドメイン固有のメソッドの両方を宣言することは、まったく珍しいことではありません。どちらも同じことを行います。(たとえば、ゲームをプレイするクライアントをIterator<GameCommand>- として実装したい場合があります。その場合を宣言する必要がありますが、まったく同じことをhasNext行うメソッドを呼び出したい場合があります。)isGameUnfinished

とはいえ、2 つの方法は同じではありません。 hasNextスキャナーが返す別のトークンがある場合は trueを返しhasNextLine、スキャナーが返す別の入力行がある場合は trueを返します。

改行で終わらないファイルに対してスキャナーを実行し、1 つを除くすべてのトークンを消費すると、falsehasNextが返されるtrue一方で返されると思います。hasNextLine(ファイルが改行で終わる場合、両方の方法は同じように動作します。すべての行が消費されたわけではない場合にのみトークンが増えるため、技術的には同じではありません。)

n++ と n+1 で異なる結果が得られるのはなぜですか

これは非常に簡単です。

n + 1の現在の値より 1 大きい値を返すだけですn。一方、 n++ n を 1 つ大きい値に設定し、その値を返します。

したがって、n現在 4 の場合、両方のオプションが5 を返します。違いは、 を呼び出した場合は の値nが 4 のままですが、 を呼び出しn + 1た場合は 5 になることですn++

一般に、ボイラープレートとして使用される状況 (インデックスのループ++など) を除いて、演算子の使用を避けるのが賢明です。for意図をより明確かつ明確に表現するために 2 ~ 3 文字、さらには 1 行余分に追加することは、ほとんどの場合行う価値のある非常に小さな代償です。

于 2012-05-09T11:58:44.037 に答える