在本文中,我们将探讨两种在 Java 中从堆栈中删除重复元素的方法。我们将比较使用嵌套循环的简单方法和使用 HashSet 的更有效方法。目标是演示如何优化重复删除并评估每种方法的性能。
编写一个Java程序,从堆栈中删除重复元素。
输入
Stackdata = initData(10L);
输出
Unique elements using Naive Approach: [1, 4, 3, 2, 8, 7, 5] Time spent for Naive Approach: 18200 nanoseconds Unique elements using Optimized Approach: [1, 4, 3, 2, 8, 7, 5] Time spent for Optimized Approach: 34800 nanoseconds
要从给定堆栈中删除重复项,我们有两种方法 -
下面是 Java 程序首先构建一个随机堆栈,然后创建它的副本以供进一步使用 -
private static Stack initData(Long size) { Stack stack = new Stack (); Random random = new Random(); int bound = (int) Math.ceil(size * 0.75); for (int i = 0; i manualCloneStack(Stack stack) { Stack newStack = new Stack (); for (Integer item: stack) { newStack.push(item); } return newStack; }
initData
帮助创建一个具有指定大小和范围从 1 到 100 的随机元素的 Stack。
manualCloneStack
通过从另一个堆栈复制数据来帮助生成数据,用它来比较两种想法的性能。
以下是使用 Naïve 方法从给定堆栈中删除重复项的步骤 -
下面是使用 Naïve 方法从给定堆栈中删除重复项的 Java 程序 -
public static Stack idea1(Stack stack) { long start = System.nanoTime(); Stack resultStack = new Stack (); while (!stack.isEmpty()) { int element = stack.pop(); if (!resultStack.contains(element)) { resultStack.add(element); } } System.out.println("Time spent for idea1 is %d nanosecond".formatted(System.nanoTime() - start)); return resultStack; }
对于朴素方法,我们使用
while (!stack.isEmpty())
处理第一个循环遍历堆栈中的所有元素,第二个循环是
resultStack.contains(element)
检查元素是否已存在。以下是使用优化方法从给定堆栈中删除重复项的步骤 -
下面是使用 HashSet 从给定堆栈中删除重复项的 Java 程序 -
public static Stackidea2(Stack stack) { long start = System.nanoTime(); Set seen = new HashSet(); Stack tempStack = new Stack(); while (!stack.isEmpty()) { int element = stack.pop(); if (!seen.contains(element)) { seen.add(element); tempStack.push(element); } } System.out.println("Time spent for idea2 is %d nanosecond".formatted(System.nanoTime() - start)); return tempStack; }
对于优化方法,我们使用
Set seen
存储Set中的唯一元素,在访问随机元素时利用O(1)复杂度来减少检查元素是否存在。
以下是使用上述两种方法从给定堆栈中删除重复项的步骤 -
下面是使用上述两种方法从堆栈中删除重复元素的 Java 程序 -
import java.util.HashSet; import java.util.Random; import java.util.Set; import java.util.Stack; public class DuplicateStackElements { private static StackinitData(Long size) { Stack stack = new Stack(); Random random = new Random(); int bound = (int) Math.ceil(size * 0.75); for (int i = 0; i cloneStack(Stack stack) { Stack newStack = new Stack(); newStack.addAll(stack); return newStack; } public static Stack idea1(Stack stack) { long start = System.nanoTime(); Stack resultStack = new Stack(); while (!stack.isEmpty()) { int element = stack.pop(); if (!resultStack.contains(element)) { resultStack.add(element); } } System.out.printf("Time spent for idea1 is %d nanoseconds%n", System.nanoTime() - start); return resultStack; } public static Stack idea2(Stack stack) { long start = System.nanoTime(); Set seen = new HashSet(); Stack tempStack = new Stack(); while (!stack.isEmpty()) { int element = stack.pop(); if (!seen.contains(element)) { seen.add(element); tempStack.push(element); } } System.out.printf("Time spent for idea2 is %d nanoseconds%n", System.nanoTime() - start); return tempStack; } public static void main(String[] args) { Stack data1 = initData(10L); Stack data2 = cloneStack(data1); System.out.println("Unique elements using idea1: " idea1(data1)); System.out.println("Unique elements using idea2: " idea2(data2)); } }
输出
* 测量单位是纳秒。
public static void main(String[] args) { Stackdata1 = initData( ); Stack data2 = manualCloneStack(data1); idea1(data1); idea2(data2); }
方法 | 100 个元素 | 1000 个元素 | 10000 个元素 |
100000 个元素 |
1000000 个元素 |
想法1 | 693100 |
4051600 |
19026900 |
114201800 |
1157256000 |
想法2 | 135800 |
681400 |
2717800 |
11489400 |
36456100 |
据观察,想法 2 的运行时间比想法 1 短,因为想法 1 的复杂度为 O(n²),而想法 2 的复杂度为 O(n)。所以,当堆栈数量增加时,计算所花费的时间也会在此基础上增加。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3