首页 > 其他分享 >每周总结第四周

每周总结第四周

时间:2023-06-09 22:12:25浏览次数:36  
标签:总结 String chain 每周 List longestChain 单词 words 四周

本周完成了算法作业:   课堂练习01题目:计算最长英语单词链。

一、题目内容:

大家经常玩成语接龙游戏,我们试一试英语的接龙吧:一个文本文件中有N 个不同的英语单词, 我们能否写一个程序,快速找出最长的能首尾相连的英语单词链,每个单词最多只能用一次。

最长的定义是:最多单词数量,和单词中字母的数量无关。

二、题目要求:

1、统一输入文件名称:input1.txt, input2.txt

2、统一输出文件名称:output1.txt,output2.txt

3、程序需要考虑下列异常状况:

(1)例如,文件不存在,你的程序会崩溃么,还是能优雅地退出并给用户提示信息?

(2)如果文件没有任何单词、只有一个单词、没有可以首尾相连的单词,程序应该如何输出?

(3)如果输入文件有一万个单词,你的程序能多快输出结果?

 

本题是一道比较经典的图论问题,可以使用回溯法或深度优先搜索来解决。具体来说,可以将单词看成图中的点,如果两个单词的首尾相连,则表示这两个单词之间有一条边,然后问题就转化成了求最长的链的问题。由于本题中最长的定义是最多单词数量,和单词中字母的数量无关,因此可以考虑使用深度优先搜索来解决。

具体算法如下:

  1. 读入单词列表,建立图结构。

  2. 对于每个单词,从该单词开始进行深度优先搜索,找到所有可以和该单词首尾相连的单词,标志已经被使用,并将该单词添加到单词链中。

  3. 每当找到一个新的单词链时,就和已有的单词链进行比较,更新最长单词链。

  4. 将最长单词链输出到文件中。

  5. 处理异常情况,例如文件不存在、文件没有单词、没有可以首尾相连的单词等等。           

 

import java.io.*;
import java.util.*;

public class LongestWordChain {
    public static void main(String[] args) {
        List<String> words = readWords("input.txt");
        List<String> longestChain = findLongestWordChain(words);
        if (longestChain.size() == 0) {
            System.out.println("No word chain found");
        } else {
            System.out.println("Longest word chain found with length " +
                    longestChain.size() + ": " + String.join(" -> ", longestChain));
            writeWords("output.txt", longestChain);
        }
    }

    public static List<String> readWords(String filename) {
        List<String> words = new ArrayList<>();
        try (Scanner scanner = new Scanner(new File(filename))) {
            while (scanner.hasNext()) {
                words.add(scanner.next());
            }
        } catch (FileNotFoundException e) {
            System.out.println("ERROR: File " + filename + " not found");
        }
        return words;
    }

    public static List<String> findLongestWordChain(List<String> words) {
        List<String> longestChain = new ArrayList<>();

        for (int i = 0; i < words.size(); i++) {
            String startWord = words.get(i);
            List<String> chain = new ArrayList<>();
            chain.add(startWord);
            Set<Integer> visited = new HashSet<>();
            visited.add(i);

            if (searchLongestChain(words, visited, chain, longestChain)) {
                longestChain = new ArrayList<>(chain);
            }
        }

        return longestChain;
    }

    public static boolean searchLongestChain(List<String> words, Set<Integer> visited,
                                              List<String> chain, List<String> longestChain) {
        boolean foundLongest = false;
        String lastWord = chain.get(chain.size() - 1);

        for (int i = 0; i < words.size(); i++) {
            if (!visited.contains(i)) {
                String nextWord = words.get(i);
                if (isConnected(lastWord, nextWord)) {
                    visited.add(i);
                    chain.add(nextWord);
                    foundLongest = searchLongestChain(words, visited, chain, longestChain);
                    chain.remove(chain.size() - 1);
                    visited.remove(i);
                }
            }
        }

        if (chain.size() > longestChain.size()) {
            foundLongest = true;
        }

        return foundLongest;
    }

    public static boolean isConnected(String word1, String word2) {
        if (word1.equals(word2)) {
            return false;
        }
        int len1 = word1.length();
        int len2 = word2.length();
        if (len1 + 1 != len2 && len1 != len2 + 1) {
            return false;
        }
        String shorter = len1 < len2 ? word1 : word2;
        String longer = len1 < len2 ? word2 : word1;
        boolean foundMismatch = false;
        for (int i = 0, j = 0; i < shorter.length(); i++, j++) {
            if (shorter.charAt(i) != longer.charAt(j)) {
                if (foundMismatch) {
                    return false;
                } else {
                    foundMismatch = true;
                    j++;
                }
            }
        }
        return true;
    }

    public static void writeWords(String filename, List<String> words) {
        try (PrintWriter writer = new PrintWriter(new File(filename))) {
            for (String word : words) {
                writer.println(word);
            }
        } catch (FileNotFoundException e) {
            System.out.println("ERROR: File " + filename + " cannot be opened for writing");
        }
    }
}

这个java程序包含了三个主要函数:

  • readWords 函数读取包含单词的文件,返回一个 String 列表。
  • findLongestWordChain 函数接受单词列表,返回最长的单词链。
  • writeWords 函数将最长单词链写入文件。

searchLongestChain 函数是递归实现的深度优先搜索,函数使用了 Set 类型存储访问过的单词的下标,用于加速访问和判断是否重复。在搜索中,如果找到一个长度更长的单词链,就将 longestChain 更新为当前单词链。

isConnected 函数用于判断两个单词是否可以首尾相连,这个函数的实现,使用了两个指针 i 和 j 分别在两个单词中移动,一旦发现不一致的字符数量超过 1,就返回 false。

此外,此程序也处理一些异常情况,例如文件不存在或无法打开,无法找到单词链,等等。

注意:使用 Java 时,需要先通过 import 语句导入需要使用的类,例如 Scanner 和 PrintWriter。在导入之后,就可以像上面的代码一样使用这些类来读写文件。

标签:总结,String,chain,每周,List,longestChain,单词,words,四周
From: https://www.cnblogs.com/sxwgzx23/p/17470351.html

相关文章

  • 【做题笔记】做题经验总结
    1.int*int会爆int,记得开longlong2.一般情况下,对于一棵树,树根没有父亲3.一定要看输入和输出格式4.多测不清空,爆零两行泪......
  • 接口总结
    接口框架:python+pytest+requests+logging+allure1、接口的参数化(数据驱动)将测试用到的数据从用例或代码中抽离保存到excel、csv中。程序运行时,pytest会自动调用test开头的yaml用例,yaml用例有个关键字parametrize:${read_xlsx(file_path)}会被执行。1、文件的读取:通过excel(xlsx)......
  • 学起总结
    作为一门计算机科学领域的重要学科,软件工程是为了开发高质量、可靠、可维护、可重用的软件而进行的。从最基本的概念、原则和方法到高级的工具和框架,软件工程的学习需要渗透一定的理论知识,了解开发实践,并理解业内的最佳实践和当前的趋势。在这篇总结中,我将分享我学习软件工程时所......
  • 第十六周总结
    在学习软件工程的过程中,我了解到以下几个关键概念和原则:软件开发生命周期:软件开发通常遵循一个生命周期,包括需求分析、设计、编码、测试和维护等阶段。每个阶段都有特定的目标和活动,并且它们之间有明确的交付物和依赖关系。需求工程:需求工程是软件开发的起点,它涉及与利益相关者......
  • 每周总结--第一周
    在本周我接触了安卓的基础学习,并且通过自学完成了一个每日打卡app每日打卡app源码alarmActivity,javapackagecom.example.myapp01;importandroidx.appcompat.app.AppCompatActivity;importandroid.os.Bundle;publicclassalarmActivityextendsAppCompatActivity{......
  • 第十六周总结
    packagecom.example.myapplication;importandroidx.appcompat.app.AlertDialog;importandroidx.appcompat.app.AppCompatActivity;importandroid.app.Activity;importandroid.content.Intent;importandroid.os.Bundle;importandroid.view.View;importandroid......
  • 第十五周总结
    <?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"......
  • MYSQL常用函数总结
    目录一、数学函数计算绝对值小数取整数字精度处理随机数(0~1)计算数字符号获取圆周率计算次方计算开平方计算除法取余计算对数角度<=>弧度三角函数计算进制转换二、字符串函数字符串长度字符拼接字符串大小写转换字符串截取复杂截取指定位置与长度的字符替换字符串替换字符串填充......
  • 算法题总结-找零钱
    原题给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。如果无解,请返回-1.数据范围:数组大小满足0\len\le100000≤n≤10000,数组中每个数字都满足0<val\le10000......
  • Linux 命令总结
    实用Linux命令总结Linux关机,重启# 关机shutdown -h now# 重启shutdown -r now查看系统,CPU信息# 查看系统内核信息uname -a# 查看系统内核版本cat /proc/version# 查看当前用户环境变量envcat /proc/cpuinfo# 查看有几个逻辑cpu, 包括cpu型号cat /proc/cpu......