質問

私は Python に慣れているので、これは少し混乱します。ユーザーが特定の数値を入力するまで、入力を行ごとに取り込もうとしています。数値は配列に保存され、統計計算が適用されます。現在、メインクラス、統計クラス、および「読み取り」クラスがあります。

2 つの質問:

  1. 入力ループをうまく動作させることができないようです。そうするためのベストプラクティスは何ですか。

  2. 読み取りメソッドのオブジェクト タイプは何になりますか?double[] ですか、それとも ArrayList ですか?

    1. メソッドタイプを配列リストとして宣言するにはどうすればよいですか?

    2. 配列内に 1000 を超える値が格納されないようにするにはどうすればよいですか?

私がこれまでに持っているものを見せてみましょう:

public static java.util.ArrayList readRange(double end_signal){
    //read in the range and stop at end_signal

    ArrayList input = new ArrayList();
    Scanner kbd = new Scanner( System.in );
    int count = 0;
    do{
        input.add(kbd.nextDouble());
        System.out.println(input); //debugging
        ++count;
    } while(input(--count) != end_signal);
    return input;
}

私の初心者を申し訳ありませんが、助けていただければ幸いです...

役に立ちましたか?

解決

答え:

>1.入力ループをうまく動作させることができないようです。そうするためのベストプラクティスは何ですか。

do{}while の代わりに単純な while ループを使いたいのですが...{}while に条件を置きます...私の例では次のように書かれています。

読み取り番号が終了信号ではなく、カウントが制限値を下回っている間:する。

>2.読み取りメソッドのオブジェクト タイプは何になりますか?double[] ですか、それとも ArrayList ですか?

ArrayList ですが、代わりに List ( java.util.List ) インターフェイスを使用することを強くお勧めします。実装ではなくインターフェイスに合わせてプログラミングすることは、良いオブジェクト指向の実践です。

>2.1メソッドタイプを配列リストとして宣言するにはどうすればよいですか?

以下のコードを参照してください。

>2.2。配列内に 1000 を超える値が格納されないようにするにはどうすればよいですか?

while 条件にこの制限を追加します。

import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;

public class InputTest{

    private int INPUT_LIMIT = 10000;

    public static void main( String [] args ) {
        InputTest test = new InputTest();
        System.out.println("Start typing numbers...");
        List list = test.readRange( 2.0 );
        System.out.println("The input was " +  list );
    }

    /**
     * Read from the standar input until endSignal number is typed.
     * Also limits the amount of entered numbers to 10000;
     * @return a list with the numbers.
     */
    public List readRange( double endSignal ) {
        List<Double> input = new ArrayList<Double>();
        Scanner kdb = new Scanner( System.in );
        int count = 0;
        double number = 0;
        while( ( number = kdb.nextDouble() ) != endSignal && count < INPUT_LIMIT ){
            System.out.println( number );
            input.add( number );
        }
        return input;
    }
}

最後のコメント:

クラスメソッドよりも「インスタンスメソッド」を使用することが推奨されます。この方法では、必要に応じて、署名を変更せずに「readRange」をサブクラスで処理できるため、サンプルでは「static」キーワードを削除して「InputTest」クラスのインスタンスを作成しました。

Java コード スタイルでは、変数名は「end_signal」ではなく「endSignal」のようにキャメルケースで指定する必要があります。

他のヒント

ループ条件で必要なものは次のとおりです。

while ( input.get( input.size()-1 ) != end_signal );

あなたがやっていることは、カウンター変数をデクリメントすることです。

また、宣言する必要があります ArrayList そのようです:

ArrayList<Double> list = new ArrayList<Double>();

これにより、リストがタイプ固有になり、指定された条件が許可されます。それ以外の場合は、追加のキャストが発生します。

スタートは悪くなかったと思いますが、ここに私の提案があります。コードの下で重要な違いとポイントを強調表示します。

パッケージコンソール。

java.utilをインポートします。;java.util.regexをインポートします。;

パブリック クラス ArrayListInput {

public ArrayListInput() {
    // as list
    List<Double> readRange = readRange(1.5);

    System.out.println(readRange);
    // converted to an array
    Double[] asArray = readRange.toArray(new Double[] {});
    System.out.println(Arrays.toString(asArray));
}

public static List<Double> readRange(double endWith) {
    String endSignal = String.valueOf(endWith);
    List<Double> result = new ArrayList<Double>();
    Scanner input = new Scanner(System.in);
    String next;
    while (!(next = input.next().trim()).equals(endSignal)) {
        if (isDouble(next)) {
            Double doubleValue = Double.valueOf(next);
            result.add(doubleValue);
            System.out.println("> Input valid: " + doubleValue);
        } else {
            System.err.println("> Input invalid! Try again");
        }
    }
    // result.add(endWith); // uncomment, if last input should be in the result
    return result;
}

public static boolean isDouble(String in) {
    return Pattern.matches(fpRegex, in);
}

public static void main(String[] args) {
    new ArrayListInput();
}

private static final String Digits = "(\\p{Digit}+)";
private static final String HexDigits = "(\\p{XDigit}+)";
// an exponent is 'e' or 'E' followed by an optionally
// signed decimal integer.
private static final String Exp = "[eE][+-]?" + Digits;
private static final String fpRegex = ("[\\x00-\\x20]*" + // Optional leading "whitespace"
        "[+-]?(" + // Optional sign character
        "NaN|" + // "NaN" string
        "Infinity|" + // "Infinity" string

        // A decimal floating-point string representing a finite positive
        // number without a leading sign has at most five basic pieces:
        // Digits . Digits ExponentPart FloatTypeSuffix
        // 
        // Since this method allows integer-only strings as input
        // in addition to strings of floating-point literals, the
        // two sub-patterns below are simplifications of the grammar
        // productions from the Java Language Specification, 2nd
        // edition, section 3.10.2.

        // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
        "(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|" +

        // . Digits ExponentPart_opt FloatTypeSuffix_opt
        "(\\.(" + Digits + ")(" + Exp + ")?)|" +

        // Hexadecimal strings
        "((" +
        // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
        "(0[xX]" + HexDigits + "(\\.)?)|" +

        // 0[xX] HexDigits_opt . HexDigits BinaryExponent
        // FloatTypeSuffix_opt
        "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +

        ")[pP][+-]?" + Digits + "))" + "[fFdD]?))" + "[\\x00-\\x20]*");// Optional
                                                                        // trailing
                                                                        // "whitespace"

}

  1. Java ではジェネリックを使用するのが良いことです。このようにして、コンパイラと仮想マシンに、使用しようとしている型に関するヒントを与えます。この場合、その二重および結果のリストが二重値を含むと宣言することにより、キャスト/タイプの変換なしで値を使用できます。

    if (!readRange.isEmpty()) {
        double last = readRange.get(readRange.size() - 1);
    }
    
  2. 特定のリスト (LinkedList、SynchronizedLists など) の実装が多数あるため、Java コレクションを操作する場合はインターフェイスを返すことをお勧めします。したがって、後で別の種類の List が必要になった場合でも、メソッド内の具体的な実装を簡単に変更でき、それ以上のコードを変更する必要はありません。

  3. なぜ while 制御ステートメントが機能するのか疑問に思われるかもしれませんが、ご覧のとおり、括弧で囲まれています。 next = input.next().trim(). 。このようにして、条件付きテストの直前に変数の割り当てが行われます。また、空白の問題を避けるために、トリムには再生時間がかかります

  4. 使ってないよ nextDouble() なぜなら、ユーザーが double ではないものを入力するたびに、例外が発生するからです。String を使用すると、ユーザーが入力したものを解析できるだけでなく、終了信号に対してテストすることもできます。

  5. ユーザーが実際に double を入力したことを確認するために、JavaDoc の正規表現を使用しました。 Double.valueOf() 方法。この式が一致する場合は値が変換され、一致しない場合はエラー メッセージが出力されます。

  6. コードには見当たらない理由でカウンターを使用しました。正常に入力された値の数を知りたい場合は、呼び出してください。 readRange.size().

  7. 配列を操作したい場合は、コンストラクターの 2 番目の部分で配列を変換する方法が示されます。

  8. double と Double を混同していないことを願っていますが、Java 1.5 機能の Auto-Boxing のおかげで、これは問題ありません。そしてとして Scanner.next() null を返すことはありません (私の知る限り)、これはまったく問題ではありません。

  9. 配列のサイズを制限したい場合は、次を使用します。

私の解決策と説明がお役に立てば幸いです。 結果.サイズ() 指標とキーワードとして 壊す while 制御ステートメントを終了します。

グリーツ、グリーツ

**

public static java.util.ArrayList readRange(double end_signal) {

    //read in the range and stop at end_signal

    ArrayList input = new ArrayList();

    Scanner kbd = new Scanner(System. in );
    int count = 0;

    do {
        input.add(Double.valueOf(kbd.next()));
        System.out.println(input); //debugging
        ++count;
    } while (input(--count) != end_signal);
    return input;
}

**

public static ArrayList&lt;Double> readRange(double end_signal) {

    ArrayList<Double> input = new ArrayList<Double>();
    Scanner kbd = new Scanner( System.in );
    int count = 0;
    do{
        input.add(kbd.nextDouble());
        ++count;
    } while(input(--count) != end_signal);
return input;
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top