Java中的大十进制比较

时间:2016-03-11 05:49:00

标签: java comparison decimal precision bigdecimal

这是BigDecimal比较的问题还是错误的预期输出?

import java.math.*;
import java.util.*;
class Solution{

 public static void main(String []argh)
 {

    int res;
    String temp = "";
    Scanner sc= new Scanner(System.in);
    MathContext mc = new MathContext(100, RoundingMode.FLOOR);
    int n=sc.nextInt();
    String []s=new String[n+2];
    for(int i=0;i<n;i++)
    {
        s[i]=sc.next();
    }

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            res = new BigDecimal(s[i], mc).compareTo(new BigDecimal(s[j], mc));
            if(res == 1){
                temp = s[i];
                s[i] = s[j];
                s[j] = temp;
            }
        }
    }

    for(int i=0;i<n;i++)
    {
        System.out.println(s[i]);
    }

 }
}
Sample Input:     9 -100 50 0 56.6 90 0.12 .12 02.34 000.000

Expected Output: 90 56.6 50 02.34 0.12 .12 0 000.000 -100

My Output:       90 56.6 50 02.34 .12 0.12 0 000.000 -100

4 个答案:

答案 0 :(得分:1)

您的排序算法不保留等效项的位置。这会导致输出与您期望的不同。

如果您想要的产品是&#34;相当于&#34;要保持与输入顺序相同的顺序,您需要实现该排序算法。

这是您更新的代码,以预期的方式排序:

class Solution {

    public static void main(String[] argh) {

        int res;
        String temp = "";
        Scanner sc = new Scanner(System.in);
        MathContext mc = new MathContext(100, RoundingMode.FLOOR);

        int n = sc.nextInt();
        String[] s = new String[n + 2];

        for (int i = 0; i < n; i++) {
            s[i] = sc.next();
        }

        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                res = new BigDecimal(s[j + 0], mc).compareTo(new BigDecimal(s[j + 1], mc));
                if (res == -1) {
                    temp = s[j + 1];
                    s[j + 1] = s[j + 0];
                    s[j + 0] = temp;
                }
            }
        }

        for (int i = 0; i < n; i++) {
            System.out.println(s[i]);
        }

        sc.close();
    }
}

答案 1 :(得分:1)

这完全是因为比较的顺序

您的算法正在向左侧复制更大的值。让我们考虑每次迭代后的字符串数组状态。当import java.util.Stack; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.TextField; import javafx.scene.layout.TilePane; import javafx.scene.layout.VBox; import javafx.stage.Stage; import javafx.stage.StageStyle; public class Main extends Application { /*The keyboard key values*/ private static final String[][] key_values = { { "7", "8", "9", "/" }, { "4", "5", "6", "*" }, { "1", "2", "3", "-" }, { "0", "c", "=", "+" } }; private Button btn[][] = new Button[4][4]; //all the keys TextField calculator_screen; //the calculator screen boolean isEqualCalled = false; int flag=0,repeat=0; String exp; String temp; String sample = "0"; String sample2 = "0"; Double num1=0.0,num2=0.0,sum=0.0; Double checkNum=0.0; Double temp_sum=0.0; Stack <String>stack = new Stack<>(); Stack <String>stack_new = new Stack<>(); //MyStack s = new MyStack(); public static void main(String[] args) { launch(args); //System.out.print("123456789"); } @Override public void start(Stage stage) { /*The outside layout*/ final VBox layout = new VBox(30); //the size vertically /*The inside layout for keys or buttons*/ TilePane keypad = new TilePane(); //even it is called keypad, it is a layout keypad.setVgap(7); keypad.setHgap(7); //set the gap between keys /*Create Calculator Screen */ calculator_screen = new TextField(); calculator_screen.setStyle("-fx-background-color: #FFFFFF;"); //set the style of the screen calculator_screen.setAlignment(Pos.CENTER_RIGHT); //make the screen in the center of the calculator calculator_screen.setEditable(false); //make sure the screen cannot be typed in manually calculator_screen.setPrefWidth(500); //set the windth of the screen /*Create Calculator keyboard*/ keypad.setPrefColumns(key_values[0].length); //set the preferred number of columns for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { btn[i][j] = new Button(key_values[i][j]); final int a = i; final int b = j; /*Add button event*/ btn[i][j].setOnAction(new EventHandler<ActionEvent>(){ @Override public void handle(ActionEvent event) { if(isEqualCalled){ calculator_screen.clear(); isEqualCalled = false; } calculator_screen.appendText(key_values[a][b]); exp = calculator_screen.getText().toString(); } } ); keypad.getChildren().add(btn[i][j]); } } btn[3][1].setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent arg0) { // TODO Auto-generated method stub calculator_screen.setText(""); } }); //-------------When "=" button is pressed-------- btn[3][2].setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent arg0) { // TODO Auto-generated method stub //System.out.println("============="); //System.out.println("Expression = "+ exp); isEqualCalled = true; //--------------Pushing the elements to the stack------------------- exp = exp+"\n"; char [] ch = exp.toCharArray(); int len = ch.length; int i=0; for(int j=0;j<len;j++) { if(ch[j]>='0' && ch[j]<='9') { //System.out.println("Digit = "+ ch[j]); i=j; sample = "0"; while(ch[i]>='0' && ch[i]<='9' && i < len)//To check if there is a more than 1 digit nummber. { if(ch[i]>='0' && ch[i]<='9') { System.out.println("Digit = "+ ch[i]); System.out.println("sample before = "+ sample); sample = sample+exp.charAt(i); System.out.println("sample after = "+ sample); i++; } } stack.push(sample); //System.out.println("hiii"); j=i-1; } else { System.out.println("Sign = "+ ch[i]); stack.push(Character.toString(ch[i])); } } temp=stack.pop(); int size= stack.size(); System.out.println("Size of stack = "+ size); //if(stack.size()==null) //-----------Reversing the order of the stack------------- while(!stack.isEmpty()) { sample2=stack.pop(); stack_new.push(sample2); } //-----------Evaluating the expression-------------------- while(!stack_new.isEmpty()) { System.out.println("--------"); temp=stack_new.peek(); System.out.println("Stack item = "+temp); int type =checkString(temp) ; if(type == 0) { num1 = Double.parseDouble(temp); stack_new.pop(); //System.out.println("Stack item = "+sum); } else if(type ==5) { System.out.println("Stack Empty"); //stack.pop(); flag=2; break; } else { int op=checkString(temp); stack_new.pop(); //System.out.println("Stack item = "+sum); temp=stack_new.peek(); type =checkString(temp) ; if(type!=0) { System.out.println("Invalid"); flag=2; } else { num2=Double.parseDouble(temp); if(op==1) { temp_sum=num1+num2; System.out.println("Sum = "+ temp_sum); } else if(op==2) { temp_sum=num1-num2; System.out.println("Diff = "+ temp_sum); } else if(op==3) { temp_sum=num1*num2; System.out.println("Product = "+ temp_sum); } else { if(num2!=0) { temp_sum=num1/num2; System.out.println("Division = "+ temp_sum); } else { System.out.println("Cannot divide by 0"); flag=1; } } num1=temp_sum; } stack_new.pop(); } } System.out.println("result = "+ temp_sum); if(flag==0) calculator_screen.setText(temp_sum.toString()); else if(flag==1) { calculator_screen.setText("Error"); calculator_screen.setStyle("-fx-text-fill: red;"); } else if(flag==2) { calculator_screen.setText("Invalid Expression"); calculator_screen.setStyle("-fx-text-fill: red;"); } } public int checkString(String temp) { // TODO Auto-generated method stub if(temp.length()==1) { char ch=temp.charAt(0); if(ch=='+') return 1; else if(ch=='-') return 2; else if(ch=='*') return 3; else if(ch=='/') return 4; else return 5; } else return 0; } }); /*Put the calculator screen and keypad into a VBox layout*/ layout.setAlignment(Pos.CENTER); //layout.setStyle("-fx-background-color: #797983; -fx-padding: 20; -fx-font-size: 20;"); layout.getChildren().addAll(calculator_screen, keypad); calculator_screen.prefWidthProperty().bind(keypad.widthProperty()); /*Show the window*/ stage.setTitle("Calculator"); stage.initStyle(StageStyle.UTILITY); stage.setResizable(false); Scene scene = new Scene(layout); stage.setScene(scene); stage.show(); } } 数组为:

i=0

因为i=0: -100 50 0 56.6 90 0.12 .12 02.34 000.000 很小,所以它保持原位。来吧:

-100

因为i=1: 50 -100 0 56.6 90 0.12 .12 02.34 000.000 大于50,所以会将其复制到左侧。来吧:

-100

i=2: 50 0 -100 56.6 90 0.12 .12 02.34 000.000 i=3: 56.6 50 0 -100 90 0.12 .12 02.34 000.000 i=4: 90 56.6 50 0 -100 0.12 .12 02.34 000.000 i=5s[5]时,您感兴趣的事情就会发生:

0.12

i=5: 90 56.6 50 0.12 0 -100 .12 02.34 000.000 将在之前0.12进行比较,并将在.12之前取代它。现在,0时我们会比较i=6

.12

因为i=6: 90 56.6 50 0.12 .12 0 -100 02.34 000.000 不大于.12并且稍后0.12更新,所以它将保留在0.12的右侧。

因此,BigDecimal比较没有问题。它运作正常。

希望我的解释不是太复杂。

答案 2 :(得分:1)

您需要实现此代码,以保留等效术语的顺序。使用常规的排序算法,您可以成功进行排序,但是将无法保留.12和0.12的排序顺序

这是您的代码,以获得确切的预期结果:

java.math.BigDecimal;
import java.util.*;
class Solution{
    public static void main(String []args){
        //Input
        Scanner sc= new Scanner(System.in);
        int n=sc.nextInt();
        String []s=new String[n+2];
        for(int i=0;i<n;i++){
            s[i]=sc.next();
        }
        sc.close();

        Comparator<String> customComparator = new Comparator<String>() {
        @Override
        public int compare(String s1, String s2) {
            BigDecimal a = new BigDecimal(s1);
            BigDecimal b = new BigDecimal(s2);
            return b.compareTo(a); 
        }
        };

        Arrays.sort(s, 0, n, customComparator);


        //Output
        for(int i=0;i<n;i++)
        {
            System.out.println(s[i]);
        }
   }
}

答案 3 :(得分:0)

在您的方法中,不是数组其余部分中最大元素的每个元素也可能会被交换。

例如,在第二轮内循环中,当 i = 0 j = 1 时。

s[i] = -100 
s[j] = 50

然后s[I]s[j]互相交换。

实际上,s[j] = 50不是数组其余部分中最大的元素。但是元素的位置将更改,因此原始顺序也将更改。

为了保持每个元素的原始位置,您应该只交换数组其余部分中最大的元素。这些不是最大的元素,不应在每次迭代期间交换

这是示例代码

class Solution{
    public static void main(String []args){
        //Input
        Scanner sc= new Scanner(System.in);
        int n=sc.nextInt();
        String []s=new String[n+2];
        for(int i=0;i<n;i++){
            s[i]=sc.next();
        }
        sc.close();

        // position of the biggest element in the array
        // it is used as a mark, we will use it later 
        // when we put the biggest element in the front of the array
           int maxIndex;

        for (int i = 0; i < n; i++) {
            // at the begin of a loop, 
            // set the first element as the biggest element
            // the maxDec may be changed during each iteration
            String maxDec = s[i];

            // reset maxDec at each iteration
            maxIndex = i;

            // we always put the biggest element in the front of the array
            // we only changed the position of the biggest element
            // other elements which are not the biggest 
            // will keep the same position as before
            for (int j = i; j < n; j++) {
                // create two BigDecimal objects for comparasion
                BigDecimal max = new BigDecimal(maxDec);
                BigDecimal dec = new BigDecimal(s[j]);

                // if two decimal are equal
                if (max.compareTo(dec) == 0) 
                    continue;

                // if any element greater the maxDec
                // mark it position, 
                // but does not put it in the front of the array
                // this operation will keep 
                // the original order of element in the array
                if (max.compareTo(dec) < 0) {
                    maxDec = s[j];
                    maxIndex = j;
                }
            }

            // in the end of loop, 
            // maxIndex marks the position of the biggest element
            // we put it in the front of the array
            if (i != maxIndex) {
                s[maxIndex] = s[i];
                s[i] = maxDec;
            }
        }

        for(int i=0;i<n;i++)
        {
            System.out.println(s[i]);
        }
    }
}