Java字符串之StringToKenizer类分割字符串之计算手机话费总额
主要用到的是StringTokenizer类里的构造函数,用于切割字符串得到想要的子字符串。
import java.util.Scanner;
import java.util.Arrays;
import java.util.StringTokenizer;
public class StrTest {
public static void main(String[] args) {
// 请在Begin-End间编写代码
/********** Begin **********/
// 接收给定的话费清单(由三行组成)
Scanner input=new Scanner(System.in);
String str1=input.next();str1=str1+" ";
String str2=input.next();str2=str2+" ";
String str3=input.next();
// 拼接三行字符串
String str=str1.concat(str2.concat(str3));
// 分隔字符串,累加每种物品的价格
StringTokenizer str0=new StringTokenizer(str);
float sum=0;
while(str0.hasMoreTokens()){
String s1=str0.nextToken();
StringTokenizer s2=new StringTokenizer(s1,":");
String uless=s2.nextToken();
String uful=s2.nextToken();
char a1[]=uful.toCharArray();//a1为所有数字,包括小数点,包括“元”
char a2[]=Arrays.copyOfRange(a1,0,a1.length-1);//去“元”,后面这个索引是不包含
String uful2=new String(a2);
StringTokenizer s3=new StringTokenizer(uful2,".");
char front[]=(s3.nextToken()).toCharArray();
char rear[]=(s3.nextToken()).toCharArray();
int item=0;
for(int i=front.length-1;i>=0;i--){
sum+=(front[i]-'0')*(Math.pow(10,item));
item++;
}
item=1;
for(int i=0;i<rear.length;i++){
sum+=(rear[i]-'0')*(Math.pow(0.1,item));
item++;
System.out.println(sum);
}
}
// 输出话费总额
System.out.print("话费总额为:"+sum);
/********** End **********/
}
}
测试输入:
套餐及固定费用:58.00元
移动增值业务费:3.00元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:61.5
测试输入:
套餐及固定费用:68.00元
移动增值业务费:36.50元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:105.0
测试输入:
套餐及固定费用:108.00元
移动增值业务费:20.04元
套餐外短信/彩信费:0.9元
—— 预期输出 ——
话费总额为:128.94
思路非常简单。
第一步:测试用例只能一个个接受,最后拼起来,为了方便切割,每个子字符串之间连接上一个“ ”。(突然发现好像没必要连起来)。
第二步:以“:”把字符串分割成两部分,弃去没有数字的那部分,由于分割的子字符串只能从前往后一个个接,故不得不用一个字符串uless接受这部分,并再用一个字符串uful接受有用的部分。
第三步:把uful转化成字符数组,用于剔去“元”这个于计算无用的字符。再把得到的字符数组转化成字符串,以“.”切割。
第四步:分别用front[]和rear[]来接受小数点前的整数部分后小数点后的小数部分,分别计算求和。
得到以下结果:
试输入:
套餐及固定费用:58.00元
移动增值业务费:3.00元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:61.5
—— 实际输出 ——
话费总额为:61.5
测试输入:
套餐及固定费用:68.00元
移动增值业务费:36.50元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:105.0
—— 实际输出 ——
话费总额为:105.0
测试输入:
套餐及固定费用:108.00元
移动增值业务费:20.04元
套餐外短信/彩信费:0.9元
—— 预期输出 ——
话费总额为:128.94
—— 实际输出 ——
话费总额为:128.93999
最后一个结果不对。128.94与128.93999是怎么得到的呢?我的sum是由整数部分和小数部分依次求和得到的,难道是求和的过程除了问题?
依次打印求小数部分的sum值:
试输入:
套餐及固定费用:58.00元
移动增值业务费:3.00元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:61.5
—— 实际输出 ——
这一次的sum值为:58.0
这一次的sum值为:58.0
这一次的sum值为:61.0
这一次的sum值为:61.0
这一次的sum值为:61.5
话费总额为:61.5
测试输入:
套餐及固定费用:68.00元
移动增值业务费:36.50元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:105.0
—— 实际输出 ——
这一次的sum值为:68.0
这一次的sum值为:68.0
这一次的sum值为:104.5
这一次的sum值为:104.5
这一次的sum值为:105.0
话费总额为:105.0
测试输入:
套餐及固定费用:108.00元
移动增值业务费:20.04元
套餐外短信/彩信费:0.9元
—— 预期输出 ——
话费总额为:128.94
—— 实际输出 ——
这一次的sum值为:108.0
这一次的sum值为:108.0
这一次的sum值为:128.0
这一次的sum值为:128.04
这一次的sum值为:128.93999
话费总额为:128.93999
其实很明显前两个测试用例没有出错就说明不太可能是算法的问题。想到之前的一道题:float与double型数据二进制算法不同,所以输入同样的值可能有不同的结果。
所以把sum更改为double型。
试输入:
套餐及固定费用:58.00元
移动增值业务费:3.00元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:61.5
—— 实际输出 ——
这一次的sum值为:58.0
这一次的sum值为:58.0
这一次的sum值为:61.0
这一次的sum值为:61.0
这一次的sum值为:61.5
话费总额为:61.5
测试输入:
套餐及固定费用:68.00元
移动增值业务费:36.50元
套餐外短信/彩信费:0.5元
—— 预期输出 ——
话费总额为:105.0
—— 实际输出 ——
话费总额为:105.0
这一次的sum值为:68.0
这一次的sum值为:68.0
这一次的sum值为:104.5
这一次的sum值为:104.5
这一次的sum值为:105.0
测试输入:
套餐及固定费用:108.00元
移动增值业务费:20.04元
套餐外短信/彩信费:0.9元
—— 预期输出 ——
话费总额为:128.94
—— 实际输出 ——
这一次的sum值为:108.0
这一次的sum值为:108.0
这一次的sum值为:128.0
这一次的sum值为:128.04
这一次的sum值为:128.94
话费总额为:128.94
这说明定义数值类型时尽量定义double类型,否则会有精度损失。
版权声明:本文为xx2765562488原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。