数据结构实习作业--使用栈进行回文分析英文文章

简介: 数据结构实习作业--使用栈进行回文分析英文文章

题目

分析英文文章

功能:

某些英文单词是回文单词,现要求借助于栈的基本操作统计出某一篇英文文章中出现的所有回文单词及该文所有的单词的数量,并计算该文章的“回文单词比率”,其中回文单词比率的定义如下。


要求:

(1)英文文章用txt文件存储。

(2)使用栈的基本操作处理该英文文章。

(3)在屏幕上直接输出该文章中所有单词的总数量及回文单词的数量,并输出回文单词比率。


提示:

(1)英文文章中各单词是以空格作为分隔符的,在处理时编写代码将英文文章中英文单词以外的字符除去,包括标点符号。

(2)提取出英文单词后对其进行回文判断前,需将其所有字母均转换为小写的,原因是:如“Dad”其实是回文单词,但若不将其第一个字母“D”转换为小写字母“d”,则程序将会判断“Dad”不是回文单词。


成品展示

但是有个小bug,会出现两个文件选择框

59d800217b6a4542afd4a3c3340e07aa.png

9c95cc5a08334bbeba525a7013627f4b.png


相关代码

文件选择弹窗实现

package Struction;
import Struction.bobo;
import java.awt.EventQueue;
import javax.swing.JFrame;
import java.awt.Button;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.io.File;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.awt.event.ActionEvent;
import java.awt.TextField;
import javax.swing.JTextField;
import javax.swing.filechooser.FileSystemView;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.security.auth.callback.ConfirmationCallback;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import java.awt.Color;
import java.awt.Font;
import java.awt.HeadlessException;
import java.awt.Panel;
public class panel extends JFrame {
  public static Method method;
  JFrame frame;
  String path="";
  int count = 0;
  private JTextField textField;
  /**
   * Launch the application.
   */
  public String chooseFile() {
    // 弹出文件浏览窗口
    JFileChooser chooser = new JFileChooser();
    // 显示对话框
    int res = chooser.showOpenDialog(this);
    // 如果点击的是确认按钮
    if (res == JFileChooser.APPROVE_OPTION) {
      File file = chooser.getSelectedFile();
      textField.setText(file.getAbsolutePath());
        path=chooser.getSelectedFile().getPath();
        return path;
      }
    return  null;
  }
  public void closeThis() {
    frame.dispose();
  }
  /**
   * Create the application.
   */
  public panel() {
    initialize();
  }
  /**
   * Initialize the contents of the frame.
   */
  private void initialize() {
    frame = new JFrame();
    frame.setFont(new Font("Dialog", Font.BOLD | Font.ITALIC, 12));
    frame.setTitle("\u56DE\u6587\u5206\u6790");
    frame.getContentPane().setBackground(new Color(152, 251, 152));
    frame.getContentPane().setForeground(new Color(255, 215, 0));
    frame.setBounds(100, 100, 410, 218);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);
    Button button = new Button("\u9009\u62E9");
    button.setBackground(new Color(192, 192, 192));
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        chooseFile(); 
      }
    });
    button.setBounds(303, 50, 62, 24);
    frame.getContentPane().add(button);
    textField = new JTextField();
    textField.setBounds(72, 50, 222, 24);
    frame.getContentPane().add(textField);
    textField.setColumns(10);
    JLabel lblNewLabel = new JLabel("\u9009\u62E9\u6240\u5904\u7406\u6587\u4EF6\u5730\u5740\uFF1A");
    lblNewLabel.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 16));
    lblNewLabel.setBounds(86, 13, 208, 24);
    frame.getContentPane().add(lblNewLabel);
    frame.setLocationRelativeTo(getOwner());
    JButton btnNewButton = new JButton("\u786E\u5B9A");
    btnNewButton.setBackground(new Color(192, 192, 192));
    btnNewButton.setForeground(new Color(0, 0, 0));
    btnNewButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        closeThis();
        bobo window = new bobo();
        window.frame.setVisible(true);
        window.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      }
    });
    btnNewButton.setBounds(303, 90, 62, 24);
    frame.getContentPane().add(btnNewButton);
  }
}


主方法类

package Struction;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JTextField;
import javax.swing.RepaintManager;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.nio.file.Path;
import java.util.concurrent.CountDownLatch;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import Struction.panel;
//对栈类进行定义
class Stack2 {// 顺序栈是栈的顺序实现
  private String[] s; // 使用数组来存贮栈中的元素,入栈和出栈都在栈顶进行
  private int top = -1 ;// 栈的索引 top表示栈顶,初始化为-1,栈顶的位置随出栈和入栈操作变化而变,需要设置top来记录当前栈顶元素在数组中的位置。
//    构造方法
  /*
(1)使用txt文件存储英文文章
(2)统计英文文章单词总数
(3)统计英文文章中回文单词数
(4)计算文章中的回文单词比率
   */
  public Stack2(int n) {
    s = new String[n];
  }
// 入栈--push
  public void push(String value) {
    // 判断栈是否满
    if (isFull()) {
      System.out.println("栈满了");
    }
    s[++top] = value;// 先运算,再++
  }
// 出栈--pop,将栈顶的数据返回
  public String pop() {
    // 判断栈是否空
    if (isEmpty()) {
      // 抛出异常
      throw new RuntimeException("栈空,没有数据");
    }
    return s[top--];// 先赋值,再--
  }
//栈空
  public boolean isEmpty() {
    return top == -1;
  }
//栈满
  public boolean isFull() {
    return top == s.length - 1;
  }
//栈的长度
  public int size() {
    return top + 1;
  }
}
public class bobo extends panel {
  // 面板变量
  JFrame frame;
  private JTextField text1;// 文本框
  private JTextField text2;
  private JTextField text3;
  public static String path1;
  private JScrollPane scrollPane;// 滚动面板
  private JTextArea Context; // 文本域
  static panel p = new panel();
  static int sum;
  static int number1;
  static double number2;
  static String s1 = "";
  static String[] s2;
  static String s3 = "";
  // 用于判断传入的文章是否是字母,如果字符为字母,则返回 true;否则返回 false。
  private static boolean ifword(String s) {
    if (s.length() == 0) {
      return false;
    }
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (!Character.isLetter(c)) {
        return false;
      }
    }
    return true;
  }
  private static boolean start(String s) {
    Stack2 st = new Stack2(s.length());//确定st的长度
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      st.push(c + ""); //将读取的逐个字符入栈
    }
    String s1 = "";
    for (int i = 0; i < s.length(); i++) {
      s1 = s1 + st.pop();// 出栈
    }
    if (s.equals(s1)) { // 判断进出是否相同,相同返回true,不相同返回false
      return true;
    }
    return false;
  }
//按照题意,将大写字母转化为小写字母
  private static String panduan(String s) {
    String ds = "";
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (Character.isLetter(c)) {
        if (Character.isUpperCase(c)) {
          c = Character.toLowerCase(c); 
        }
        ds = ds + c;
      }
    }
    return ds;
  }
// 通过调用spilt方法将文章每个单词逐个存入数组中,但是其中混有.,并且规范每一行的单词数,每行最多16个单词
  private static String sort(String en) {
    String[] a = en.split(" ");
    String Sorten = "  ";
    for (int i = 0; i < a.length; i++) {
      Sorten = Sorten + a[i] + " ";
      if (i % 15 == 0 && i != 0) {
        Sorten = Sorten + "\r\n"; 
      }
    }
    return Sorten;
  }
// 通过选择文件弹窗,获得地址,将地址传入到bufferedReader io流读取文件信息
  public static void main(String[] args) throws Exception {
    BufferedReader b = new BufferedReader(new FileReader(p.chooseFile()));
    String en;
    // 表示每次读取一行数据 直到为空退出循环, 对文本进行分隔 换行 排序
    while ((en = b.readLine()) != null) {
      s1 += en + " ";
      en = sort(en);// 对文本进行分隔 换行 排序
      s3 += en + "\r\n";
    }
    s2 = s1.split(" ");
    Stack2 stack = new Stack2(s2.length);
    for (String s : s2) { // 遍历每个元素
      s = panduan(s);// 判断是否是大写字母
      if (ifword(s)) {// 判断是否是字母
        if (start(s)) {// 判断是否回文
          number1++;
        }
        if (s.length() != 0) {
          stack.push(s);
        }
      }
    }
    sum = stack.size();
    number2 = ((double) number1 / (double) sum); //求回文率
    b.close();//关闭流
    EventQueue.invokeLater(new Runnable() { ///它封装了异步事件指派机制,该机制从队列中提取事件,不允许同时从该队列中指派多个事件。 按顺序指派。 
      public void run() {
        try {
          panel p = new panel();
          p.frame.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }
  /**
   * Create the application.
   */
  public bobo() {
    initialize();
  }
  /**
   * Initialize the contents of the frame.
   */
  private void initialize() {
    frame = new JFrame();
    frame.setResizable(false);
    frame.getContentPane().setBackground(Color.YELLOW);
    frame.getContentPane().setForeground(Color.BLACK);
    frame.setBounds(100, 100, 786, 652);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(getOwner());
    JLabel lable = new JLabel("\u82F1\u6587\u6587\u7AE0");
    lable.setBounds(14, 159, 156, 46);
    lable.setFont(new Font("宋体", Font.PLAIN, 39));
    JLabel label1 = new JLabel("\u5355\u8BCD\u603B\u6570:");
    label1.setBounds(29, 291, 88, 21);
    label1.setFont(new Font("宋体", Font.PLAIN, 18));
    JLabel label2 = new JLabel("\u56DE\u6587\u5355\u8BCD\u6570:");
    label2.setBounds(29, 343, 99, 21);
    label2.setFont(new Font("宋体", Font.PLAIN, 18));
    JLabel label3 = new JLabel("\u56DE\u6587\u7387:");
    label3.setBounds(29, 401, 78, 21);
    label3.setFont(new Font("宋体", Font.PLAIN, 18));
    text1 = new JTextField();
    text1.setBounds(29, 312, 42, 24);
    text1.setEditable(false);
    text1.setColumns(10);
    text2 = new JTextField();
    text2.setBounds(29, 364, 42, 24);
    text2.setEditable(false);
    text2.setColumns(10);
    text3 = new JTextField();
    text3.setBounds(29, 424, 141, 21);
    text3.setEditable(false);
    text3.setColumns(10);
    text1.setText("" + sum);
    text2.setText("" + number1);
    String sh = "" + (number2 * 100);
    text3.setText("" + sh + "%");
    scrollPane = new JScrollPane();
    scrollPane.setBounds(184, 0, 584, 605);
    scrollPane.setBackground(Color.WHITE);
    scrollPane.setForeground(Color.WHITE);
    scrollPane.setEnabled(false);
    frame.getContentPane().setLayout(null);
    frame.getContentPane().add(label2);
    frame.getContentPane().add(label1);
    frame.getContentPane().add(text1);
    frame.getContentPane().add(text2);
    frame.getContentPane().add(label3);
    frame.getContentPane().add(text3);
    frame.getContentPane().add(lable);
    frame.getContentPane().add(scrollPane);
    Context = new JTextArea();
    scrollPane.setViewportView(Context);
    Context.setEditable(false);
    Context.setForeground(Color.WHITE);
    Context.setFont(new Font("Monospaced", Font.PLAIN, 16));
    Context.setBackground(Color.PINK);
    Context.setText(s3);
  }
}

如有问题,感谢指出!

相关文章
|
5月前
|
编译器 C语言 C++
栈区的非法访问导致的死循环(x64)
这段内容主要分析了一段C语言代码在VS2022中形成死循环的原因,涉及栈区内存布局和数组越界问题。代码中`arr[15]`越界访问,修改了变量`i`的值,导致`for`循环条件始终为真,形成死循环。原因是VS2022栈区从低地址到高地址分配内存,`arr`数组与`i`相邻,`arr[15]`恰好覆盖`i`的地址。而在VS2019中,栈区先分配高地址再分配低地址,因此相同代码表现不同。这说明编译器对栈区内存分配顺序的实现差异会导致程序行为不一致,需避免数组越界以确保代码健壮性。
98 0
栈区的非法访问导致的死循环(x64)
232.用栈实现队列,225. 用队列实现栈
在232题中,通过两个栈(`stIn`和`stOut`)模拟队列的先入先出(FIFO)行为。`push`操作将元素压入`stIn`,`pop`和`peek`操作则通过将`stIn`的元素转移到`stOut`来实现队列的顺序访问。 225题则是利用单个队列(`que`)模拟栈的后入先出(LIFO)特性。通过多次调整队列头部元素的位置,确保弹出顺序符合栈的要求。`top`操作直接返回队列尾部元素,`empty`判断队列是否为空。 两题均仅使用基础数据结构操作,展示了栈与队列之间的转换逻辑。
|
10月前
|
存储 C语言 C++
【C++数据结构——栈与队列】顺序栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现顺序栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 1.初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储
446 77
|
9月前
|
算法 调度 C++
STL——栈和队列和优先队列
通过以上对栈、队列和优先队列的详细解释和示例,希望能帮助读者更好地理解和应用这些重要的数据结构。
214 11
|
9月前
|
DataX
☀☀☀☀☀☀☀有关栈和队列应用的oj题讲解☼☼☼☼☼☼☼
### 简介 本文介绍了三种数据结构的实现方法:用两个队列实现栈、用两个栈实现队列以及设计循环队列。具体思路如下: 1. **用两个队列实现栈**: - 插入元素时,选择非空队列进行插入。 - 移除栈顶元素时,将非空队列中的元素依次转移到另一个队列,直到只剩下一个元素,然后弹出该元素。 - 判空条件为两个队列均为空。 2. **用两个栈实现队列**: - 插入元素时,选择非空栈进行插入。 - 移除队首元素时,将非空栈中的元素依次转移到另一个栈,再将这些元素重新放回原栈以保持顺序。 - 判空条件为两个栈均为空。
|
10月前
|
存储 C++ 索引
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
【数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】初始化队列、销毁队列、判断队列是否为空、进队列、出队列等。本关任务:编写一个程序实现环形队列的基本运算。(6)出队列序列:yzopq2*(5)依次进队列元素:opq2*(6)出队列序列:bcdef。(2)依次进队列元素:abc。(5)依次进队列元素:def。(2)依次进队列元素:xyz。开始你的任务吧,祝你成功!(4)出队一个元素a。(4)出队一个元素x。
371 13
【C++数据结构——栈与队列】环形队列的基本运算(头歌实践教学平台习题)【合集】
|
10月前
|
存储 C语言 C++
【C++数据结构——栈与队列】链栈的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现链栈的基本运算。开始你的任务吧,祝你成功!​ 相关知识 初始化栈 销毁栈 判断栈是否为空 进栈 出栈 取栈顶元素 初始化栈 概念:初始化栈是为栈的使用做准备,包括分配内存空间(如果是动态分配)和设置栈的初始状态。栈有顺序栈和链式栈两种常见形式。对于顺序栈,通常需要定义一个数组来存储栈元素,并设置一个变量来记录栈顶位置;对于链式栈,需要定义节点结构,包含数据域和指针域,同时初始化栈顶指针。 示例(顺序栈): 以下是一个简单的顺序栈初始化示例,假设用C语言实现,栈中存储整数,最大
199 9
|
10月前
|
C++
【C++数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】
【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】(1)遇到左括号:进栈Push()(2)遇到右括号:若栈顶元素为左括号,则出栈Pop();否则返回false。(3)当遍历表达式结束,且栈为空时,则返回true,否则返回false。本关任务:编写一个程序利用栈判断左、右圆括号是否配对。为了完成本关任务,你需要掌握:栈对括号的处理。(1)遇到左括号:进栈Push()开始你的任务吧,祝你成功!测试输入:(()))
222 7
|
12月前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
345 5
|
12月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
382 1

热门文章

最新文章