减少这个java程序的运行时间

时间:2015-07-22 17:38:11

标签: java arrays

我已经制作了一个程序来输入数组,并找到3个最大数目的数组的乘积,这样:

数组构成子数组,每次增加一个索引。

也就是说,对于10个元素的数组,找到考虑前3个元素的产品,然后是前4个元素,然后是前5个元素,依此类推。

这是我的代码:

import java.io.*;
import java.util.Arrays;
public class monkmulti {
    public static void main(String args[] ) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());    // no. of elements
        String xs = br.readLine(); //accepting those elements in a string
        xs=xs+" ";
        if(n<1||n>100000)  //constraint
            System.exit(0);
        int i,temp,count=0;
        for(i=0;i<xs.length();i++)
        {
            if(xs.charAt(i)==' ')
            {
                count++;
            }
        }
        if(count!=n)    //checks if no. of elements are equal to n
            System.exit(0);
        int[] x=new int[count];
        int k=0;
        temp=0;
        for(i=0;i<xs.length();i++)
        {
            if(xs.charAt(i)==' ')
            {
                x[k++]=Integer.parseInt(xs.substring(temp, i));
                temp=i+1;
            }
        }
        count=0;
        int len=x.length,j;
        int[] x1=new int[len];
        System.arraycopy(x, 0, x1, 0, len);
        for(i=0;i<len;i++)
        {
            if(x[i]<1||x[i]>100000)      //constraint for each element
                System.exit(0);
        }
        int m1=0,m2=0,m3=0;
        int max1=x[0],max2=x[0],max3=x[0];
        /*code to be improved below from here*/
        for(i=2;i<len;i++)            
        {
            for(j=0;j<=i;j++)
            {
                for(k=0;k<i;k++)
                {
                    if(x1[k]>x1[k+1])
                    {
                        temp=x1[k];
                        x1[k]=x1[k+1];
                        x1[k+1]=temp;
                    }
                }
            }
            System.out.println(x1[i]*x1[i-1]*x1[i-2]);
        }
    }
}

输入:

n =用户输入号码。数组中的元素 xs = string接受以空格分隔的n个元素

输出:

产品考虑前3个要素
产品考虑前4个要素
等...... ..

示例:

输入:
5
6 2 9 3 8

输出:
-1
-1
108个
162个
432

解释 有5个整数6,2,9,3,8
对于第三个指数,前三个数字是6,2和9,其乘积为108 对于第四个指数,前三个数字是6,9和3,其乘积为162 对于第五个指数,前三个数字是6,9和8,其乘积为432.

2 个答案:

答案 0 :(得分:0)

如果我明白,你需要这样的东西:

订单是O(项目* log(子组)) - &gt; O(项目* log(3)) - &gt; O(项目)

public static void product(int[] items, int subGroup) {
    if (subGroup > 0 && items.length >= subGroup) {
        // this save the largest numbers:
        PriorityQueue<Integer> maxElements = new PriorityQueue<>(subGroup);
        int product = 1;
        for (int i = 0; i < items.length; i++) {
            // the queue of largest numbers is full:
            if (maxElements.size() == subGroup) {
                // the minimum of previous largest number is lower than the new number
                if (maxElements.peek() < items[i]) {
                    // swapping
                    product /= maxElements.poll();
                    product *= items[i];
                    maxElements.add(items[i]);
                }
                System.out.println(product);
            } else {
                product *= items[i];
                maxElements.add(items[i]);
                if (maxElements.size() < subGroup) {
                    //the queue of largest numbers isn't full
                    System.out.println("-1");
                } else {
                    // the queue of largest numbers is full now
                    System.out.println(product);
                }
            }
        }
    }
}

public static void main(String[] args) {
    int[] input = {6, 2, 9, 3, 8};
    product(input, 3);
}

输出:

-1
-1
108
162
432

编辑: 快一点:

private static void heap(int[] maxElements) {
    int candidate = 1;
    if (maxElements[1] > maxElements[2]) {
        candidate = 2;
    }
    if (maxElements[0] > maxElements[candidate]) {
        int temp = maxElements[0];
        maxElements[0] = maxElements[candidate];
        maxElements[candidate] = temp;
    }
}

private static int addElement(int k, int[] maxElements, int item) {
    if (k < 3) {
        maxElements[k++] = item;
        if (k < 3) {
            System.out.println("-1");
        } else {
            heap(maxElements);
            System.out.println(maxElements[0] * maxElements[1] * maxElements[2]);
        }
    } else {
        if (maxElements[0] < item) {
            maxElements[0] = item;
            heap(maxElements);
        }
        System.out.println(maxElements[0] * maxElements[1] * maxElements[2]);
    }
    return k;
}

public static void main(String args[]) throws IOException {

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int n = Integer.parseInt(br.readLine());    // no. of elements
    String line = br.readLine(); //accepting those elements in a string
    int[] maxElements = new int[3];
    int k = 0;
    int item = 0;
    char c;
    for (int i = 0; i < line.length(); i++) {
        c = line.charAt(i);
        if (c == ' ') {
            k = addElement(k, maxElements, item);
            item = 0;
        } else {
            item = item * 10 + (c - '0');
        }
    }
    addElement(k, maxElements, item);
}

答案 1 :(得分:0)

以下解决方案删除了​​所有“元素数量”检查代码,因为它不是解决方案所必需的。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.TreeSet;

public class MonkMulti
{
    public static void main(String args[]) throws IOException
    {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Input a list of numbers separated by space");
        String xs = br.readLine(); // accepting those elements in a string

        // split input values by space
        String[] numbers = xs.split("\\ ");
        // create int array
        int[] x = new int[numbers.length];
        // convert all strings to int
        for (int i = 0; i < numbers.length; i++)
        {
            x[i] = Integer.valueOf(numbers[i]);
        }

        for (int arraySize = 3; arraySize <= x.length; arraySize++)
        {
            calculateMonkMulti(x, arraySize);
        }
    }

    /**
     * Calculate the product for different sizes
     * 
     * @param values
     * @param arraySize
     */
    private static void calculateMonkMulti(int[] values, int arraySize)
    {
        // new target sub array
        int[] sorted = new int[arraySize];
        // copy values of the sub array
        System.arraycopy(values, 0, sorted, 0, arraySize);
        // sort the sub array
        Arrays.sort(sorted);

        // calculate start index of top 3 elements
        int startIndex = sorted.length - 3;
        // get top three elements
        System.err.println(startIndex + "/" + arraySize + "/" + sorted.length);
        int int1 = sorted[startIndex];
        int int2 = sorted[++startIndex];
        int int3 = sorted[++startIndex];
        // calculate
        long result = int1 * int2 * int3;
        // output (or return)
        System.out.println(int1 + " * " + int2 + " * " + int3 + " = " + result);
    }
}

使用JDK类和函数的解决方案。

我得到以下运行时值: 对于链接中具有100.000值的总数组:运行时:所有子阵列100000个元素的47毫秒

对于x元素的所有子数组的运行时,启动以下内容(在完成后更新):

  • 总运行时间:总共100000个元素的1000个元素后66毫秒
  • 总运行时间:总计100000个元素的2000个元素后的195毫秒
  • 总运行时间:总计100000个元素的3000个元素后317毫秒
  • ...
  • 总运行时间:98000个元素(总计100000个元素)之后的295667毫秒
  • 总运行时间:总计100000个元素的99000个元素后的301906毫秒
  • 总运行时间:总计100000个元素的100000个元素后的308266毫秒

运行时:所有子阵列100000个元素的运行时间为308266 ms

我不知道网站的衡量标准。编译时间?

版本2: 新的优化版本可以解决总问题Runtime: 26900 ms for all sub arrays 100000 elements

中的问题

现在版本3:

  • ...
  • 总运行时间:总共100000个元素的98000个元素后54毫秒
  • 总运行时间:总共100000个元素的99000个元素后54毫秒
  • 总运行时间:总计100000个元素的100000个元素后54毫秒

运行时:所有子阵列100000个元素的运行时间为55毫秒

我最快的解决方案:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class MonkMulti
{
    static int[] sortedFast;
    public static void main(String args[]) throws IOException
    {
        BufferedReader br = new BufferedReader(new FileReader(new File(
                "u:/temp/numbers.txt")));
        String xs = br.readLine(); // accepting those elements in a string

        // split input values by space
        long startTime = System.currentTimeMillis();
        String[] numbers = xs.split("\\ ");
        // create int array
        int[] sourceValues = new int[numbers.length];
        // convert all strings to int
        for (int i = 0; i < numbers.length; i++)
        {
            sourceValues[i] = Integer.valueOf(numbers[i]);
        }

        // create memory array for top 3 values
        sortedFast = new int[3];
        // copy first to elements from source to memory by one position up
        System.arraycopy(sourceValues, 0, sortedFast, 1, 2);
        // and set the lowest element to -1
        sortedFast[0] = -1;

        long result = 0;
        // start with 3 elements in sub array
        int startIndex = 3;
        // loop all sub arrays from 3 .. sourceValues.leength
        for (int arraySize = startIndex; arraySize <= sourceValues.length; arraySize++)
        {
            // calculate the value
            result += calculateMonkMegaFast(sourceValues, arraySize);
        }
        long endTime = System.currentTimeMillis();

        System.out
                .println("Runtime: " + (endTime - startTime)
                        + " ms for all sub arrays " + sourceValues.length
                        + " elements (some value to ignore to prevent optimization: " + result + ")");
    }


    private final static long calculateMonkMegaFast(int[] values, int arraySize)
    {
        // check if the next element if greater as the lowest element in memory
        // sort the sub array
        if (values[arraySize - 1] > sortedFast[0])
        {
            // yes, replace lowest element with the bigger element from source
            sortedFast[0] = values[arraySize - 1];
            // sort the 3 element memory array
            Arrays.sort(sortedFast);
        }

        // get new top 3 elements
        int int1 = sortedFast[0];
        int int2 = sortedFast[1];
        int int3 = sortedFast[2];

        // calculate result
        long result = int1 * int2 * int3;
        // output (or return)
        // System.out.println(int1 + " * " + int2 + " * " + int3 + " = " +
        // result);

        return result;
    }
}

结果计算应使用double来防止值溢出。复杂性几乎是O(n)。