我正在尝试编写一个购物清单程序,用户可以在其中输入具有相应价格的购物清单项目。我在购物清单上的商品上使用了String数组,在价格上使用了double数组。最后,程序应打印出最贵的物品和最便宜的物品。
为此,我制作了价格数组的副本。然后使用Arrays.sort()
对原始价格数组进行排序,以便按升序重新排列。之后,我使用for循环将重复价格数组与已排序原始数组进行比较,并且当重复数组中的值与已排序数组中的最低/最高值相同时,我将购物商品打印在对应位置上。字符串数组。
这似乎并不完全正确,因为根据我的逻辑,所打印的字符串并不总是与确切位置相对应。我无法弄清楚哪里出了问题。我认为问题出在getCheapestItem()
和getMostExpensiveItem()
方法中。
编辑:
也许有更好的方法可以做到这一点,例如使用List或ArrayList,但是我只需要使用Arrays即可解决。
主类:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static Scanner scanner = new Scanner(System.in);
static int listSize;
static String[] sl;
static double[] price;
static double [] price_duplicate;
public static void main(String[] args) {
Fruit fruit = new Fruit();
shoppingList();
sl = new String[listSize];
price = new double[listSize];
//Loop asking user to enter items and prices
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println("Enter item " + (i+1) + ":");
fruit.setName(scanner.nextLine());
sl[i] = fruit.getName();
System.out.print("Price of " + sl[i] + ":");
fruit.setPrice(scanner.nextDouble());
scanner.nextLine(); //calling nextLine() to get rid of the newline character
price[i] = fruit.getPrice();
}
//Loop printing items and their prices
System.out.println();
System.out.println("-Your shopping list-");
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println(sl[i] + " cost " + price[i]);
}
System.out.println();
//Duplicate the price array
price_duplicate = price;
//Order the array in ascending order so as to be able to easily access lowest and highest values in the array
Arrays.sort(price);
//Identify the cheapest and most expensive items on the shopping list
getCheapestItem();
getMostExpensiveItem();
}
static int shoppingList(){
System.out.print("Enter the number of items in your shopping list:");
listSize = scanner.nextInt();
scanner.nextLine(); //calling nextLine() to get rid of the newline character
return listSize;
}
//Method to match the lowest price in the sorted array to its equivalent value in the duplicate of the original array and print the corresponding string from the sl array, thus identifying the cheapest item on the list
static void getCheapestItem(){
Arrays.sort(price);
for(int i = 0; i < price_duplicate.length; i++){
if(price_duplicate[i] == price[0])
{
System.out.println(sl[i] + " cost(s) " + price[0] + " and is/are the cheapest item(s) on the list.");
}
}
}
//Method to Match the highest price in the sorted array to its equivalent value in the duplicate of the original array and print the corresponding string from the sl array, thus identifying the most expensive item on the list
static void getMostExpensiveItem(){
Arrays.sort(price);
for(int i = price_duplicate.length - 1; i >= 0; i--){
if( price_duplicate[i] == price[price.length - 1])
{
System.out.println(sl[i] + " cost(s) " + price[price.length -1] + " and is/are the most expensive item(s) on the list.");
}
}
}
}
水果班:
public class Fruit {
private String name;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
答案 0 :(得分:1)
我猜您的问题出在复制/复制价格数组。您正在使用price_duplicate=price;
,它实际上并不复制价格数组内容,而只是引用/指向具有重复数组的同一价格数组对象。
因此,当您对原始价格数组进行排序时,您重复的数组也会被排序。有几个ways可以将一个数组对象复制到另一个对象。
但是我建议您使用现有的代码流之一,当您将价格插入原始的 price 数组中时,也可以将它们插入重复的数组中。
在
price[i]=fruit.getPrice();
之后,只需添加
price_duplicate[i]=fruit.getPrice();
别忘了初始化重复数组,就像之前初始化原始价格数组一样。
答案 1 :(得分:0)
我不确定为什么要使用两个数组,因为这会使事情变得更复杂。我会只列出一个列表static List<Fruit> fruits;
。
然后阅读项目也可以简化:
for(int i = 0; i <= listSize - 1; i++)
{
System.out.println("Enter item " + (i+1) + ":");
name = scanner.nextLine();
System.out.print("Price of " + sl[i] + ":");
price = scanner.nextDouble();
scanner.nextLine(); //calling nextLine() to get rid of the newline character
fruits.add(new Fruit(name, price));
}
当然,这意味着Fruit
需要一个既需要名称又需要价格的构造函数。 name
和price
应该在循环之外定义。
要进行排序,您可以使用Comperator<Fruit>
。
Comperator<Fruit> compareByPrice = (Fruit f1, Fruit f2) ->
f1.getPrice().compareTo(f2.getPrice());
要升序排序:
Collections.sort(fruits, compareByPrice);
以降序排列:
Collections.sort(fruits, compareByPrice.reversed());
答案 2 :(得分:0)
您不必使事情复杂化。您可以通过水果对象本身获得最便宜和最昂贵的水果。看下面的例子。创建水果对象列表。比做Collections.sort。在Collections.sort中,您可以提供Comparator的实现(对任何对象进行排序的方式)。在这种情况下,必须按价格进行分类。排序后,您可以在第一个索引中找到最便宜的水果,在最后一个索引中找到最昂贵的水果
BehaviorSubject
答案 3 :(得分:0)
您使用非法组织。您应该将代码分为以下部分:
Fruit
类,其中包含有关单个水果的完整信息这是Fruit
类的实现。它是不可变。
public final class Fruit {
private final String name;
private final double price;
public Fruit(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
}
接收List<Fruit>
并检索需要特定条件的结果的函数。
请注意,价格是 double 值,因此应使用Double.compare(one, two) == 0
方法而不是one == two
正确比较它。
private static final Function<List<Fruit>, List<Fruit>> GET_CHEAPEST = fruits -> {
final double minPrice = fruits.stream().mapToDouble(Fruit::getPrice).min().orElse(Double.NaN);
return fruits.stream().filter(fruit -> Double.compare(fruit.getPrice(), minPrice) == 0).collect(Collectors.toList());
};
private static final Function<List<Fruit>, List<Fruit>> GET_MOST_EXPENSIVE = fruits -> {
final double maxPrice = fruits.stream().mapToDouble(Fruit::getPrice).max().orElse(Double.NaN);
return fruits.stream().filter(fruit -> Double.compare(fruit.getPrice(), maxPrice) == 0).collect(Collectors.toList());
};
此方法使用Scanner
来接收有关所有水果的所有信息。不要忘记关闭Scanner
。
private static List<Fruit> getFruits() {
try (Scanner scan = new Scanner(System.in)) {
System.out.print("Enter the number of items in your shopping list: ");
int total = scan.nextInt();
List<Fruit> fruits = new ArrayList<>(total);
for (int i = 1; i <= total; i++) {
System.out.println("Enter item " + i + ':');
System.out.print("Name: ");
String name = scan.nextLine();
System.out.print("Price: ");
double price = scan.nextDouble();
fruits.add(new Fruit(name, price));
System.out.println();
}
return fruits;
}
}
最后是客户端代码。我相信现在很容易实现。
List<Fruit> fruits = getFruits();
List<Fruit> cheapestFruits = GET_CHEAPEST.apply(fruits);
List<Fruit> mostExpensiveFruits = GET_MOST_EXPENSIVE.apply(fruits);
System.out.println("Cheapest fruits:");
cheapestFruits.forEach(fruit -> System.out.format("%s costs %.2f\n", fruit.getName(), fruit.getPrice()));
System.out.println();
System.out.println("Most expensive fruits:");
mostExpensiveFruits.forEach(fruit -> System.out.format("%s costs %.2f\n", fruit.getName(), fruit.getPrice()));
答案 4 :(得分:0)
所以..我采用了另一种方式来处理信息。我相信值得您关注。尽管它不能满足您的问题,但它将创建一个有效的示例。
扫描仪或任何涉及将String解析为Integer / Double / Short / etc ..的问题,该String必须完全等于该值。
在您的示例中,执行Scanner.parseDouble(String);问题是用户是否输入非十进制值。您的程序将崩溃。最重要的是,如果小数位数不正确,它将返回无效或非预期的结果。
要解决这个问题,我们使用了一个char数组或一个远远超出我们需求的值类型。在我的情况下,我使用了长期价值。其最大数值为9,223,372,036,854,775,807。我们不需要这个数额附近的任何东西,因此可以安全地将商品的最高价格锁定为999,999,999.99,并且该价格可以容纳数百万次。然后,当需要显示此值时,我们可以将其转换为可作为价格阅读的文本。
我还采用了非数组方法,使您可以洞悉查找,存储和显示成本最低和成本最高的商品的另一种方式。我还给了您物品总数和总购物费用。希望您可以将其中一些示例用于将来的代码。
要指出他如何将数字字符串转换为值的另一件事。有很多方法可以解决此问题,但是在这种情况下,如果没有给出十进制,我选择从已知的十进制索引或字符串长度向后循环。我们将字符从0-9转换为0到9。这是通过将其char值减去48来完成的。如果该值不等于0到9之间的数字,那么我们将其跳过。如果可以,我们将其加到总价值中。我们从100开始作为乘数,因此98.76将给我们9800的价格值。然后,我们添加为99的更改,因此总数为9876。当我们要将其转换为价格时。我们执行9876/100 = 98并显示98。然后取9876和负(98 * 100)=76。因此,我们显示“。”和“ 76”。这使我们可以安全地显示费用,并且我们可以安全地支持0到999,999,999.99之间的任何金额。
_
import java.util.Scanner;
public class ShoppingList
{
private static long LOWEST_ITEM_COST = Long.MAX_VALUE;
private static long HIGHEST_ITEM_COST = -1;
private static long TOTAL_COST = 0;
private static int TOTAL_ITEMS = 0;
private static String LOWEST_ITEM_NAME;
private static String HIGHEST_ITEM_NAME;
public static void main(String[] args)
{
System.out.print("\nSyntax: FOODNAME PRICE, I.e. Apples $8.50");
while (true)
{
Scanner sc = new Scanner(System.in);
System.out.print("\nEnter a food: ");
String split[] = sc.nextLine().split(" ");
if (split.length > 2)
{
}
if (split.length == 2)
{
String name = split[0];
int length = split[1].length();
int decimal_position = -1;
for (int j = length; --j >= 0; )
{
if (split[1].charAt(j) == '.')
{
decimal_position = j;
break;
}
}
if (decimal_position != -1)
length = decimal_position;
long dollars = 0;
long change = 0;
int place = 100;
for (int c = length; --c >= 0; )
{
int value = (int)split[1].charAt(c) - 48;
if (value < 0 || value > 10)
continue;
if (place == 1000000000) //1 Billion is too large to process stop here!
{
System.out.print("\nPrice Amount exceeds $999,999,999.99 limitation! You entered: " + split[1]);
continue;
}
value *= place;
place *= 10;
dollars += value;
}
place = 10;
if (decimal_position != -1 && (split[1].length() - 3 >= decimal_position))
{
for (int c = decimal_position; c < split[1].length(); ++c)
{
int value = (int)split[1].charAt(c) - 48;
if (value < 0 || value > 10)
continue;
value *= place;
place -= 9;
change += value;
if (place < 0)
break;
}
}
System.out.print("\nItem: " + name + " was added to the shopping cart. Cost: $" + (dollars / 100) + '.' + ((change < 10) ? (change + '0') : (change)));
dollars += change;
if (dollars < LOWEST_ITEM_COST)
{
LOWEST_ITEM_COST = dollars;
LOWEST_ITEM_NAME = name;
}
if (dollars > HIGHEST_ITEM_COST)
{
HIGHEST_ITEM_COST = dollars;
HIGHEST_ITEM_NAME = name;
}
TOTAL_ITEMS++;
TOTAL_COST += dollars;
} else {
if (split.length == 1 && split[0].toLowerCase().contains("done"))
{
break;
}
System.out.print("\nSyntax: FOODNAME PRICE, E.g. IceCream 8.50");
System.out.print("\nTo Finish The Shopping List Simply type: DONE");
continue;
}
}
if (TOTAL_ITEMS == 0)
{
System.out.print("\nNothing Was Added To Your Shopping List Today..");
return;
}
long dollars = HIGHEST_ITEM_COST / 100;
long change = HIGHEST_ITEM_COST - (dollars * 100);
System.out.print("\nHighest Cost Item: " + HIGHEST_ITEM_NAME + " , Costed: " + dollars + '.' + change + ((change < 10) ? '0' : ""));
dollars = LOWEST_ITEM_COST / 100;
change = LOWEST_ITEM_COST - (dollars * 100);
System.out.print("\nLowest Cost Item: " + LOWEST_ITEM_NAME + " , Costed: " + dollars + '.' + change + ((change < 10) ? '0' : ""));
dollars = TOTAL_COST / 100;
change = TOTAL_COST - (dollars * 100);
System.out.print("\nTotal Items Bought: " + TOTAL_ITEMS + " , With a total cost of $" + dollars + '.' + change + ((change < 10) ? '0' : ""));
}
}