10

ファイルから入力を読み取り、各単語内の文字をソートする Java プログラムを作成します。それが完了したら、結果のすべての単語を昇順に並べ替え、最後にファイル内の数値の合計を続けます。

  • データの処理中に特殊文字とストップ ワードを削除する
  • コードの実行にかかった時間を測定する

ファイルの内容は次のとおりです。Sachin Tendulkar は 18111 回の ODI 実行と 14692 回のテスト実行を記録しました。

出力:achins adeklnrtu adn cdeors dio estt nrsu nrsu 32803

所要時間: 3 ミリ秒

私のコードの実行には 15 ミリ秒かかります.....

この問題を解決する手っ取り早い方法を教えてください........

コード:

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.*;

public class Sorting {

    public static void main(String[] ags)throws Exception
    {
        long st=System.currentTimeMillis();
        int v=0;
        List ls=new ArrayList();
        //To read data from file
        BufferedReader in=new BufferedReader(
                 new FileReader("D:\\Bhive\\File.txt"));
        String read=in.readLine().toLowerCase();
        //Spliting the string based on spaces
        String[] sp=read.replaceAll("\\.","").split(" ");
        for(int i=0;i<sp.length;i++)
        {
            //Check for the array if it matches number
            if(sp[i].matches("(\\d+)"))
                //Adding the numbers
                v+=Integer.parseInt(sp[i]);
            else
            {
                //sorting the characters
                char[] c=sp[i].toCharArray();
                Arrays.sort(c);
                String r=new String(c);
                //Adding the resulting word into list
                ls.add(r);
            }
        }
        //Sorting the resulting words in ascending order
        Collections.sort(ls);
        //Appending the number in the end of the list
        ls.add(v);
        //Displaying the string using Iteartor
        Iterator it=ls.iterator();
        while(it.hasNext())
            System.out.print(it.next()+" ");
        long time=System.currentTimeMillis()-st;
        System.out.println("\n Time Taken:"+time);
    }
}
4

5 に答える 5

5

indexOf()の代わりに文字列から単語を抽出するために使用しますsplit(" ")。パフォーマンスが向上します。

このスレッドを参照してください: Java での StringTokenizer クラスと分割メソッドのパフォーマンス

また、出力のサイズを大きくして、Sachin Tendulkar が 18111 ODI 実行と 14692 テスト実行を記録した行をコピーして貼り付けます。テキスト ファイルで 50,000 回実行し、パフォーマンスを測定します。そうすれば、さまざまな最適化を試したときに、かなりの時間差を確認できます。

編集

このコードをテストしました (使用済み.indexOf())

        long st = System.currentTimeMillis();
        int v = 0;
        List ls = new ArrayList();
        // To read data from file
        BufferedReader in = new BufferedReader(new FileReader("D:\\File.txt"));
        String read = in.readLine().toLowerCase();
        read.replaceAll("\\.", "");
        int pos = 0, end;
        while ((end = read.indexOf(' ', pos)) >= 0) {
            String curString = read.substring(pos,end);
            pos = end + 1;
        // Check for the array if it matches number
            try {
                // Adding the numbers
                v += Integer.parseInt(curString);
            }
            catch (NumberFormatException e) {
                // sorting the characters
                char[] c = curString.toCharArray();
                Arrays.sort(c);
                String r = new String(c);
                // Adding the resulting word into TreeSet
                ls.add(r);
            }
        }
        //sorting the list
        Collections.sort(ls);
        //adding the number
        list.add(v);
        // Displaying the string using Iteartor 
        Iterator<String> it = ls.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }
        long time = System.currentTimeMillis() - st;
        System.out.println("\n Time Taken: " + time + " ms");

ファイル内の 1 行を使用したパフォーマンス
あなたのコード: 3 ミリ秒
私のコード: 2 ミリ秒

ファイルで 50K 行を使用した場合のパフォーマンス
あなたのコード: 45 ミリ秒
私のコード: 32 ミリ秒

ご覧のとおり、入力サイズが大きくなると差が顕著になります。お使いのマシンでテストして、結果を共有してください。

于 2012-06-21T06:40:29.623 に答える
3

私が見る唯一のもの:次の行は不必要に高価です:

   System.out.print(it.next()+" ");

これは、すべてのフラッシングが行われているため、印刷が非効率的であるためです。代わりに、文字列ビルダーを使用して文字列全体を作成してから、printの呼び出しを1回に減らします。

于 2012-06-21T05:23:07.600 に答える
1

List の代わりに PriorityQueue を使用して同じコードを実行しました。また、nes1983 が提案したように、すべての単語を個別に出力する代わりに、最初に出力文字列を作成すると、実行時間を短縮できます。

これらの変更後の実行時間は確実に短縮されました。

于 2012-06-21T06:44:11.513 に答える
1

私はリストを削除し、配列のみを使用して読み取りました。私のマシンでは、配列のみを使用してコードを 6 ミリ秒に短縮し、4 ~ 5 ミリ秒かかりました。あなたのマシンでこのコードを実行し、私に時間を知らせてください.

import java.io.BufferedReader;

import java.io.FileReader;

import java.util.*;

public class Sorting {
public static void main(String[] ags)throws Exception
{
    long st=System.currentTimeMillis();
    int v=0;
    //To read data from file
    BufferedReader in=new BufferedReader(new FileReader("File.txt"));
    String read=in.readLine().toLowerCase();
    //Spliting the string based on spaces
    String[] sp=read.replaceAll("\\.","").split(" ");
    int j=0;
    for(int i=0;i<sp.length;i++)
    {
        //Check for the array if it matches number
        if(sp[i].matches("(\\d+)"))
            //Adding the numbers
            v+=Integer.parseInt(sp[i]);
        else
        {
            //sorting the characters
            char[] c=sp[i].toCharArray();
            Arrays.sort(c);
            read=new String(c);
            sp[j]= read;
            j++;
        }
    }
    //Sorting the resulting words in ascending order
    Arrays.sort(sp);
    //Appending the number in the end of the list
    //Displaying the string using Iteartor
    for(int i=0;i<j; i++)
        System.out.print(sp[i]+" ");
        System.out.print(v);
    st=System.currentTimeMillis()-st;
    System.out.println("\n Time Taken:"+st);
}

}
于 2012-06-21T05:34:21.250 に答える
0

@Teja ロジックも含めて、このようなコードをさらに変更したところ、2 ミリ秒から 1 ミリ秒になりました。

long st=System.currentTimeMillis();
     BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream("D:\\Bhive\\File.txt")));
     String read= in.readLine().toLowerCase();
     String[] sp=read.replaceAll("\\.","").split(" ");
     int v=0;
     int len = sp.length;
     int j=0;
     for(int i=0;i<len;i++)
     {
            if(isNum(sp[i]))
             v+=Integer.parseInt(sp[i]);
             else
            {
              char[] c=sp[i].toCharArray();
              Arrays.sort(c);
              String r=new String(c);
              sp[j] = r;
              j++;
             }
      }
        Arrays.sort(sp, 0, len);
        long time=System.currentTimeMillis()-st;
        System.out.println("\n Time Taken:"+time);
        for(int i=0;i<j; i++)
        System.out.print(sp[i]+" ");
        System.out.print(v); 

文字列に正規表現ではなく数値が含まれているかどうかをチェックするために実行する小さなユーティリティを作成しました。

private static boolean isNum(String cs){
     char [] s = cs.toCharArray();
     for(char c : s)
     {
      if(Character.isDigit(c))
       {
         return true;
       }
     }
     return false;
 }

これは操作をブロックしているため、System.out 操作を呼び出す前に時間を計算します。

于 2012-06-21T07:06:32.487 に答える