解析一下这行代码Set<String> groupSet = listMap.keySet();
时间: 2024-04-24 16:22:17 浏览: 157
这行代码的作用是将 `listMap` 中所有的键(key)存储到一个 Set 集合中,这个 Set 集合中的元素都是 String 类型的。可以通过这个 Set 集合来获取 `listMap` 中所有的键。
具体来说,`listMap` 是一个 Map 集合,它存储了一些键值对(key-value pair)。`keySet()` 方法是 Map 接口中的一个方法,用于获取 Map 中所有的键,返回一个 Set 集合。这个方法返回的 Set 集合中的元素是无序的,并且不允许有重复元素。这个 Set 集合可以用于迭代 Map 中的所有键,或者用于判断某个键是否存在于 Map 中。
将 `listMap.keySet()` 的返回值赋值给 `groupSet`,就创建了一个新的 Set 集合,其中包含了 `listMap` 中所有的键。这个 Set 集合的泛型参数是 `String`,这意味着集合中的元素都是 String 类型。
相关问题
假如你是一个高级程序员,请用Java编写具体代码实现下面功能 创建一个 GUI 界面,让用户输入语法 G。您可以使用 Java Swing 来创建用户界面。 创建一个 CFG 类,用于处理输入语法 G 的左递归和公共左因子分解。在该类中,您可以添加方法来计算每个非终端符号的 FIRST 和 FOLLOW 集。 实现 LL(1) 解析器算法。您可以使用一个解析器类来实现此算法。该算法需要 LL(1) 解析表来预测下一个输入标记是哪个。可以使用一个二维数组来表示解析表。每个单元格都对应一个非终结符和一个终结符。解析表中的每个元素包含一个产生式,该产生式来标识生成哪个非终极符号的语法树。 将 CFG 类和解析器类与 GUI 类集成,以便用户可以输入要解析的句子,并且输出可以显示在屏幕上。您可以将 CFG 类和解析器类作为 GUI 类的成员变量,并在 GUI 类中添加按钮和文本框,以便用户可以输入要解析的句子并将打印出来的FIRST、FOLLOW集和预测分析表输出显示在屏幕上。
好的,以下是我给出的Java代码实现:
首先,我们创建一个GUI界面,使用Java Swing来创建。代码如下:
```java
import javax.swing.*;
import java.awt.*;
public class CFG_GUI {
private JFrame frame;
private JPanel panel;
private JLabel inputLabel;
private JTextField inputField;
private JButton submitButton;
private JTextArea outputArea;
private JScrollPane scrollPane;
public CFG_GUI() {
frame = new JFrame("CFG Parser");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new BorderLayout());
inputLabel = new JLabel("Input Grammar:");
inputField = new JTextField(50);
submitButton = new JButton("Parse");
outputArea = new JTextArea(30, 50);
outputArea.setEditable(false);
scrollPane = new JScrollPane(outputArea);
JPanel inputPanel = new JPanel();
inputPanel.add(inputLabel);
inputPanel.add(inputField);
inputPanel.add(submitButton);
panel.add(inputPanel, BorderLayout.NORTH);
panel.add(scrollPane, BorderLayout.CENTER);
frame.add(panel);
frame.setVisible(true);
}
public String getInput() {
return inputField.getText();
}
public void setOutput(String output) {
outputArea.setText(output);
}
public void addSubmitListener(ActionListener listener) {
submitButton.addActionListener(listener);
}
}
```
接下来,我们创建一个CFG类,用于处理输入语法G的左递归和公共左因子分解,并添加方法来计算每个非终端符号的FIRST和FOLLOW集。代码如下:
```java
import java.util.*;
public class CFG {
private Map<String, List<String>> productions;
public CFG(String input) {
productions = new HashMap<>();
String[] lines = input.split("\n");
for (String line : lines) {
String[] tokens = line.split(" -> ");
String nonterminal = tokens[0];
String[] rhs = tokens[1].split("\\|");
List<String> productionsList = new ArrayList<>(Arrays.asList(rhs));
productions.put(nonterminal, productionsList);
}
}
public Map<String, Set<String>> getFirst() {
Map<String, Set<String>> first = new HashMap<>();
for (String nonterminal : productions.keySet()) {
first.put(nonterminal, new HashSet<>());
}
boolean changed;
do {
changed = false;
for (String nonterminal : productions.keySet()) {
for (String production : productions.get(nonterminal)) {
String[] symbols = production.split("\\s+");
int i = 0;
while (i < symbols.length) {
String symbol = symbols[i];
if (isTerminal(symbol)) {
changed |= first.get(nonterminal).add(symbol);
break;
} else {
Set<String> firstOfSymbol = first.get(symbol);
changed |= first.get(nonterminal).addAll(firstOfSymbol);
if (!firstOfSymbol.contains("")) {
break;
}
}
i++;
}
if (i == symbols.length) {
changed |= first.get(nonterminal).add("");
}
}
}
} while (changed);
return first;
}
public Map<String, Set<String>> getFollow(Map<String, Set<String>> first) {
Map<String, Set<String>> follow = new HashMap<>();
for (String nonterminal : productions.keySet()) {
follow.put(nonterminal, new HashSet<>());
}
follow.get("S").add("$");
boolean changed;
do {
changed = false;
for (String nonterminal : productions.keySet()) {
for (String production : productions.get(nonterminal)) {
String[] symbols = production.split("\\s+");
for (int i = 0; i < symbols.length; i++) {
String symbol = symbols[i];
if (isNonterminal(symbol)) {
Set<String> followOfSymbol = follow.get(symbol);
int j = i + 1;
while (j < symbols.length) {
Set<String> firstOfNextSymbol = first.get(symbols[j]);
changed |= followOfSymbol.addAll(firstOfNextSymbol);
if (!firstOfNextSymbol.contains("")) {
break;
}
j++;
}
if (j == symbols.length) {
changed |= followOfSymbol.addAll(follow.get(nonterminal));
}
}
}
}
}
} while (changed);
return follow;
}
public boolean isNonterminal(String symbol) {
return symbol.matches("[A-Z].*");
}
public boolean isTerminal(String symbol) {
return !isNonterminal(symbol);
}
public String eliminateLeftRecursion() {
List<String> nonterminals = new ArrayList<>(productions.keySet());
StringBuilder output = new StringBuilder();
for (int i = 0; i < nonterminals.size(); i++) {
String nonterminal = nonterminals.get(i);
output.append(nonterminal).append(" -> ");
List<String> productionsList = productions.get(nonterminal);
List<String> alpha = new ArrayList<>();
List<String> beta = new ArrayList<>();
for (String production : productionsList) {
String[] symbols = production.split("\\s+");
if (symbols[0].equals(nonterminal)) {
alpha.add(production.substring(nonterminal.length() + 3));
} else {
beta.add(production);
}
}
if (alpha.isEmpty()) {
output.append(String.join(" | ", beta)).append("\n");
continue;
}
String newNonterminal = nonterminal + "'";
output.append(String.join(" | ", beta)).append(" ").append(newNonterminal).append("\n");
List<String> newProductions = new ArrayList<>();
for (String b : beta) {
newProductions.add(b + " " + newNonterminal);
}
newProductions.add("");
List<String> newAlphaProductions = new ArrayList<>();
for (String a : alpha) {
newAlphaProductions.add(a.substring(1) + " " + newNonterminal);
}
newAlphaProductions.add("");
productions.put(nonterminal, new ArrayList<>(newProductions));
productions.put(newNonterminal, new ArrayList<>(newAlphaProductions));
nonterminals.add(i + 1, newNonterminal);
}
return output.toString();
}
public String factorize() {
List<String> nonterminals = new ArrayList<>(productions.keySet());
StringBuilder output = new StringBuilder();
for (int i = 0; i < nonterminals.size(); i++) {
String nonterminal = nonterminals.get(i);
List<String> productionsList = productions.get(nonterminal);
Map<String, List<String>> groups = new HashMap<>();
for (String production : productionsList) {
String symbol = production.split("\\s+")[0];
if (!groups.containsKey(symbol)) {
groups.put(symbol, new ArrayList<>());
}
groups.get(symbol).add(production);
}
List<String> newProductions = new ArrayList<>();
for (String symbol : groups.keySet()) {
List<String> group = groups.get(symbol);
if (group.size() > 1) {
String newNonterminal = nonterminal + "'";
output.append(newNonterminal).append(" -> ").append(symbol).append(" ").append(newNonterminal).append("\n");
productions.put(newNonterminal, new ArrayList<>(group));
newProductions.add(symbol + " " + newNonterminal);
nonterminals.add(i + 1, newNonterminal);
} else {
newProductions.addAll(group);
}
}
productions.put(nonterminal, newProductions);
}
return output.toString();
}
}
```
最后,我们实现LL(1)解析器算法,使用一个解析器类来实现此算法。代码如下:
```java
import java.util.*;
public class Parser {
private String[][] parsingTable;
private Map<String, List<String>> productions;
public Parser(Map<String, Set<String>> first, Map<String, Set<String>> follow, CFG cfg) {
Set<String> terminals = new HashSet<>();
Set<String> nonterminals = new HashSet<>(cfg.productions.keySet());
productions = cfg.productions;
for (String nonterminal : nonterminals) {
terminals.addAll(first.get(nonterminal));
terminals.addAll(follow.get(nonterminal));
}
terminals.remove("");
parsingTable = new String[nonterminals.size() + 1][terminals.size() + 1];
for (int i = 0; i < parsingTable.length; i++) {
for (int j = 0; j < parsingTable[0].length; j++) {
parsingTable[i][j] = "";
}
}
for (String nonterminal : nonterminals) {
int i = getIndex(nonterminal, nonterminals);
for (String production : productions.get(nonterminal)) {
Set<String> firstOfProduction = getFirstOfProduction(production, first);
for (String symbol : firstOfProduction) {
if (!symbol.equals("")) {
int j = getIndex(symbol, terminals);
parsingTable[i][j] = production;
}
}
if (firstOfProduction.contains("")) {
for (String symbol : follow.get(nonterminal)) {
int j = getIndex(symbol, terminals);
parsingTable[i][j] = production;
}
}
}
}
}
public boolean parse(String input) {
Stack<String> stack = new Stack<>();
stack.push("$");
stack.push("S");
String[] tokens = input.split("\\s+");
int i = 0;
while (!stack.empty()) {
String top = stack.pop();
if (isTerminal(top)) {
if (!top.equals(tokens[i])) {
return false;
}
i++;
} else if (isNonterminal(top)) {
int row = getIndex(top, productions.keySet());
int col = getIndex(tokens[i], parsingTable[0]);
String production = parsingTable[row][col];
if (production.equals("")) {
return false;
}
String[] symbols = production.split("\\s+");
for (int j = symbols.length - 1; j >= 0; j--) {
stack.push(symbols[j]);
}
}
}
return true;
}
public Set<String> getFirstOfProduction(String production, Map<String, Set<String>> first) {
String[] symbols = production.split("\\s+");
Set<String> firstOfProduction = new HashSet<>();
int i = 0;
while (i < symbols.length) {
String symbol = symbols[i];
if (isTerminal(symbol)) {
firstOfProduction.add(symbol);
break;
} else {
Set<String> firstOfSymbol = first.get(symbol);
firstOfProduction.addAll(firstOfSymbol);
if (!firstOfSymbol.contains("")) {
break;
}
}
i++;
}
if (i == symbols.length) {
firstOfProduction.add("");
}
return firstOfProduction;
}
public boolean isNonterminal(String symbol) {
return symbol.matches("[A-Z].*");
}
public boolean isTerminal(String symbol) {
return !isNonterminal(symbol);
}
public int getIndex(String symbol, Set<String> set) {
int i = 0;
for (String s : set) {
if (s.equals(symbol)) {
return i;
}
i++;
}
return -1;
}
public int getIndex(String symbol, String[] array) {
int i = 0;
for (String s : array) {
if (s.equals(symbol)) {
return i;
}
i++;
}
return -1;
}
}
```
最后,我们将CFG类和解析器类与GUI类集成,以便用户可以输入要解析的句子,并且输出可以显示在屏幕上。代码如下:
```java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Map;
import java.util.Set;
public class Main {
public static void main(String[] args) {
CFG_GUI gui = new CFG_GUI();
gui.addSubmitListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String input = gui.getInput();
CFG cfg = new CFG(input);
String output = "";
output += "Original Grammar:\n" + input + "\n\n";
output += "Eliminated Left Recursion:\n" + cfg.eliminateLeftRecursion() + "\n";
output += "Factored Grammar:\n" + cfg.factorize() + "\n";
Map<String, Set<String>> first = cfg.getFirst();
output += "FIRST Sets:\n";
for (String nonterminal : first.keySet()) {
output += nonterminal + ": " + first.get(nonterminal) + "\n";
}
output += "\n";
Map<String, Set<String>> follow = cfg.getFollow(first);
output += "FOLLOW Sets:\n";
for (String nonterminal : follow.keySet()) {
output += nonterminal + ": " + follow.get(nonterminal) + "\n";
}
output += "\n";
Parser parser = new Parser(first, follow, cfg);
output += "Parsing Table:\n";
output += String.format("%-6s", "");
Set<String> terminals = parser.getIndex("", first).isEmpty() ? first.get("S") : first.get("");
for (String terminal : terminals) {
output += String.format("%-25s", terminal);
}
output += "\n";
for (String nonterminal : cfg.productions.keySet()) {
output += String.format("%-6s", nonterminal);
for (String terminal : terminals) {
String production = parser.parsingTable[parser.getIndex(nonterminal, cfg.productions.keySet())][parser.getIndex(terminal, parser.parsingTable[0])];
if (!production.equals("")) {
output += String.format("%-25s", nonterminal + " -> " + production);
} else {
output += String.format("%-25s", "");
}
}
output += "\n";
}
output += "\n";
boolean success = parser.parse(gui.getInput());
output += "Parsing Result: " + (success ? "Accepted" : "Rejected");
gui.setOutput(output);
}
});
}
}
```
请设计一个类型,提供如下方法 提示 要统计每个单词出现的次数,由于一个方法不能返回2种类型,我们需要把单词和它的出现次数封装到一个类中 去,所以,可以定义一个类型如下: 由于我们统计的有多个单词,所以,我们上面的 countSize 方法的返回类型就可以设计成 WordBean[],如下: public class PatternDemo { //此方法用来统计 content 中的英文单词个数, 请使用正则表达式来做,单词的正则表达式请自行编写, public int countWords(CharSequence content) { ... } //此方法返回一串固定的字符串,已写好,可以直接用。 public StringBuilder getContent() { //此方法的内容如下: StringBuilder builder = new StringBuilder(); builder.append("Hooray! It's snowing! It's time to make a snowman.James runs out. He makes a big pile of snow. He puts a big snowball on top. He adds a scarf and a hat. He adds an orange for the nose. He adds coal for the eyes and buttons.In the evening, James opens the door. What does he see? The snowman is moving! James invites him in. The snowman has never been inside a house. He says hello to the cat. He plays with paper towels.A moment later, the snowman takes James's hand and goes out.They go up, up, up into the air! They are flying! What a wonderful night!The next morning, James jumps out of bed. He runs to the door.He wants to thank the snowman. But he's gone."); // return builder; } //此方法统计出每个单词[不考虑大小写]出现的次数,数据结构请自行定义,设计如下: public ? countSize(CharSequence content) { //TODO ... } //注:? 处是你需要去思考,该设计什么结构来存放结果 } public class WordBean { //属性 private String word; //单词 private int count; //出次 //TODO 请自行完成构造、getter/setter、toString、等相关方法 } public WordBean[] countSize(CharSequence content) { //TODO ... } 最后写一个调用者类,来测试你的实现,如下: public class UsePatternDemo() { public static void main(String[] args) { //TODO ... }
可以使用 HashMap 来存储每个单词出现的次数,设计如下:
```
public class PatternDemo {
//此方法用来统计 content 中的英文单词个数, 请使用正则表达式来做,单词的正则表达式请自行编写,
public int countWords(CharSequence content) {
//定义单词正则表达式
String wordRegex = "\\b[a-zA-Z]+\\b";
//统计单词个数
Pattern pattern = Pattern.compile(wordRegex);
Matcher matcher = pattern.matcher(content);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
//此方法返回一串固定的字符串,已写好,可以直接用。
public StringBuilder getContent() {
StringBuilder builder = new StringBuilder();
builder.append("Hooray! It's snowing! It's time to make a snowman.James runs out. He makes a big pile of snow. He puts a big snowball on top. He adds a scarf and a hat. He adds an orange for the nose. He adds coal for the eyes and buttons.In the evening, James opens the door. What does he see? The snowman is moving! James invites him in. The snowman has never been inside a house. He says hello to the cat. He plays with paper towels.A moment later, the snowman takes James's hand and goes out.They go up, up, up into the air! They are flying! What a wonderful night!The next morning, James jumps out of bed. He runs to the door.He wants to thank the snowman. But he's gone.");
return builder;
}
//此方法统计出每个单词[不考虑大小写]出现的次数,数据结构请自行定义,设计如下:
public HashMap<String, Integer> countSize(CharSequence content) {
//定义单词正则表达式
String wordRegex = "\\b[a-zA-Z]+\\b";
//统计每个单词出现的次数
Pattern pattern = Pattern.compile(wordRegex);
Matcher matcher = pattern.matcher(content);
HashMap<String, Integer> map = new HashMap<>();
while (matcher.find()) {
String word = matcher.group().toLowerCase(); //转换为小写
if (map.containsKey(word)) {
map.put(word, map.get(word) + 1);
} else {
map.put(word, 1);
}
}
return map;
}
}
public class WordBean {
//属性
private String word; //单词
private int count; //出现次数
//构造方法
public WordBean(String word, int count) {
this.word = word;
this.count = count;
}
//getter/setter方法
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
//toString方法
@Override
public String toString() {
return "WordBean{" +
"word='" + word + '\'' +
", count=" + count +
'}';
}
}
public WordBean[] countSize(CharSequence content) {
HashMap<String, Integer> map = countSize(content);
WordBean[] result = new WordBean[map.size()];
int i = 0;
for (String key : map.keySet()) {
result[i++] = new WordBean(key, map.get(key));
}
return result;
}
public class UsePatternDemo {
public static void main(String[] args) {
PatternDemo demo = new PatternDemo();
StringBuilder content = demo.getContent();
int countWords = demo.countWords(content);
System.out.println("单词个数:" + countWords);
HashMap<String, Integer> map = demo.countSize(content);
for (String key : map.keySet()) {
System.out.println(key + "出现次数:" + map.get(key));
}
WordBean[] wordBeans = demo.countSize(content);
for (WordBean wordBean : wordBeans) {
System.out.println(wordBean);
}
}
}
```
阅读全文