字符串加法计算,由一段由数学表达式组成的字符串,计算出这段字符串的实际结果
在本例中,只需要实现加法
规则说明:
支持负数
支持多个数的加法
只支持10进制,其他进制不考虑
不支持科学计数法
不支持常数,例如e等
不接受大于等于3个连符号,例如“+++“
完全忽略非0到9和+、-号和小数点的字符
算法题要求:
/**
* <h2>字符串加法计算</h2>
* 由一段由数学表达式组成的字符串,计算出这段字符串的实际结果。
* <p>例如:</p>
* <ut>
* <li>“1+1“=2</li>
* <li>“1-1“=0</li>
* <li>“1+a“=1</li>
* </ul>
* <p>在本例中,只需要实现加法·</p>
* <h2>规则说明</h2>
* <ut>
* <li>支持负数</li>
* <li>支持多个数的加法</li>
* <li>只支持10进制,其他进制不考虑</li>
* <li>不支持科学计数法</li>
* <li>不支持常数,例如e等</li>
* <li>不接受大于等于3个连符号,例如“+++“</li>
* <li>完全忽略非0到9和+、-号和小数点的字符</li>
* </ut>
* @param input 输入源
* @return 计算结果
*/
public static double calc(String input) {
}
测试类:
@DisplayName("字符串加法")
@ParameterizedTest(name = "输入字符串:{0},预期识别结果:{1}")
@CsvSource({
"1+1,2",
"85+96,181",
"1+a,1",
"1+-1,0",
"1+ 1,2",
"a+1,1",
"1+1+1,3",
"-1+ -1,-2",
"-1 + -1,-2",
" -1 + -1 ,-2",
" a + -1,-1",
"1a,1",
"1a+1,2",
"1a0+10,20",
"1ffff+1ffff,2",
"1_+1,2",
"1*1,11",
"1*1+1*1,22",
"(a+1)+1,2",
"0.10001+0.1,0.20001",
"Θ.121+-0.12,0.001",
"0.01+-0.1,-0.09",
"3.1415901+-0.0000001,3.14159",
"3.1415926535897932384626433832795+0.01,3.1515926535897932384626433832795",
"0.333333333333+0.333333333333+0.333333333333,0.999999999999",
})
void calcTest(String intput,Double expected) {
double actual = Calculate.calc(intput);
Assertions.assertEquals(expected, actual);
}
答案1:
public static double calc(String input) {
// 1.空值检验
if (!StringUtils.hasText(input)) {return 0;}
// 2.使用正则表达式来保存字符串中的数字,加号,负号,小数点,同时剔除其他字符
input = input.replaceAll("[^0-9+\\-\\.]", "");
input = input.trim();
// 3.只计算加法,分割成字符串数组
String[] numberStrArr = input.split("\\+");
// 4.计算总数
double sum = getSum(numberStrArr);
// 5.输出结果
return sum;
}
/**
* 求和计算
* @param numbers
* @return
*/
private static double getSum(String[] numbers) {
if (numbers == null || numbers.length==0)return 0;
BigDecimal sum = new BigDecimal(0);
for (String number : numbers) {
// number不能为空
if (StringUtils.hasText(number)){
BigDecimal num = new BigDecimal(number);
sum = sum.add(num);
}
}
return sum.doubleValue();
}
运行结果:
答案2:
public static double calc(String input) {
// 1.空值检验
if (!StringUtils.hasText(input)) {return 0;}
// 2.只计算加法,分割成字符串数组
String[] numberStrArr = input.split("\\+");
// 3.字符串数组转换成bg数组
// bg能保证精度不丢失
BigDecimal[] numbers = getNumbers(numberStrArr);
// 4.计算总数
double sum = getSum(numbers);
// 5.输出结果
return sum;
}
/**
* 将字符串数组转换成bg数组
* @param numberStrArr
* @return
*/
private static BigDecimal[] getNumbers(String[] numberStrArr) {
// 1.空值校验
if (null == numberStrArr || numberStrArr.length == 0 ) return new BigDecimal[0];
BigDecimal[] numbers = new BigDecimal[numberStrArr.length];
// 2.遍历字符串数字,转换成bg数字
for (int i = 0; i < numberStrArr.length; i++) {
String numberStr = numberStrArr[i];
BigDecimal number = extracNumber(numberStr);
numbers[i] = number;
}
// 3.返回bg数组
return numbers;
}
/**
* 将字符串转换成数字,过滤其中的非数字字符
* @param numberStr
* @return
*/
private static BigDecimal extracNumber(String numberStr) {
if (!StringUtils.hasText(numberStr))return new BigDecimal(0);
// 1.转换成字符数组
char[] charArr = numberStr.toCharArray();
StringBuilder result = new StringBuilder();
// 2.遍历字符数组,过滤非数字字符
for (char aChar : charArr) {
// 仅为一个字符
if (charArr.length==1){
// 非数字返回0
if (!Character.isDigit(aChar)){
result.append("0");
}else {
result.append(aChar);
}
}else {
// 剔除非数字字符
// 1.支持负号
if (aChar == '-') {
result.append(aChar);
} else if (aChar == '.') {
// 2.支持小数点
result.append(aChar);
} else if (Character.isDigit(aChar)) {
// 3.支持0-9数字
result.append(aChar);
}
}
}
// 3.返回bg数字
if (!StringUtils.hasText(result)) result.append(0);
return new BigDecimal(result.toString());
}
/**
* 求和计算
* @param numbers
* @return
*/
private static double getSum(BigDecimal[] numbers) {
if (numbers == null || numbers.length==0)return 0;
BigDecimal sum = new BigDecimal(0);
for (BigDecimal number : numbers) {
sum = sum.add(number);
}
return sum.doubleValue();
}