”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > Java程序从给定堆栈中删除重复项

Java程序从给定堆栈中删除重复项

发布于2024-09-02
浏览:737

在本文中,我们将探讨两种在 Java 中从堆栈中删除重复元素的方法。我们将比较使用嵌套循环的简单方法和使用 HashSet 的更有效方法。目标是演示如何优化重复删除并评估每种方法的性能。

问题陈述

编写一个Java程序,从堆栈中删除重复元素。

输入

Stack data = 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

要从给定堆栈中删除重复项,我们有两种方法 -

  • 天真的方法:创建两个嵌套循环来查看哪些元素已经存在并防止将它们添加到结果堆栈返回中。
  • HashSet方法:使用Set来存储唯一元素,并利用其O(1)复杂度来检查元素是否存在。

生成和克隆随机堆栈

下面是 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 方法从给定堆栈中删除重复项的步骤 -

  • 启动计时器。
  • 创建一个空堆栈来存储唯一元素。
  • 使用while循环迭代并继续,直到原始堆栈为空弹出顶部元素。
  • 使用 resultStack.contains(element) 检查重复项以查看该元素是否已在结果堆栈中。
  • 如果该元素不在结果栈中,则将其添加到结果栈中。
  • 记录结束时间并计算总花费时间。
  • 返回结果

例子

下面是使用 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) 从给定堆栈中删除重复项

以下是使用优化方法从给定堆栈中删除重复项的步骤 -

  • 启动计时器
  • 创建一个 Set 来跟踪看到的元素(用于 O(1) 复杂性检查)。
  • 创建临时堆栈来存储唯一元素。
  • 使用 while循环进行迭代,直到堆栈为空。
  • 从堆栈中移除顶部元素。
  • 要检查重复项,我们将使用 seen.contains(element) 来检查该元素是否已在集合中。
  • 如果该元素不在集合中,则将其添加到可见堆栈和临时堆栈中。
  • 记录结束时间并计算总花费时间。
  • 返回结果

例子

下面是使用 HashSet 从给定堆栈中删除重复项的 Java 程序 -

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.println("Time spent for idea2 is %d nanosecond".formatted(System.nanoTime() - start));
    return tempStack;
}

对于优化方法,我们使用

Set seen
存储Set中的唯一元素,在访问随机元素时利用O(1)复杂度来减少检查元素是否存在。

结合使用两种方法

以下是使用上述两种方法从给定堆栈中删除重复项的步骤 -

  • 初始化数据,我们使用initData(Long size)方法创建一个充满随机整数的堆栈。
  • 克隆堆栈我们使用 cloneStack(Stack stack) 方法 来创建原始堆栈的精确副本。
  • 使用initData.
  • 生成初始堆栈
  • 使用 cloneStack 克隆此堆栈。
  • 应用朴素方法从原始堆栈中删除重复项。
  • 应用优化方法从克隆堆栈中删除重复项。
  • 显示每种方法所花费的时间以及两种方法产生的独特元素

例子

下面是使用上述两种方法从堆栈中删除重复元素的 Java 程序 -

import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.Stack;

public class DuplicateStackElements {
    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  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));
    }
}

输出

Java program to remove duplicates from a given stack


比较

* 测量单位是纳秒。

public static void main(String[] args) {
    Stack data1 = 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)。所以,当堆栈数量增加时,计算所花费的时间也会在此基础上增加。


版本声明 本文转载于:https://www.tutorialspoint.com/java-program-to-remove-duplicates-from-a-given-stack如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在C#中如何高效重复字符串字符用于缩进?
    在C#中如何高效重复字符串字符用于缩进?
    在基于项目的深度下固定字符串时,重复一个字符串以进行凹痕,很方便有效地有一种有效的方法来返回字符串重复指定的次数的字符串。使用指定的次数。 constructor 这将返回字符串“ -----”。 字符串凹痕= new String(' - ',depth); console.Wr...
    编程 发布于2025-04-18
  • 查找当前执行JavaScript的脚本元素方法
    查找当前执行JavaScript的脚本元素方法
    如何引用当前执行脚本的脚本元素在某些方案中理解问题在某些方案中,开发人员可能需要将其他脚本动态加载其他脚本。但是,如果Head Element尚未完全渲染,则使用document.getElementsbytagname('head')[0] .appendChild(v)的常规方...
    编程 发布于2025-04-18
  • 如何克服PHP的功能重新定义限制?
    如何克服PHP的功能重新定义限制?
    克服PHP的函数重新定义限制在PHP中,多次定义一个相同名称的函数是一个no-no。尝试这样做,如提供的代码段所示,将导致可怕的“不能重新列出”错误。 但是,PHP工具腰带中有一个隐藏的宝石:runkit扩展。它使您能够灵活地重新定义函数。 runkit_function_renction_re...
    编程 发布于2025-04-18
  • 在Python中如何创建动态变量?
    在Python中如何创建动态变量?
    在Python 中,动态创建变量的功能可以是一种强大的工具,尤其是在使用复杂的数据结构或算法时,Dynamic Variable Creation的动态变量创建。 Python提供了几种创造性的方法来实现这一目标。利用dictionaries 一种有效的方法是利用字典。字典允许您动态创建密钥并分...
    编程 发布于2025-04-18
  • 使用jQuery如何有效修改":after"伪元素的CSS属性?
    使用jQuery如何有效修改":after"伪元素的CSS属性?
    在jquery中了解伪元素的限制:访问“ selector 尝试修改“:”选择器的CSS属性时,您可能会遇到困难。 This is because pseudo-elements are not part of the DOM (Document Object Model) and are th...
    编程 发布于2025-04-18
  • FastAPI自定义404页面创建指南
    FastAPI自定义404页面创建指南
    response = await call_next(request) if response.status_code == 404: return RedirectResponse("https://fastapi.tiangolo.com") else: ...
    编程 发布于2025-04-18
  • 如何同步迭代并从PHP中的两个等级阵列打印值?
    如何同步迭代并从PHP中的两个等级阵列打印值?
    同步的迭代和打印值来自相同大小的两个数组使用两个数组相等大小的selectbox时,一个包含country代码的数组,另一个包含乡村代码,另一个包含其相应名称的数组,可能会因不当提供了exply for for for the uncore for the forsion for for ytry...
    编程 发布于2025-04-18
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 考虑文档中给出的示例:这是内部发生的事情: 现在在3月3日添加另一个月,因为2月在2001年只有2...
    编程 发布于2025-04-18
  • 如何在Java的全屏独家模式下处理用户输入?
    如何在Java的全屏独家模式下处理用户输入?
    Handling User Input in Full Screen Exclusive Mode in JavaIntroductionWhen running a Java application in full screen exclusive mode, the usual event ha...
    编程 发布于2025-04-18
  • 如何实时捕获和流媒体以进行聊天机器人命令执行?
    如何实时捕获和流媒体以进行聊天机器人命令执行?
    在开发能够执行命令的chatbots的领域中,实时从命令执行实时捕获Stdout,一个常见的需求是能够检索和显示标准输出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    编程 发布于2025-04-18
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-04-18
  • Java的Map.Entry和SimpleEntry如何简化键值对管理?
    Java的Map.Entry和SimpleEntry如何简化键值对管理?
    A Comprehensive Collection for Value Pairs: Introducing Java's Map.Entry and SimpleEntryIn Java, when defining a collection where each element com...
    编程 发布于2025-04-18
  • 在不同操作系统中获取当前用户名的方法
    在不同操作系统中获取当前用户名的方法
    检索当前用户名:一种跨平台方法在使用各种操作系统时,对于无缝地检索当前用户的用户名是必不可少的。类似于熟悉的OS.GetUid()用于用户标识的函数,我们寻求一个独立于平台的解决方案。此方法提供了与UNIX和Windows操作系统的兼容性,从而满足了我们对可移植性的要求。值得注意的是,根据注释,g...
    编程 发布于2025-04-18
  • 版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    版本5.6.5之前,使用current_timestamp与时间戳列的current_timestamp与时间戳列有什么限制?
    在时间戳列上使用current_timestamp或MySQL版本中的current_timestamp或在5.6.5 此限制源于遗留实现的关注,这些限制需要对当前的_timestamp功能进行特定的实现。 创建表`foo`( `Productid` int(10)unsigned not n...
    编程 发布于2025-04-18
  • eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    称量()和ast.literal_eval()中的Python Security 在使用用户输入时,必须优先确保安全性。强大的python功能eval()通常是作为潜在解决方案而出现的,但担心其潜在风险。 This article delves into the differences betwee...
    编程 发布于2025-04-18

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3