当前位置: 首页 > 面试题库 >

十进制补码算法实现中的ArrayIndexOutOfBoundsException

林意蕴
2023-03-14
问题内容

我的代码尝试实现一种算法来

  • 从用户输入两个整数和一个操作数,+或者-从控制台获取,
  • 将这些数字逐位存储在int[50],用十进制补码表示负数,
  • 实现(十进制)逐位加/减运算,
  • 以十进制格式打印结果,且不带前导零。

但是,在我当前的实现中,存在两个问题

  • 当加99 + 9999时,打印结果为01098,而不是预期的010098。
  • 当减去ArrayIndexOutOfBoundsException: 5099-9999时,得到的不是预期结果-09900。
    import java.util.*;

    public class Program9 {
        public static String getOperand() {
            Scanner scan = new Scanner(System.in);
            String stringOfInteger;

            System.out.print("Please enter an integer up to 50 numbers: ");
            stringOfInteger = scan.nextLine();
            return stringOfInteger;
        }

        public static int[] convert(String operand) {
            int[] integer = new int[50];
            char ch;

            int position = operand.length() - 1;
            for (int i = integer.length - 1; i >= 0; i--) {
                if (position >= 0)
                    ch = operand.charAt(position--);
                else
                    ch = 0;
                if (ch >= '0' && ch <= '9') {
                    integer[i] = ch - '0';
                } else {
                    integer[i] = 0;
                }
            }
            return integer;
        }

        public static int[] add(int[] operand1, int[] operand2) {
            int[] result = new int[operand1.length];
            int carry = 0;
            for (int i = operand1.length - 1; i >= 0; i--) {
                result[i] = operand1[i] + operand2[i] + carry;
                if (result[i] / 10 == 1) {
                    result[i] = result[i] % 10;
                    carry = 1;
                } else
                    carry = 0;
            }
            return result;
        }

        public static int[] complement(int[] operand) {
            int[] result = new int[operand.length];
            for (int i = operand.length - 1; i >= 0; i--)
                result[i] = 9 - operand[i];
            return result;
        }

        public static int[] add1(int[] operand) {
            int[] result = new int[50];
            result[49] = 1;
            for (int i = result.length - 2; i >= 0; i--)
                result[i] = 0;
            return result;
        }

        public static int[] negate(int[] operand) {
            return add(add1(operand), complement(operand));
        }

        public static void print(int[] result, String operation) {
            if (operation.charAt(0) == '+')
                System.out.print("The subtotal of the two integer = ");
            else if (operation.charAt(0) == '-')
                System.out.print("The substraction of the two integers = ");
            if (result[0] == 9) {
                result = negate(result);
                System.out.print("-");
                for (int i = 0; i < result.length; i++) {
                    if (result[i] == 0 && result[i + 1] == 0)
                        continue;
                    else
                        System.out.print(result[i]);
                }
            } else
                for (int i = 0; i < result.length; i++) {
                    if (result[i] == 0 && result[i + 1] == 0)
                        continue;
                    else
                        System.out.print(result[i]);
                }
            System.out.println();
        }

        public static void main(String[] args) {
            Scanner scan = new Scanner(System.in);
            int[] result = new int[50];
            String string1 = getOperand();
            String string2 = getOperand();
            int[] integer1 = convert(string1);
            int[] integer2 = convert(string2);
            String operation;

            System.out.print("Please enter which operation will be used (+ or -): ");
            operation = scan.nextLine();
            if (operation.charAt(0) == '+')
                add(integer1, integer2);
            else if (operation.charAt(0) == '-')
                integer2 = negate(integer2);

            result = add(integer1, integer2);

            System.out.println(Arrays.toString(integer1));
            System.out.println(Arrays.toString(integer2));
            System.out.println(Arrays.toString(add(integer1, integer2)));
            print(result, operation);
        }
    }

问题答案:

好吧,经过如此多的讨论和如此多的代码问题,我已经完全修改了原始代码,因为您说过您想了解更多。除其他改进外,我还进行了以下更改:

  • Meaninfgul类别名称
  • 有意义的方法和参数名称
  • 出于简洁的代码原因(文档,一处轻松更改,有意义的名称),运行时优化),将重复且经常使用的常数(例如,50和数字的数组表示形式1)(需要否定)转换为静态最终成员。
  • 扩展代码以允许负整数作为操作数
  • 添加了用于用户输入的验证模式。例如,现在检查最大数字长度,以避免数组溢出。
  • 通过使数组大于用户输入允许的最大位数来避免计算过程中的数值溢出(请参阅源代码注释)
  • 添加带有操作数和操作员输入错误处理的重试循环,将控制台处理提取到一种参数化方法中。
  • 通过删除不必要的检查来简化代码,因为在将用户输入转换为之前,已经对其进行了验证int[]
  • 使调试输出为可选
    package de.scrum_master.stackoverflow;

    import java.util.Arrays;
    import java.util.Scanner;
    import java.util.regex.Pattern;

    public class TensComplementArithmetic {
        // Print debug messages?
        private static final boolean DEBUG = true;

        // Maximum length for numbers entered by a user
        // (number of digits excluding the optional +/- sign)
        private static final int MAX_NUMBER_LENGTH = 50;

        // Array must have one additional element for the sign and
        // one more to avoid overflows when adding big negative numbers
        private static final int ARRAY_LENGTH = MAX_NUMBER_LENGTH + 2;

        // Scanner for console input handling
        private static final Scanner INPUT_SCANNER = new Scanner(System.in);

        // Regex pattern for positive/negative integer number format verification incl. length check
        private static final Pattern INTEGER_PATTERN = Pattern.compile("[+-]?[0-9]{1," + MAX_NUMBER_LENGTH + "}");

        // Regex pattern for operator verification (currently only "+"/"-" allowed)
        private static final Pattern OPERATOR_PATTERN = Pattern.compile("[+-]");

        // The number 1 is always needed for converting a 9's into a 10's complement
        // during negation, so we define it as a reusable constant
        private static final int[] NUMBER_ONE;

        static {
            // Initialise constant carrying array representation for number 1
            NUMBER_ONE = new int[ARRAY_LENGTH];
            NUMBER_ONE[ARRAY_LENGTH - 1] = 1;
        }

        public static String readConsoleInput(String prompt, Pattern validationPattern, String errorMessage) {
            String input = null;
            while (input == null) {
                System.out.print(prompt + ": ");
                if (INPUT_SCANNER.hasNext(validationPattern))
                    input = INPUT_SCANNER.next(validationPattern);
                else {
                    INPUT_SCANNER.nextLine();
                    System.out.println(errorMessage);
                }
            }
            return input;
        }

        public static String getOperand(String operandName) {
            return readConsoleInput(
                "Operand " + operandName,
                INTEGER_PATTERN,
                "Illegal number format, please enter a positive/negative integer of max. " + MAX_NUMBER_LENGTH + " digits."
            );
        }

        private static String getOperator() {
            return readConsoleInput(
                "Arithmetical operator (+ or -)",
                OPERATOR_PATTERN,
                "Unknown operator, try again."
            );
        }

        public static int[] parseInteger(String number) {
            char sign = number.charAt(0);
            boolean isNegative = sign == '-' ? true : false;
            if (isNegative || sign == '+')
                number = number.substring(1);

            int[] result = new int[ARRAY_LENGTH];
            int parsePosition = number.length() - 1;
            for (int i = result.length - 1; i >= 0; i--) {
                if (parsePosition < 0)
                    break;
                result[i] = number.charAt(parsePosition--) - '0';
            }
            return isNegative ? negate(result) : result;
        }

        public static int[] add(int[] operand1, int[] operand2) {
            int[] result = new int[ARRAY_LENGTH];
            int carry = 0;

            for (int i = ARRAY_LENGTH - 1; i >= 0; i--) {
                result[i] = operand1[i] + operand2[i] + carry;
                if (result[i] >= 10) {
                    result[i] = result[i] % 10;
                    carry = 1;
                } else
                    carry = 0;
            }
            return result;
        }

        public static int[] complement(int[] operand) {
            int[] result = new int[ARRAY_LENGTH];

            for (int i = operand.length - 1; i >= 0; i--)
                result[i] = 9 - operand[i];
            return result;
        }

        public static int[] negate(int[] operand) {
            return add(complement(operand), NUMBER_ONE);
        }

        public static void print(int[] result, String operation) {
            System.out.print(operation.charAt(0) == '-' ? "Difference = " : "Sum = ");
            if (result[0] == 9) {
                result = negate(result);
                System.out.print("-");
            }
            boolean leadingZero = true;
            for (int i = 0; i < result.length; i++) {
                if (leadingZero) {
                    if (result[i] == 0)
                        continue;
                    leadingZero = false;
                }
                System.out.print(result[i]);
            }
            System.out.println(leadingZero ? "0" : "");
        }

        public static void main(String[] args) {
            int[] operand1 = parseInteger(getOperand("#1"));
            int[] operand2 = parseInteger(getOperand("#2"));
            String operator = getOperator();

            if (operator.equals("-"))
                operand2 = negate(operand2);

            int[] result = new int[ARRAY_LENGTH];
            result = add(operand1, operand2);
            if (DEBUG) {
                System.out.println("Operand #1 = " + Arrays.toString(operand1));
                System.out.println("Operand #2 = " + Arrays.toString(operand2));
                System.out.println("Result     = " + Arrays.toString(result));
            }
            print(result, operator);
        }
    }


 类似资料:
  • 问题内容: 我有一个代表2的补码的十六进制字符串。是否有一种简单的方法(库/函数)将十六进制转换为十进制而不直接使用其位? EG这是给定左侧十六进制的预期输出: 谢谢! 问题答案: 这似乎在欺骗Java转换数字而不强制给出正结果: 当然,这种情况仅适用于8、16、32和64位2的补码:

  • 将二进制补码转换为十进制最简单的方法是什么?例如,如果我通常将“1001”之类的字符串转换为十进制,则得到9。但我实际上想得到一个简单的-7。你们有什么建议?,

  • 问题内容: Python中的整数以二进制补码存储,对吗? 虽然: 和: 真是la脚。如何获取python以实数二进制位给我数字,并且没有0b开头?所以: 问题答案: 不确定如何使用标准库获取所需的内容。那里有一些脚本和软件包可以为您完成转换。 我只是想指出“为什么”以及为什么它不la脚。 bin()不返回二进制位。它将数字转换为二进制字符串。根据python语言定义,前导‘0b’告诉解释器您正在处

  • 本文向大家介绍C语言中十六进制转十进制两种实现方法,包括了C语言中十六进制转十进制两种实现方法的使用技巧和注意事项,需要的朋友参考一下 C语言 · 十六进制转十进制 问题描述   从键盘输入一个不超过8位的正的十六进制数字符串,将它转换为正的十进制数后输出。   注:十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。 样例输入 FFFF 样例输出 65535 思路:感觉自己的

  • 我使用这个二进制搜索函数得到一个较大数据集的索引错误。当我输入一个较小的数据集时,即[1,2,3,4,5]搜索5。算法按预期运行。但是,当我获取下面的文本时,使用空参数列表(delimeter char为“”)调用string对象的split方法,并将字符串拆分为列表值,其中每个元素都是字符串,然后搜索单词“culpa”,我最终会出现以下错误: 索引错误:列表索引超出范围 非常感谢你的帮助。非常感

  • 本文向大家介绍Java 程序实现八进制转换为二进制,十进制,十六进制,包括了Java 程序实现八进制转换为二进制,十进制,十六进制的使用技巧和注意事项,需要的朋友参考一下 假设我们有一个八进制数字。要将八进制转换为其他进制,例如二进制,十六进制等,Java代码如下: 示例 输出结果 一个名为Demo的类包含一个名为“base_convert”的函数。此函数将整数从源基解析为目标基,将其转换为字符串