Java 如何优化此代码以减少计算时间
我在解决一个问题,这个问题要求我打印一个整数数组中的所有数字,其中包含1,2,3。例如,一个包含[123300,456789]的数组将输出为[123300]。 在我的代码中,我使用了ArrayList和所有需要解决它的东西。不过,评估时间还没有达到标准Java 如何优化此代码以减少计算时间,java,algorithm,Java,Algorithm,我在解决一个问题,这个问题要求我打印一个整数数组中的所有数字,其中包含1,2,3。例如,一个包含[123300,456789]的数组将输出为[123300]。 在我的代码中,我使用了ArrayList和所有需要解决它的东西。不过,评估时间还没有达到标准 public static void take(int[] a) { ArrayList<Integer> ai = new ArrayList<>(); for(int i=0; i<a.leng
public static void take(int[] a)
{
ArrayList<Integer> ai = new ArrayList<>();
for(int i=0; i<a.length;i++)
{
int temp =a[i];
while(a[i]>0)
{
int b=a[i]%10;
if(b==1||b==2||b==3)
{
ai.add(temp);
break;
}
a[i]= a[i]/10;
}
}
if(ai.isEmpty())
{
System.out.println(-1);
}
else
{
ai.sort(null);
System.out.println(ai);
}
}
public static void main(String[] args)
{
Scanner mew = new Scanner(System.in);
int t=mew.nextInt();
for(int i=0; i<t;i++)
{
int n=mew.nextInt();
int a[] = new int[n];
for(int j=0; j<n;j++)
{
a[j] = mew.nextInt();
}
take(a);
}
}
publicstaticvoidtake(int[]a)
{
ArrayList ai=新的ArrayList();
对于(int i=0;i0)
{
int b=a[i]%10;
如果(b==1 | | b==2 | | b==3)
{
ai.添加(临时);
打破
}
a[i]=a[i]/10;
}
}
if(ai.isEmpty())
{
系统输出打印项数(-1);
}
其他的
{
ai.sort(空);
系统输出打印LN(ai);
}
}
公共静态void main(字符串[]args)
{
扫描器mew=新扫描器(System.in);
int t=mew.nextInt();
对于(int i=0;i您只需将数字
转换为字符串;检索所有字符,并使用Set
检查所需字符是否存在:
public static Set<Integer> take(int[] a, char[] markers) {
Set<Integer> numbers = new TreeSet<>();
for (int i = 0; i < a.length; i++) {
String str = String.valueOf(a[i]);
for (char marker : markers) {
if (str.contains(String.valueOf(marker))) {
numbers.add(a[i]);
break;
}
}
}
return numbers;
}
publicstaticset-take(int[]a,char[]markers){
设置编号=新树集();
for(int i=0;i
作为替代方案,您可以使用流:
public static Set<Integer> take(int[] a, char[] markers) {
return Arrays.stream(a)
.boxed()
.filter(val -> {
String str = String.valueOf(val);
for (char marker : markers)
if (str.contains(String.valueOf(marker)))
return true;
return false;
})
.sorted()
.collect(Collectors.toSet());
}
publicstaticset-take(int[]a,char[]markers){
返回数组.stream(a)
.boxed()
.filter(val->{
String str=String.valueOf(val);
用于(字符标记:标记)
if(str.contains(String.valueOf(marker)))
返回true;
返回false;
})
.已排序()
.collect(收集器.toSet());
}
对此使用哈希。。。
使用键1、2和3创建hashmap。如果我理解正确,那么许多数字将被删除。如果数字1、2或3至少出现一次,您希望通过文本搜索。您可以使用如下正则表达式执行此操作:
import java.util.*;
public class So {
public static void searchForNumbers(int[] sourceArray) {
System.out.println("source array = " + Arrays.toString(sourceArray));
List<Integer> ai = new ArrayList<>();
for (int i = 0; i < sourceArray.length; i++) {
if( Integer.toString(sourceArray[i]).matches(".*[1-3].*")) {
ai.add(sourceArray[i]);
}
}
if (ai.isEmpty()) {
System.out.println(-1);
} else {
ai.sort(Comparator.naturalOrder());
System.out.println(ai);
}
}
public static void main(String[] args) {
Scanner mew = new Scanner(System.in);
int numberOfTimesToAskForNumbers = mew.nextInt();
System.out.println("numberOfTimesToAskForNumbers = " + numberOfTimesToAskForNumbers);
for (int i = 0; i < numberOfTimesToAskForNumbers; i++) {
int amountOfNumbersInThisRound = mew.nextInt();
System.out.println("amountOfNumbersInThisRound = " + amountOfNumbersInThisRound);
int a[] = new int[amountOfNumbersInThisRound];
for (int j = 0; j < amountOfNumbersInThisRound; j++) {
a[j] = mew.nextInt();
System.out.println("a[j] = " + a[j]);
}
searchForNumbers(a);
}
}
}
import java.util.*;
公开课{
公共静态void searchForNumbers(int[]sourceArray){
System.out.println(“源数组=“+Arrays.toString(sourceArray));
列表ai=新的ArrayList();
for(int i=0;i
我还重新命名了变量,使其更加清晰,并添加了额外的打印输出,以便在命令行的交互过程中获得反馈
旁注:像这样的事情真的应该通过单元测试来测试,以确保所有情况都正常,而不必一直手动键入内容进行测试。您的目标过于复杂。效率的第一条规则是“避免做额外的工作”。以下是代码工作过度的地方:
- 您从输入中读取字符,将其解析为整数,然后将数字重新分解为数字,以对照1、2和3检查每个字符
- 构建候选数组,然后测试数组的每个元素,但不需要数组本身,因为您只对通过1-2-3测试的候选对象感兴趣
我下面的代码避免了额外的工作,并使用稍微更有效的测试来检查1、2或3的存在。这将导致显著的加速:
import java.util.*;
public class J {
public static boolean has1or2or3(String s) {
for (char c : s.toCharArray())
if (c >= '1' && c <= '3') return true;
return false;
}
public static void solve(Scanner in) {
int cases = in.nextInt();
while (cases-- > 0) {
// read input, solve problem
ArrayList<Integer> good = new ArrayList<>();
int count = in.nextInt();
for (int i=0; i<count; i++) {
String candidate = in.next();
if (has1or2or3(candidate)) {
good.add(Integer.parseInt(candidate));
}
}
// generate output
if (good.isEmpty()) {
System.out.println(-1);
} else {
Collections.sort(good);
for (int c : good) {
System.out.print(c + " ");
}
System.out.println();
}
}
}
public static void main(String[] args) {
try (Scanner in = new Scanner(System.in)) {
solve(in);
}
}
}
问:你说的“不合格”到底是什么意思?到目前为止,您采用了什么计时方式?建议:尝试一个简单的循环,将每个数字转换为字符串,并检查字符“1”、“2”或“3”。将计时方式与原始版本进行比较。是否需要排序?如果您的代码工作正常且速度有点慢,您可能应该尝试codereview.stackexchange.comNot Up the mark meanin我想你可以把这个和另一个答案结合起来,使用.filter(str->str.matches(“.[1-3].]))
谢谢,这是一个很好的解决方案,但我的问题并不是针对这个问题的。我可以知道如何减少解决方案的编译时间,就像一些基本规则一样吗?就效率而言,流和额外的数据结构(如集合)是多余的。可读性当然会提高,但这并不是最初的目标。如果时间是在一个premium,正则表达式比单个字符传递慢。即使JVM以后可能会对其进行优化,他们也需要在前10k左右的迭代中编译和执行正则表达式。构建hashmap不是答案。虽然它可以工作,但数字的hashmap比大小为10的int数组便宜得多。而且,因为我们只对查找无论是1、2还是3,你都不需要数组。当你需要高效的代码时,使用额外的数据结构并不需要数组
1
6
4567 345 1122 89458 8495 473
345 473 1122