猿问

校验位计算改进或优化

我现在在开发阶段使用了一个简单的校验位计算器。校验位取决于帐号和常数乘数2187654321。帐号为字符串格式。我需要将它拆分成整数数组。然后每个整数都需要分别乘以它们的乘数。


假设帐号是 08060002506。那么这个过程就是2x0 + 1x8 + 8x0...


我的问题是,是否有人可以建议是否有更多优化方法来进行计算?因为我将对大约数千个帐户进行计算。


这是我的代码


import java.util.Arrays;


class CheckDigit {

    public static void main(String[] args) {

        String accountNo = "08060002506";

        Integer[] multiplier = new Integer[]{2, 1, 8, 7, 6, 5, 4, 3, 2, 1};

        Object[] accountNoArr = convertAccountToIntArray(accountNo);


        int sum = getSum(multiplier, accountNoArr);


        int remainder = getRemainder(sum);

        int checkDigit = 9 - remainder;

        System.out.println("Check digit is = " + checkDigit);

    }


    private static Object[] convertAccountToIntArray(String accountNo) {

        return Arrays.stream(accountNo.split(""))

                .map(Integer::parseInt).toArray();

    }


    private static int getSum(Integer[] multiplier, Object[] accountNoArr) {

        int sum = 0;

        for (int i = 0, multiplierLength = multiplier.length; i < multiplierLength; i++) {

            Integer numToMultiply = (Integer) accountNoArr[i];

            Integer mul = multiplier[i];

            sum += mul * numToMultiply;

        }

        return sum;

    }


    private static int getRemainder(int sum) {

        return sum % 9;

    }

}


MMMHUHU
浏览 173回答 3
3回答

largeQ

优先使用String.charAt(int)andCharacter.digit(char, int)来String.split("")解析每个子字符串(并使用 anint[]而不是 an Integer[])。就像是,public static void main(String[] args) {&nbsp; &nbsp; String accountNo = "08060002506";&nbsp; &nbsp; int[] multiplier = {2, 1, 8, 7, 6, 5, 4, 3, 2, 1};&nbsp; &nbsp; int sum = getSum(multiplier, accountNo);&nbsp; &nbsp; int remainder = getRemainder(sum);&nbsp; &nbsp; int checkDigit = 9 - remainder;&nbsp; &nbsp; System.out.println("Check digit is = " + checkDigit);}private static int getSum(int[] multiplier, String accountNo) {&nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; for (int i = 0; i < multiplier.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; int numToMultiply = Character.digit(accountNo.charAt(i), 10);&nbsp; &nbsp; &nbsp; &nbsp; sum += multiplier[i] * numToMultiply;&nbsp; &nbsp; }&nbsp; &nbsp; return sum;}

慕哥6287543

优先使用String.charAt(int)andCharacter.digit(char, int)来String.split("")解析每个子字符串(并使用 anint[]而不是 an Integer[])。就像是,public static void main(String[] args) {&nbsp; &nbsp; String accountNo = "08060002506";&nbsp; &nbsp; int[] multiplier = {2, 1, 8, 7, 6, 5, 4, 3, 2, 1};&nbsp; &nbsp; int sum = getSum(multiplier, accountNo);&nbsp; &nbsp; int remainder = getRemainder(sum);&nbsp; &nbsp; int checkDigit = 9 - remainder;&nbsp; &nbsp; System.out.println("Check digit is = " + checkDigit);}private static int getSum(int[] multiplier, String accountNo) {&nbsp; &nbsp; int sum = 0;&nbsp; &nbsp; for (int i = 0; i < multiplier.length; i++) {&nbsp; &nbsp; &nbsp; &nbsp; int numToMultiply = Character.digit(accountNo.charAt(i), 10);&nbsp; &nbsp; &nbsp; &nbsp; sum += multiplier[i] * numToMultiply;&nbsp; &nbsp; }&nbsp; &nbsp; return sum;}

慕标5832272

为了优化计算我建议使用流的并行计算,这是stream api的内置功能。该问题可以视为 2 个向量(帐户和乘数)之间的点积。这是获得更好运行时性能的代码:import java.util.Arrays;import java.util.stream.IntStream;public class CheckDigitCalculationImprovementOrOptimization {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; String accountNo = "08060002506";&nbsp; &nbsp; &nbsp; &nbsp; int[] multiplier = {2, 1, 8, 7, 6, 5, 4, 3, 2, 1};&nbsp; &nbsp; &nbsp; &nbsp; int[] accountNoArr = StringToIntArray(accountNo);&nbsp; &nbsp; &nbsp; &nbsp; int result = dotProduct(multiplier, accountNoArr);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(result);&nbsp; &nbsp; }&nbsp; &nbsp; private static int dotProduct(int[] v1, int[] v2) {&nbsp; &nbsp; &nbsp; &nbsp; return IntStream.range(0, v1.length)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .parallel()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map( id -> v2[id] * v1[id])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .reduce(0, Integer::sum);&nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; static int[] StringToIntArray(String str) {&nbsp; &nbsp; &nbsp; &nbsp; return Arrays.stream(str.split("\\B"))&nbsp; &nbsp; &nbsp; &nbsp; .mapToInt(Integer::valueOf)&nbsp; &nbsp; &nbsp; &nbsp; .toArray();&nbsp; &nbsp; }}另一个优化步骤:您可以提前准备将帐户从字符串转换为 int 数组。我建议运行多个线程来执行此任务。您应该创建一个 int 数组列表,使用帐户大小进行初始化(如果此大小不是常量,则对所有数组使用最大大小)。每个线程将负责用转换后的字符串填充固定数量的帐户。加入来自这些线程的所有任务后,使用相同的技术在向量之间执行点积。每个线程将在固定数量的账户和给定的乘数之间执行点积。选择线程数很棘手,取决于各个任务的运行时间。微调方法可能很有用。
随时随地看视频慕课网APP

相关分类

Java
我要回答