题目详情
一份银行流水数据,因打印模糊导致部分金额不清楚。
收入、支出、余额满足以下3条规则:
1、收入、支出、余额三列都是数字
2、同一行收入和支出的值不能同时为非零值
3、第N-1行余额(+第N行收入或-第N行支出)=第N行余额
程序语言: java
请按照规则编写算法,修复不清楚的值
输入描述:
输入数据最多25行,每行都包含四个数据,分别是:数据编号,收入、支出、余额,模糊的数据以?表示,
它们之间以;隔开。
以文件结尾。第一组数据为初始数据值,收入、支出、余额数据保留2位小数。
输出描述:
以输入的数据顺序输出修复后的数据。
答题说明
输入样例:
流水记录ID;收入;支出;余额
1;0.00;51.90;1945.45
2;0.00;1000.00;?
输出样例:
流水记录ID;收入;支出;余额
1;0.00;51.90;1945.45
2;0.00;1000.00;945.45
试了30次,无法通过。求大神指点。不多说,代码如下
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Scanner;
public class Main {
/**
* 标志:代表?,即未知数
*/
private static BigDecimal Flag = new BigDecimal(-1);
/**
* 代表0
*/
private static BigDecimal ZERO = new BigDecimal(0);
/**
* 输入数据最大行数
*/
private static int MaxLine = 25;
/**
* <解析为BigDecimal>
* @param input
* @return
*/
private static BigDecimal parse(String input) {
if (input.equals("?")) {
return Flag;
}
else if (input.equals("0.00") || input.equals("0")) {
return ZERO;
}
return new BigDecimal(input);
}
/**
* <处理单行信息>
* @param line
* @return
*/
private static BigDecimal[] parseLine(String line) {
String[] strs = line.split(";");
if( strs.length != 4){
return null;
}
BigDecimal[] out = null;
try{
BigDecimal income = parse(strs[1]);
BigDecimal payout = parse(strs[2]);
BigDecimal balance = parse(strs[3]);
if (income != Flag && income != ZERO && payout == Flag)
payout = ZERO;
else if (payout != Flag && payout != ZERO && income == Flag)
income = ZERO;
out = new BigDecimal[]
{income, payout, balance};
}catch(Exception e){
return null;
}
return out;
}
/**
* <格式化输出>
* @param f
* @return
*/
public static String show(BigDecimal f) {
if (f == Flag) {
return "?";
}
else if (f == ZERO) {
return "0.00";
}
else {
return f.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
}
}
/**
* <处理当前行及上一行余额已知,且当前行中存在2个未知数情形>
* @param datas
* @param currentLineBalanceIndex
*/
private static void doCaseOne(BigDecimal[] datas, int currentLineBalanceIndex) {
BigDecimal diff = datas[currentLineBalanceIndex].subtract(datas[currentLineBalanceIndex - 3]);
if (diff.signum() == -1) {
datas[currentLineBalanceIndex - 1] = diff.negate();
datas[currentLineBalanceIndex - 2] = ZERO;
}
else {
datas[currentLineBalanceIndex - 2] = diff;
datas[currentLineBalanceIndex - 1] = ZERO;
}
}
public static void main(String[] args) throws IOException {
Scanner cin = new Scanner(System.in);
String lineStr = null;
BigDecimal[] datas = new BigDecimal[MaxLine * 3 + 1];//存放收入,支出,余额数据,从下标为1开始存
String[] idStrs = new String[MaxLine + 1];//存放每行编号信息,从下标为1开始存
int[] lineMisCount = new int[MaxLine + 1];//存放每行未知数总数,从下标为1开始存,可为0-3之间的值
int lineCount = 1;//已读取行数统计
int dataCount = 1;//已读取数据统计
int misCount = 0;//未知数统计
String firstLineStr = null;
while (cin.hasNext() && lineCount < MaxLine + 1) {
if (firstLineStr == null) {//表头
firstLineStr = cin.nextLine();
continue;
}
lineStr = cin.nextLine();
BigDecimal[] d = parseLine(lineStr);
if(d == null){
continue;
}
idStrs[lineCount] = lineStr.substring(0, lineStr.indexOf(";"));
int lineMis = 0;
for (BigDecimal t : d) {
if (t == Flag) {
misCount++;
lineMis++;
}
}
lineMisCount[lineCount] = lineMis;
datas[dataCount++] = d[0];
datas[dataCount++] = d[1];
datas[dataCount++] = d[2];
if (lineCount >= 2 && misCount > 0) {//从第二行起,每读一行,循环去倒推当前行及上一行中的未知数
for (int i = lineCount; i > 1 && misCount > 0; i--) {
//==========断层情况开始============
if (lineMisCount[i] == 3) {//当前行中三个数未知,将无法倒推出前面所有行中的数据,直接跳出循环,断层原理
break;
}
int index = i * 3;//当前行对应的余额下标
if (lineMisCount[i - 1] == 0) {//上一行数据全部已知,则最多只能推出本行的未知数据,断层原理
if (lineMisCount[i] == 1) {
if (datas[index] == Flag) {//形如 100.00 0.00 ? 形式
datas[index] = datas[index - 3].add(datas[index - 2].subtract(datas[index - 1]));
}
else {//形如 ? 0.00 100.00 或 0.00 ? 100.00形式
BigDecimal diff = datas[index].subtract(datas[index - 3]);
if (diff.signum() == -1)
datas[index - 1] = diff.negate();
else
datas[index - 2] = diff;
}
lineMisCount[i]--;
misCount--;
}
else if (lineMisCount[i] == 2) {
if (datas[index] != Flag) {//形如 ? ? 100.00形式
doCaseOne(datas, index);
lineMisCount[i] = 0;
misCount -= 2;
}
}//其它 80.00 0.00 100.00 及 ? ? ? 这两种情况不考虑,前一种没有未知数据,后一种情况,根据之前的判断,不可能出现
break;
}
//==========断层情况结束============
if (lineMisCount[i] == 0) {//当前行数据全部已知
if (datas[index - 3] == Flag) {//推出上一行中的余额
datas[index - 3] = datas[index].add(datas[index - 1]).subtract(datas[index - 2]);
lineMisCount[i - 1]--;
misCount--;
}
continue;
}
if (lineMisCount[i] == 2) {//当前行两个未知数
if (datas[index] != Flag && datas[index - 3] != Flag) {//形如 ? ? 100.00形式 及上一行的 x x 100.00形式
doCaseOne(datas, index);
lineMisCount[i] = 0;
misCount -= 2;
}//其它情况既无法推出本行未知数,也无法推出上一行的未知数
continue;
}
if (lineMisCount[i] == 1) {//当前行一个未知数
if (datas[index - 3] != Flag) {//只有上一行余额已知时才能推导出本行未知数
if (datas[index - 1] == Flag) {
datas[index - 1] = datas[index - 3].subtract(datas[index]);
}
else if (datas[index - 2] == Flag) {
datas[index - 2] = datas[index].subtract(datas[index - 3]);
}
else {
datas[index] = datas[index - 3].add(datas[index - 2]).subtract(datas[index - 1]);
}
lineMisCount[i] = 0;
misCount--;
}
}
}
}
lineCount++;
}
lineCount--;
int size = lineCount * 3;
if (firstLineStr != null) {
System.out.println(firstLineStr);//输出表头
}
for (int i = 1; i <= size; i += 3) {
int lineNum = i / 3 + 1;
System.out.println(idStrs[lineNum] + ";" + show(datas[i]) + ";" + show(datas[i + 1]) + ";"
+ show(datas[i + 2]));
}
cin.close();
}
}
上面用的是BigDecimal来存放数据,个人觉得用double存也是可以的。
版权声明:本文为博主原创文章,未经博主允许不得转载。
分享到:
相关推荐
Java笔试题是评估应聘者Java编程能力的一种常见方式,尤其在技术驱动的公司如平安科技中,这样的测试显得尤为重要。平安科技作为一家领先的金融科技企业,对Java开发人员的专业技能有着高标准的要求。以下是一些可能...
【智能金融】平安银行零售科技CTO在AI研发过程中提出的「二三五」原则,主要聚焦于大数据平台的建设和应用,以及AI技术在金融领域的实践。这位CTO,储量,强调了技术与业务的结合,以及平台支撑和数据管理的重要性。...
【标题】"平安科技开发试题汇总"所涉及的知识点涵盖了Java开发的核心技术和面试常见问题,主要针对的是在平安科技公司进行Java开发岗位面试的求职者。以下是对这些知识点的详细阐述: 1. **Java基础**:Java语言是...
#### 一、平安科技技术岗位薪酬体系与福利待遇 根据平安科技的需求JD文档,平安科技对于不同层级的技术人员设置了明确的薪酬范围,并提供了丰厚的福利待遇。 1. **薪酬标准**: - 对标P6/P6+层级的岗位,月薪范围...
平安科技所提出的“平安深度学习云”和“平安异构计算云”正是基于这样的设计理念,依托于分布式异构计算平台,利用强大的云计算能力,加速深度学习的计算过程,确保深度学习服务的高效与可靠。 在演讲中,夏磊豪还...
【中国平安励志计划创业大赛】是中国青少年发展基金会与平安保险集团联合举办的年度创业竞赛,旨在提升大学生的创业和就业能力,增强他们的创业信心,并为他们的创新想法提供展示平台。大赛自2011年7月至12月进行,...
这份报告对于理解当时及未来一段时间内,平安私人银行的投资策略,以及对整个银行业的投资趋势分析具有重要的参考价值。 首先,报告可能会详细分析2020年全球及中国的经济环境。2020年正处于COVID-19疫情的冲击之下...
《平安科技AIOPS建设实践分享》 在当今的数字化时代,运维自动化与智能化的重要性日益凸显。AIOPS(Artificial Intelligence for IT Operations)作为这一领域的前沿技术,正逐步改变着传统IT运维模式。平安科技...
### 平安科技Java一百道面试题解析 #### 基础知识问题解析 ##### 1. JSP九个内置对象及其作用 JSP(JavaServer Pages)是一种用于创建动态网页的技术,它允许开发者在HTML代码中嵌入Java代码。JSP提供了九个内置...
Java 平安科技宝典包含了多个关于 Java 编程、数据库操作、ORM 框架以及软件设计原则的问题。以下是对这些知识点的详细说明: 1. **类的加载与继承**: - 在题目1中,`A` 和 `B` 类的静态块先于实例化执行,因此...
平安科技在精益看板的研发实践中,逐步推动了价值的拉动和持续改进。这个过程始于2011年,当时平安科技作为国际领先的“互联网+综合金融”高科技提供商,拥有28年的科技、互联网和金融经验,专注于大数据、云平台和...
根据提供的文件信息,我们可以推断出这份文档主要讨论的是关于中国开放银行的发展情况与趋势分析。下面将基于标题、描述以及部分展示的内容来提炼出关键的知识点。 ### 知识点一:开放银行的基本概念 开放银行...
20201218-平安银行-银行业:平安私人银行2021年第一季度投资策略报告.pdf
【文档描述】:“这是一份教育精品资料,详细介绍了2010年广州中医药大学金融理财协会举办的第三届模拟炒股大赛,旨在为大学生提供股票市场的实践平台。” 【文档标签】:“教育精品资料” 【文档部分内容】:文档...
【平安证券】计算机行业周报:合肥就促进低空经济产业高质量发展征求意见,国产3A游戏《黑神话:悟空》正式上线.pdf【平安证券】计算机行业周报:合肥就促进低空经济产业高质量发展征求意见,国产3A游戏《黑神话:...
蚂蚁集团(原蚂蚁金服)利用金融科技推动普惠金融,而中国平安则通过“金融+科技”策略打造生态圈,其保险科技业务对外销售,实现双重效益。腾讯控股则在金融领域逐步发力,支付业务带动其全牌照布局。 尽管如此,...
为此,广州中医药大学金融理财协会联合广东药学院职业生涯规划与发展协会,共同举办“平安银行杯模拟炒股大赛”,旨在为学生们提供一个接触股票市场的平台。 - **举办目的**: - 活跃校园氛围,丰富校园文化生活; ...
平安科技AIOPS建设实践分享.pdf
20200923-平安银行-银行业:平安私人银行2020年第四季度投资策略报告.pdf
标题"行业-银行行业周报:平安银行一季报打响银行业“头炮”"揭示了这是关于银行行业的周度报告,重点聚焦平安银行的一季度业绩发布。"头炮"这个词形象地表示平安银行的一季报可能是银行业整体业绩的一个亮点或开局...