这是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
答案 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=5
为s[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]);
}
}
}