我想用Java编写一个程序,给定一个数组,可以找到数组中所有数字的总和-例外!由于数字13非常不幸,我建议我们将数字13以及在数字13之后的数字直接排除在总数之外。
该程序(我将称为import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
public class MergePdfUtility {
FormDataBean formData = null;
public String mergePdf(String contentType, int formDataLength, HttpServletRequest request) {
String saveFile = new String();
String strUploadFile = "";
File flUploadFile = null;
formData = new FormDataBean();
FileOutputStream fileout = null;
BufferedOutputStream bout = null;
BufferedInputStream bin = null;
String strStatusMsg;
InputStream inputStream1 = null;
InputStream inputStream2 = null;
InputStream inputStream3 = null;
InputStream inputStream4 = null;
InputStream inputStream5 = null;
try {
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
List<InputStream> list = new ArrayList<InputStream>();
//List<InputStream> finalList = new ArrayList<InputStream>();
for (FileItem item : items) {
if (item.isFormField()) {
String fieldname = item.getFieldName();
String fieldvalue = item.getString() + ".pdf";
if (fieldvalue == null || fieldvalue.length() == 0 || fieldvalue.equals(".pdf")) {
fieldvalue = "Merger.pdf";
}
System.out.println("Field Value = " + fieldvalue);
if (fieldname.equals("txtFileName")) {
formData.setStrFileName(fieldvalue);
System.out.println("successfully assigned");
}
} else {
saveFile = FilenameUtils.getName(item.getName());
if (saveFile.endsWith(".pdf")) {
String strFieldName = item.getFieldName();
System.out.println(saveFile);
contentType = item.getContentType();
strUploadFile = "D:\\Samik\\BCP\\" + saveFile;
flUploadFile = new File(strUploadFile);
fileout = new FileOutputStream(flUploadFile);
bin = new BufferedInputStream(item.getInputStream());
bout = new BufferedOutputStream(fileout);
int byte_;
while ((byte_ = bin.read()) != -1) {
bout.write(byte_);
}
bout.flush();
bout.close();
//bin.close();
if(strFieldName.endsWith("1")) {
inputStream1 = new FileInputStream(flUploadFile);
list.add(inputStream1);
formData.setFile1(flUploadFile);
} else if(strFieldName.endsWith("2")) {
inputStream2 = new FileInputStream(flUploadFile);
list.add(inputStream2);
formData.setFile2(flUploadFile);
}
else if(strFieldName.endsWith("3")) {
inputStream3 = new FileInputStream(flUploadFile);
list.add(inputStream3);
formData.setFile3(flUploadFile);
}
else if(strFieldName.endsWith("4")) {
inputStream4 = new FileInputStream(flUploadFile);
list.add(inputStream4);
formData.setFile4(flUploadFile);
}
else if(strFieldName.endsWith("5")) {
inputStream5 = new FileInputStream(flUploadFile);
list.add(inputStream5);
formData.setFile5(flUploadFile);
}
}
}
}
mergePdf(list, formData);
System.out.println("Finishing the main method");
if(flUploadFile != null) {
flUploadFile.delete();
}
strStatusMsg = "success";
} catch (Exception e) {
e.printStackTrace();
strStatusMsg = "failure";
}
return strStatusMsg;
}
private static void mergePdf(List<InputStream> list, FormDataBean formData) {
OutputStream mergeOutputStream = null;
Document document = null;
try {
mergeOutputStream = new FileOutputStream(new File("D:\\Samik\\BCP\\" + formData.getStrFileName()));
document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, mergeOutputStream);
document.open();
PdfContentByte pdfContentByte = pdfWriter.getDirectContent();
for (InputStream tempInputStream : list) {
PdfReader pdfReader = new PdfReader(tempInputStream);
for (int i = 1; i <= pdfReader.getNumberOfPages(); i++) {
document.newPage();
PdfImportedPage page = pdfWriter.getImportedPage(pdfReader, i);
pdfContentByte.addTemplate(page, 0, 0);
}
tempInputStream.close();
pdfReader.close();
}
System.out.println("Merging completed");
deleteFiles(formData);
pdfWriter.flush();
pdfWriter.close();
} catch (DocumentException | IOException e) {
try {
throw e;
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {
try {
if (mergeOutputStream != null) {
mergeOutputStream.close();
}
if (document != null) {
document.close();
}
System.out.println("Exiting the method");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
private static void deleteFiles(FormDataBean formData) throws IOException, FileNotFoundException {
if(formData.getFile1()!=null) {
formData.getFile1().delete();
}
if(formData.getFile2()!=null) {
formData.getFile2().delete();
}
if(formData.getFile3()!=null) {
formData.getFile3().delete();
}
if(formData.getFile4()!=null) {
formData.getFile4().delete();
}
if(formData.getFile5()!=null) {
formData.getFile5().delete();
}
}
}
)应从以下输入(以下仅作为示例)产生以下结果:
sum13
这是正常现象;这里没有13。
sum13([1,2,2,1]) = 6
排除了13号和13号之后的数字。
sum13([5, 13, 2]) = 5
该数组仅包含13个,因此都不包含。
sum13([13, 13]) = 0
预期输出的稍长示例。
这是我为sum13([1, 2, 13, 2, 1, 13]) = 4
想到的代码:
sum13
上面的程序可以运行,尽管看起来确实很乱!
有没有更好的方式编写这样一个不包含多个循环和嵌套public int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
// we start by adding all the non-13s to the sum
if (nums[i] != 13) sum += nums[i];
}
// now we go back and remove all the non-13s directly after a 13
for (int j = 0; j < nums.length; j++) {
// the outermost loop checks if the numbers are a 13
if (nums[j] == 13 && j < nums.length - 1) {
for (int k = j + 1; k < nums.length; k++) {
// this loop checks that the number after the 13 is not a 13
if (nums[k] != 13) {
sum -= nums[k];
break;
}
}
}
}
return sum;
}
的程序?
答案 0 :(得分:9)
好吧,您使用i作为迭代器。只需在当前数字为13时输入i++
。这样,不仅您不将13加到总和上,而且还跳过了下一个值。
public int sum13(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; i++) {
// we start by adding all the non-13s to the sum
if (nums[i] != 13){
sum += nums[i];
}
else {
i++;
}
}
return sum;
}
答案 1 :(得分:5)
Kepotx shows如何使用传统的for
循环进行操作。您还可以在增强的for
循环中使用标志来完成此操作:
public int sum13(int[] nums) {
int sum = 0;
boolean skipNext = false;
for (int num : nums) {
if (num == 13) {
skipNext = true;
} else {
if (!skipNext) {
sum += num;
}
skipNext = false;
}
}
return sum;
}
Live Example,其中包含提供的输入和预期的输出。
希望有精通流的人向我们展示了聪明的流方法... :-) ...和Malte Hartwig did(尽管他说过,那里没有最佳实践)。
答案 2 :(得分:3)
使用AtomicBoolean
可以大大缩短循环时间,当您使用IntStream
求和时,它甚至更短:
public static int sum13(int[] numbers)
{
AtomicBoolean was13 = new AtomicBoolean(false);
return IntStream.of(numbers)
.filter(i -> !was13.getAndSet(i == 13) && i != 13)
.sum();
}
最大的优点是AtomicBoolean.getAndSet(boolean)
允许我们检查以前的数字是否为13,并同时存储当前的数字是否为13。
警告:正如Hulk在评论中指出的那样,并不是在流“外部”更改对象状态的最佳实践。例如,如果您尝试并行使用流,这可能会困扰您。可以避免在此处使用自定义Collector
使用外部状态,但是对于这个特定问题,这会使代码变得过于复杂。
答案 3 :(得分:0)
数字13到达后,您需要跳过循环中的13和下一个字符
public class HelloWorld{
public static void main(String []args){
int arr[] = {1, 2, 4, 2, 1, 13,10};
System.out.println(sum13(arr));
}
public static int sum13(int[] nums) {
int sum = 0;
int n = nums.length;
for (int i = 0; i < n; i++) {
if (nums[i] == 13){
i=i+2;
}
if(i<n){
sum += nums[i];
}
}
return sum;
}
}
答案 4 :(得分:0)
为什么不使用ArrayList类?它实现了iterator()方法,代码可能如下所示:
int sum13 (ArrayList<Integer> a) {
Iterator<Integer> iter = a.iterator();
int n;
int sum=0;
while (iter.hasNext() ) {
n = iter.next();
if (n !=13)
sum = sum + n; /* n!=13 it will be added*/
else if (iter.hasNext() )
iter.next() /* n==13 not summing and skipping next */
}
return sum;
}