【问题标题】:How do I convert a String into doubles to compute average in Java?如何将字符串转换为双精度以在 Java 中计算平均值?
【发布时间】:2021-03-27 00:40:02
【问题描述】:

我在作业方面需要帮助。这里有很多类似的问题,但这些答案对我不起作用,所以我不知道我做错了什么。

分配是“程序提示用户输入 5 到 10 个数字,都在一行上,并用空格分隔。然后程序计算这些数字的平均值,并将这些数字及其平均值显示给用户。”

我们需要调用不同的方法来做到这一点。给我带来问题的部分是将字符串转换为双精度并找到平均值。我们还需要验证字符串中是否有 5-10 个数字(我可以在正确计数后验证它)。我尝试了一些方法,包括对此处类似问题的答案(如下面的代码所示),但我得到的唯一输出是 0.0。

这是我的代码:

public static void main(String[] args) {
              
        String getNumbers = "";
        double calcAverage = 0;
        
        getNumbers();
        calcAverage(getNumbers);
        System.out.println(calcAverage);
                
    }
    
    public static String getNumbers() {
        Scanner scnr = new Scanner(System.in);
        
        System.out.println("Please enter 5 to 10 numbers separated by spaces: ");
        String getNumbers = scnr.next();
        
        return getNumbers;
    }

    
public static double calcAverage(String userNumbers){

        double calcAverage = 0.0;
        double i = 0;
        double count = 0.0;
        
        Scanner str = new Scanner(userNumbers);
        
        while (str.hasNextDouble()){
            count++;
            i = i + str.nextDouble();
        }
        System.out.println("count=" + count); //test to check it is counting properly
        calcAverage = i/count;
        return calcAverage;
    }

非常感谢您的帮助!

【问题讨论】:

  • 对不起 Zephyr,我没有澄清。作业要我们使用一个while循环。我确实看到你写的方法是一种可能,但不幸的是它不符合作业要求。
  • 我建议您edit 提出您的问题并发布您的minimal reproducible example。在不知道传递给此方法的userNumbers 字符串的格式的情况下,很难进行测试。
  • @Zephyr,我现在将添加更多代码。这是我第一次提出问题,我不确定要添加什么
  • 不用担心,欢迎来到 Stack Overflow。请务必阅读我发布的链接,因为它对本网站非常重要。有时这似乎有点矫枉过正,但相信我:它总会带来更有帮助的答案。 :)
  • 可以使用Double.parseDouble(String)进行解析

标签: java string average


【解决方案1】:

您的 main 方法中似乎有错误,需要将 getNumbers 设置为等于 getNumbers 方法,并且与 calcaverage 方法的 calcaverage double 相同。

public static void main(String[] args) {
              
        String getNumbers = "";
        double calcAverage = 0;
        
        getNumbers();
        calcAverage(getNumbers);
        System.out.println(calcAverage);
                
    }

应该是

public static void main(String[] args) {
              
        String getNumbers = "";
        double calcAverage = 0;
        
        getNumbers =getNumbers();
        calcAverage =calcAverage(getNumbers);
        System.out.println(calcAverage);
                
    }

【讨论】:

  • 谢谢!!我一直认为我是对的,哈哈……
【解决方案2】:

您可以使用流使其更具可读性并避免外部迭代


import static java.util.Arrays.stream;
import java.util.OptionalDouble;


class Scratch {

  public static void main(String[] args) {

    OptionalDouble optAvg = calcAverage("2 5 6 7 8 9 0 1");

    if (optAvg.isPresent()) {
      System.out.println("optAvg.getAsDouble() = " + optAvg.getAsDouble());
    }

  }

  public static OptionalDouble calcAverage(String userNumbers) {

    String[] inputArr = userNumbers.split(" ");
    int count = inputArr.length;

    System.out.println("count = " + count);

    if (count < 5 || count > 10) {
      throw new IllegalArgumentException("Or do some other this here!");
    }

    return stream(inputArr)
        .mapToDouble(
            Double::parseDouble) // throws a NumberFormatException if it can't convert to Double
        .average();
  }
}

甚至更简单


import static java.util.Arrays.stream;
import java.util.DoubleSummaryStatistics;


class Scratch {

  public static void main(String[] args) {

    DoubleSummaryStatistics doubleSummaryStatistics = calcAverage("2 5 6 7 8 9 0 1");
    System.out.println("count = " + doubleSummaryStatistics.getCount());
    System.out.println("average = " + doubleSummaryStatistics.getAverage());
  }

  public static DoubleSummaryStatistics calcAverage(String userNumbers) {
    return stream(userNumbers.split(" "))
        .mapToDouble(Double::parseDouble)
        .summaryStatistics();
  }
}

【讨论】:

  • 我真的很感谢你这样做,但我还没有学到很多你放在那里的东西,所以很遗憾我不能使用它,除非我想让我的老师知道我寻求帮助 lol
【解决方案3】:

给你:

public static void main(String[] args) {

    String numberString = getNumbers();
    double averageNum = calcAverage(numberString);
    System.out.println(averageNum);
            
}

public static String getNumbers() {
    Scanner scnr = new Scanner(System.in);

    System.out.println("Please enter 5 to 10 numbers separated by spaces: ");
    String getNumbers = scnr.nextLine();
    
    return getNumbers;
}


public static double calcAverage(String userNumbers){

    double calcAverage = 0.0;
    double i = 0;
    double count = 0.0;
    
    Scanner str = new Scanner(userNumbers);
    
    while (str.hasNextDouble()){
        count++;
        i = i + str.nextDouble();
    }
    System.out.println("count=" + count); //test to check it is counting properly
    calcAverage = i/count;
    return calcAverage;
}

进行了一些更改,但大多数情况下您都做对了。从文件顶部开始:

  • 删除了 getNumbers 和 calcAverage
  • 增加了numberString和averageNum(当你调用带有return的函数时,你需要将它返回的值存储到一个变量中)
  • 换行:
String getNumbers = scnr.next();

到:

String getNumbers = scnr.nextLine();

如果您有任何问题,请告诉我。

【讨论】:

  • 谢谢!!那么我遇到的主要问题是String getNumbers = scnr.next(); 而不是String getNumbers = scnr.nextLine(); ??
  • 没错!一个非常小的错误,否则做得很好!
【解决方案4】:

这是使用提供的值验证的一种方法:

public static double calcAverage(String userNumbers) {
    double calcAverage = 0.0;
    double i = 0;
    int count = 0;

    Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));

    while (str.hasNext()) {
        String val = str.next();
        // Is the supplied numerical value valid?
        if (!val.matches("-?\\d+(\\.\\d+)?")) {
            //No...
            System.out.println("Supplied value of " + val + 
                    " is ignored since it is not a valid numerical value!");
            continue;
        }
        count++;  // count now that we know the value is indeed valid.
        i += Double.parseDouble(val);
        
    }
    
    System.out.println("count=" + count); //test to check it is counting properly
    calcAverage = i / count;
    return calcAverage;
}

由于您正在处理提供的由空格分隔的字符串希望 数值,您只能将Scanner#hasNext() 方法与Scanner#next() 方法结合使用。

准备扫描器对象:

Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));

这里我们获取包含在提供的userNumbers 字符串变量中的字符串,并修剪掉任何可能的前导和尾随空格,如果有的话,我们不想要这些。我们还将提供的字符串中可能包含更多的任何部分替换为仅使用单个空格而不是单个空格。我们希望在继续之前强制执行此格式,以帮助消除稍后在方法代码中的任何可能类型的冲突。你不能总是依靠用户来完美地提供一切,所以如果你能提供帮助,那是值得的。

从提供的字符串中检索每个提供的值:

while (str.hasNext()) {
    String val = str.next();
    // ... other code ...
} 

hasNext() 方法将允许循环继续,只要有另一个空格分隔的字符串标记要处理。在这种情况下,我们希望每个标记都是数字值的字符串表示形式。

因为hasNext() 方法让我们深入到循环中,所以我们知道还有另一个可用的字符串标记。 str.next() 调用检索该可用令牌,在这种情况下,将该字符串令牌放入名为val 的字符串变量中。这是在 while 循环的每次迭代中完成的,直到没有更多的令牌需要处理。

验证检索到的字符串标记:

if (!val.matches("-?\\d+(\\.\\d+)?")) { ... }

这里使用String#matches() 方法以及"-?\\d+(\\.\\d+)?" 的特定Regular Expression(正则表达式)验证每个字符串标记。当传入matches() 方法时,此正则表达式检查它所针对的字符串是否确实是有符号或无符号整数或浮点数值的字符串表示:

-?            Optional. Value is prefixed with '-'.
\\d+          One or more digits.
(\\.\\d+)?    Optional. Value is post-fixed with a decimal point 
              and one or more digits.

在这种情况下,我们将检查令牌是否无效,如果是,我们会向控制台窗口提供一条消息,指示该令牌值将被忽略的事实。我们通过使用 continue 关键字来忽略它,该关键字强制 while 循环进入下一次迭代并绕过循环中的剩余代码。

将 String 数值转换为 Double 数据类型:

count++;  // count now that we know the value is indeed valid.
i+= Double.parseDouble(val);

我们在知道所提供的值确实有效之后进行计数。 i 之前被声明为 double 类型,并在使用 Double.parseDouble() 方法将其转换为 double 后对令牌数值求和。使用i += 与使用i = i + 完全相同。


另一种更短的方式:

public static double calcAverage(String userNumbers) {
    double calcAverage = 0.0;
    double i = 0;
    int count = 0;

    Scanner str = new Scanner(userNumbers.trim().replaceAll("\\s+", " "));
    while (str.hasNextDouble()) {
        double val = str.nextDouble();
        count++; 
        i+= val;
    }
    
    System.out.println("count=" + count); //test to check it is counting properly
    calcAverage = i / count;
    return calcAverage;
}

【讨论】:

    猜你喜欢
    • 2018-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多