0

私は自分が作ろうとしているゲームを試しています。for ループを除いて同一のメソッドが 2 つあることがわかりました。これは単に前者の逆です。

同じコードを前後に使えるように作ってみました。私は終わった:

for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))

A) B) このコンセプトをみんなと共有したかった。

B) そのようなループの効率に興味があります。アクセス時にターゲット数と増分係数を計算していることは知っていますが、それをテストする方法がわかりません。

C) 作業中に、一時変数を使用せずに 2 つの変数を交換する 1 行を見つけました。読むのに少し時間がかかりますが、これは temp を使用するよりも (コード的に) 優れていますか? (下のメインの 3 行目)

機能をテストしましたが、期待どおりに動作します。2 番目の数値が最初の数値より大きい場合は、カウントアップします。そうでない場合は、カウントダウンします。私のテストコードは次のとおりです。

// A generic loop that can go up or down
import java.io.*;

public class reversable
{
  public static int start = 1;
  public static int finish = 10;

   public static void main(String[] args)
  {
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
     finish = (start + finish) - (start = finish);  
System.out.println("Finish = " + finish);
System.out.println("Start = " + start);
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
     finish = 10;
     for (int i = start; i != (finish + 1 * ((start < finish) ? 1 : -1)); i += 1 * ((start < finish) ? 1 : -1))
     {
        System.out.println("i = " + i);
     }
  }
}

コメントに基づいて、これは受け入れられるでしょうか:

public static void reversable (int i, int j)
{
  if (i > j) int inc = -1;  // Count down
  else       int inc = 1;  // Count up
  j += inc;
  for (i; i != j; i += inc)
  {
    dostuff();
    morestuff();
    mostuff();
  }
}
4

4 に答える 4

15

1 行で多くのことを実行したり、手の込んだトリックを行ったりするコードではなく、読みやすいコードを書くように努める必要があります。

私があなたと一緒にプロジェクトに取り組んでいたとしたら、最初に for ループを読んだ後であなたの首を絞めたくなるでしょう。課題内の課題についても同様です。

于 2010-11-03T02:28:51.143 に答える
10

このコードを本番環境で見たら、すぐに読みやすいものにリファクタリングするでしょう。

コードの重複を減らしたい理由を考えてください。コードをより保守しやすくするためです。やりきった感はありますか?

作業中に、一時変数を使用せずに 2 つの変数を交換する 1 行を見つけました。読むのに少し時間がかかりますが、これは temp を使用するよりも (コード的に) 優れていますか?

これは数値型でのみ機能するため、それほど便利ではありません。トリックを知らない人がコードを読みにくくしたため、コードのメンテナンスが遅くなりました。1つの一時変数を節約する価値があるとは思いません。

于 2010-11-03T02:36:21.007 に答える
6

ええと、レンガになろうとしているわけではありませんが、あなたは次のように書こうとしたと思います:

public static void doAction(int i) {
    System.out.println("i = " + i);
}

public static void loopValues(int i, int j) {
    if (i > j) while (i >= j) doAction(i--);
    else       while (i <= j) doAction(i++);;
}

public static void main(String[] args) {
    int start = 1, finish = 10;
    loopValues(start, finish);
    loopValues(finish, start);
}

2 つのループがある理由は、効率とケースの読みやすさです。比較はコストのかかる操作であり、通常、通常のコースを変更するためだけにループに比較を追加することは望ましくありません。

于 2010-11-03T02:55:18.920 に答える
0

確かに、コードに従うのは難しいです...しかし、批評家にとっては十分です。誰かがループだけが異なる再利用可能なメソッドを求めるとき、頭に浮かぶのはIterator. イテレータ パターンは、まさにこの再利用可能なケースに必要なものです。イテレータをIterableforインターフェースでラップすると、ブロック内で簡単に使用できます。例 :

public class IntegerRange implements Iterable<Integer> {
   private boolean reverse;
   private int start;
   private int end;

   public IntegerRange(int start, int end) {
      this.reverse = (start > end);
      this.start = start;
      this.end = end;
   }

   @Override
   public Iterator<Integer> iterator() {
      return new IntegerIterator();
   }


   private class IntegerIterator implements Iterator<Integer> {

      private int current;

      private IntegerIterator() {
         current = start;
      }

      @Override
      public boolean hasNext() {
         if (reverse) {
            return (end <= current);
         } else {
            return (current <= end);
         }
      }

      @Override
      public Integer next() {
         if (!hasNext()) {
            throw new NoSuchElementException();
         }
         if (reverse) {
            return current--;
         } else {
            return current++;
         }
      }

      @Override
      public void remove() {
         throw new UnsupportedOperationException("Cannot remove from this iterator");
      }
   }

}

次に、イテレータを使用して再利用します...

static public void main(String...args) {
   doStuff(new IntegerRange(1, 10));
   doStuff(new IntegerRange(10, 1));
}

static private void doStuff(IntegerRange range) {
   for (int i : range) {
      System.out.println("i = " + i);
   }
} 

コードがより読みやすくなりました。

于 2010-11-03T14:56:18.417 に答える