数据结构课程设计, 随便写的, 见笑了
二三题写在一块了,自己拆分一下
题目一 文本文件单词统计
1.1【问题描述】
编写一个文本文件单词统计的程序,包括建立文件、单词统计、单词查询、单词定位的功能。
1.2 【基本要求】
程序应先询问用户的ID号(ID号包括两个大写字母和4 位数字),例如:
请输入用户 ID 号 :AB1234
程序应对输入的 ID 号验证,符合 ID 号要求的格式,然后程序提示四种选择:
(1) 建立文件
(2) 单词统计
(3) 单词查询及定位
(4) 退出
注意:
i) 文件至少包含50个英文单词(一定出现重复的单词,且一定包含数字)
ii) 文档不规范,单词之间可能不只有一个空格,并且有加引号的一些单词“jiaozi”
加引号的单词算单词,但数字不算单词
iii) 逐行扫描文本文件,计算文档中单词总数,及各个单词出现的频次,并且按照单词首字母abcd……
的顺序排列,显示并生成soft.txt文件
iv) 查询任意给出的单词是否存在,如果不存在,在屏幕上输出“ 查无此词! ”;如果存在,显示单词
出现的总次数,并且详细列出其出现的位置。
例如: 请您输入待查询的词: of
单词 of 共出现了 2 次;
第 1 次出现在第 1 行,第 5 个位置;
第 2 次出现在第 3 行,第 1 个位置。
请您输入待查询的词:
1.3 【源代码】
package DataStructureDesign.Demo;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.regex.Pattern;
@SuppressWarnings("all")
public class Processor {
private String path; // 文件路径
private Map<String, ArrayList> hashTab; // 逻辑输出 单词:出现位置组成的链表始址
private static final Pattern NUMBER_PATTERN = Pattern.compile("-?\\d+(\\.\\d+)?");
public Map<String, ArrayList> getHashTab() {
return hashTab;
}
public Processor() {
this.path = null;
this.hashTab = new TreeMap<>();
}
public void touchFile(User user) throws IOException {
String dirName = "D:\\files\\" + user.getId();
new File(dirName).mkdirs();
System.out.print("请输入文件名:");
Scanner sc = new Scanner(System.in);
path = dirName + "\\" + sc.next();
sc.nextLine();
File file = new File(path);
if (file.exists()) {
System.out.println("文件已存在!");
return;
}
file.createNewFile();
FileWriter writer = new FileWriter(file.getAbsolutePath());
// 向文件写入内容
System.out.println("请输入文本:(按'q'退出输入)");
String str = "";
while (sc.hasNextLine()) {
str = sc.nextLine();
if (str.equals("q"))
break;
writer.write(str + '\n');
}
writer.flush();
writer.close();
}
public String whichFile(User user) {
System.out.println("是否选择当前文件?" + path);
byte useCurrent = new Scanner(System.in).nextByte();
if (useCurrent == 0 || path == null) {
this.hashTab.clear();
System.out.print("请输入想要 统计词频/单词查询 的文件名");
path = "D:\\files\\" + user.getId() + "\\" + new Scanner(System.in).next();
}
return path;
}
public static String stringFormatting(String str) {
str = str.replaceAll("\"", "");
str = str.replaceAll("\\p{Punct}", "");
str = str.replaceAll("\\s+"," ");
str = str.toLowerCase();
return str;
}
public static boolean neededToBeCounted(String str) {
boolean isNumeric = str != null && NUMBER_PATTERN.matcher(str).matches();
return !isNumeric;
}
/**
* @throws FileNotFoundException
* @description : 逐行读取文件, 得到一张以单词为键,其各出现位置所组成的链表始址为值的哈希表
* @param : void
* @return : void
*/
public void wordFrequency() throws FileNotFoundException {
try {
hashTab.clear();
File file = new File(path);
BufferedReader in = new BufferedReader(new FileReader(file.getAbsolutePath()));
String str;
String[] strArr;
int row = 0;
while ((str = in.readLine()) != null) {
str = stringFormatting(str);
strArr = str.split(" ");
for (int col = 0; col < strArr.length; col++) {
if (neededToBeCounted(strArr[col])) {
if (!hashTab.containsKey(strArr[col])) {
ArrayList<Integer[]> list = new ArrayList<>();
hashTab.put(strArr[col], list);
list.add(new Integer[]{row + 1, col + 1});
} else
hashTab.get(strArr[col]).add(new Integer[]{row + 1, col + 1});
}
} // for
row++;
} // while
} // try
catch (IOException e) {
path = null;
System.out.println("文件不存在!");
}
}
public void printResult() {
int cnt = 0;
for (String str: hashTab.keySet()
) {
int tmp = hashTab.get(str).size();
cnt += tmp;
System.out.println("单词:" + str + ' ' + ' ' + "出现次数:" + tmp);
}
System.out.println("单词总数:" + cnt);
}
public void query(String word) {
if (hashTab.containsKey(word)) {
ArrayList<Integer[]> list = hashTab.get(word);
int frequency = list.size(); //各出现位置所组成的链表的长度即为该单词出现的次数
System.out.println("单词" + word + "共出现了" + frequency + "次");
int i = 1;
for (Integer[] tmp: list
) {
System.out.println("第" + i++ + "次" + "出现在第" + tmp[0] + "行" + ",第" + tmp[1] + "个位置。");
}
} // if (hashTab.containsKey(word))
else {
System.out.println("查无此词!");
}
}
}
package DataStructureDesign.Demo;
import java.io.IOException;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
User user = new User();
System.out.print("请输入用户ID号:");
while (!user.setId(sc.next()))
System.out.println("id号不合法,请重新输入");
int option;
Processor pc = new Processor();
while (true) {
System.out.println("(1)建立文件");
System.out.println("(2)单词统计");
System.out.println("(3)单词查询及定位");
System.out.println("(4)退出");
do {
option = new Scanner(System.in).nextInt();
} while (option < 1 || option > 4);
if (4 == option)
break;
switch (option) {
case 1:
pc.touchFile(user);
break;
case 2:
pc.whichFile(user);
pc.wordFrequency();
pc.printResult();
break;
case 3:
pc.whichFile(user);
if (pc.getHashTab().isEmpty())
pc.wordFrequency();
String str;
while (sc.hasNextLine()) {
System.out.print("请您输入待查询的词:(按'q'退出)");
str = sc.next();
if (str.equals("q"))
break;
pc.query(str);
}
break;
} // switch
} // while (true)
} // psvm
}
package DataStructureDesign.Demo;
public class User {
private String id;
private static final int DIGIT = 6;
public String getId() {
return id;
}
public boolean setId(String id) {
boolean result = isAuthorized(id);
if (result)
this.id = id;
return result;
}
public boolean isAuthorized(String id) {
char[] tmp = id.toCharArray();
if (tmp.length != 6)
return false;
for (int i = 0; i < DIGIT; i++) {
if (i < 2) {
if (tmp[i] < 65 || tmp[i] > 90)
return false;
}
else {
if (tmp[i] < 48 || tmp[i] > 57)
return false;
}
} // for
return true;
}
}
题目二 构造可以使n个城市连接的最小生成树
2.1【问题描述】
给定一个地区的n个城市间的距离网,用Prim算法和Kruskal算法建立最小生成树,并计算得到的最小生成树的代价。
2.2【设计及分析】
程序包含6个模块:
(1) 输入城市信息;城市之间的距离网用邻接矩阵表示,如图1所示。(至少要求5个城市,9条边,设定9999为不可达)
(2 )打印城市信息和城市之间的直接可达距离;
输出格式要求: 城市的列表如下,共有 5 个城市:
( 1 )太原 ( 2 )北京 ( 3 )上海
( 4 )深圳 ( 5 )广州
太原到北京距离 15 万公里;
太原到上海距离 20 万公里;
太原到广州不能直接到达;
注意: 城市及编号可以任意设定,但必须按输出格式要求显示;距离和可否直接可达可以虚构。
(3 )判断是否为连通图;(可利用图的遍历来解决连通性问题)
(4 )用Prim 算法求最小生成树,并显示最小生成树的代价
(5 )用Kruskal 算法求最小生成树,并显示最小生成树的代价
(6 )退出
报告包含:
(1)简述图遍历算法,并画出算法实现的流程图;
(2)简述Prim算法和Kruskal算法,并画出Prim算法和Kruskal算法实现的流程图。分析两个算法的异同。
题目三 交通咨询系统(最短路径问题)
3.1【问题描述】
给定一个地区的n个城市间的距离网,计算任意两个城市之间的最短路径。
3.2 【基本要求】
程序包含4个模块:
(1 )输入城市信息;城市之间的距离网用邻接矩阵表示,如图2所示。(至少要求6个城市,10条边,设定9999为不可达)
(2 )打印城市信息和城市之间的直接可达距离;
输出格式要求: 城市的列表如下,共有 5 个城市:
( 1 )太原 ( 2 )北京 ( 3 )上海
( 4 )深圳 ( 5 )广州
太原到北京距离 15 万公里;
太原到上海距离 20 万公里;
太原到广州不能直接到达;
注意: 城市及编号可以任意设定,但必须按输出格式要求显示;距离和可否直接可达可以虚构。
(3 )计算任意两个城市之间的最短路径;
格式要求:提示用户输入选择的起点城市序号和终点城市序号,如果输入的城市序号不在,提示出错并请用户重新输入;
输出起点城市到终点城市的最短路径及路径长度
(4 )退出
报告包含:
简述算法过程,并画出算法实现的流程图
3.3【源代码】
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define INFINITY 65535
typedef struct {
VertexType vexs[MAXVEX]; // 顶点数组
EdgeType arc[MAXVEX][MAXVEX]; // 邻接矩阵
int numVertexes, numEdges; // 顶点数和边数
int numConnectedComponent; // 连通分量数
} MGraph;
char visited[MAXVEX];
char cityList[10][10] = {"太原", "北京", "上海", "深圳", "广州"};
void createMGraph(MGraph *G) {
int i, j, k, w;
G->numConnectedComponent = 0;
// printf("输入顶点数和边数:\n");
scanf("%d %d", &G->numVertexes, &G->numEdges);
// for (i = 0; i < G->numVertexes; i++) {
// scanf(&G->vexs[i]);
// }
for (i = 0; i < G->numVertexes; i++)
for (j = 0; j < G->numVertexes; j++)
G->arc[i][j] = INFINITY;
for (k = 0; k < G->numEdges; k++) {
// printf("输入边(vi, vj)上的下标i, 下标j和权w:\n");
scanf("%d %d %d", &i, &j, &w);
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];
}
}
bool isLegal(EdgeType e) {
return e>0 && e<INFINITY;
}
void DFS(MGraph &G, int i) {
visited[i] = 1;
// printf("城市名:%s\n", cityList[i]);
for (int j = 0; j < G.numVertexes; j++) {
if (isLegal(G.arc[i][j]) && !visited[j])
DFS(G, j);
}
}
void DFSTraverse(MGraph &G) {
int i;
for (i = 0; i < G.numVertexes; i++)
visited[i] = 0;
for (i = 0; i < G.numVertexes; i++)
if (!visited[i]) {
DFS(G, i);
G.numConnectedComponent++;
}
}
void printInfo(MGraph &G) {
printf("城市的列表如下, 共有%d个城市:\n", G.numVertexes);
for (int i = 0; i < G.numVertexes; i++) {
printf("(%d) %s ", i+1, cityList[i]);
if (i%2==0 && i!=0)
printf("\n"); // 逢3换行显示
}
for (int i = 0; i < G.numVertexes; i++) {
for (int j = 0; j < G.numVertexes; j++) {
if (i == j)
continue;
else if (G.arc[i][j] == INFINITY)
printf("%s到%s不能直接到达\n", cityList[i], cityList[j]);
else
printf("%s到%s距离%d公里\n", cityList[i], cityList[j], G.arc[i][j]);
}
printf("===================================\n");
}
DFSTraverse(G);
if (G.numConnectedComponent == 1)
printf("该交通网是连通的\n");
else
printf("该交通网是不连通的\n");
}
void miniSpanTree_Prim(MGraph G) {
int min, i, j, k;
int adjVex[MAXVEX];
int lowCost[MAXVEX];
lowCost[0] = 0;
adjVex[0] = 0;
for (i = 1; i < G.numVertexes; i++) {
lowCost[i] = G.arc[0][i];
adjVex[i] = 0;
}
for (i = 1; i < G.numVertexes; i++) {
min = INFINITY;
j = 1; k = 0;
while (j < G.numVertexes) {
if (lowCost[j]!=0 && lowCost[j]<min) {
min = lowCost[j];
k = j;
}
j++;
}
printf("(%d, %d)", adjVex[k], k);
lowCost[k] = 0;
for (j = 1; j < G.numVertexes; j++) {
if (lowCost[j]!=0 && G.arc[k][j]<lowCost[j]) {
lowCost[j] = G.arc[k][j];
adjVex[j] = k;
}
}
}
}
#define MAXEDGE 15
typedef struct {
int begin;
int end;
int weight;
} Edge;
int find(int *parents, int f) {
while (parents[f] > 0)
f = parents[f];
return f;
}
bool compare(const Edge &e1, const Edge &e2) {
return e1.weight <= e2.weight; //权重从小到大排序
}
void miniSpanTree_Kruscal(MGraph G) {
int i, n, m;
int parents[MAXVEX];
vector<Edge> edges;
for (i = 0; i < G.numVertexes; i++)
parents[i] = 0;
for (int j = 0; j < G.numEdges; j++) {
for (int k = j; k < G.numEdges; k++) {
if (isLegal(G.arc[j][k])) {
Edge tmp;
tmp.begin = j;
tmp.end = k;
tmp.weight = G.arc[j][k];
edges.push_back(tmp);
}
}
}
sort(edges.begin(), edges.end(), compare);
for (Edge edge : edges) {
n = find(parents, edge.begin);
m = find(parents, edge.end);
if (n != m) {
parents[n] = m;
printf("(%d, %d) %d\n", edge.begin, edge.end, edge.weight);
}
}
}
typedef int pathMatrix[MAXVEX]; // 存储最短路径下标
typedef int shortPathTable[MAXVEX]; // 存储到各点最短路径的权值和
// 求网G的v0顶点到其余顶点v最短路径P[v]及带权长度D[v]
void shortestPath_Dijkstra(MGraph G, int v0, pathMatrix *P, shortPathTable *D) {
int v, w, k, min;
int final[MAXVEX];
for (v = 0; v < G.numVertexes; v++) {
final[v] = 0;
(*D)[v] = G.arc[v0][v];
(*P)[v] = v0; // 这是关键 初始化成v0
}
(*D)[v0] = 0;
final[v0] = 1;
for (v = 1; v < G.numVertexes; v++) {
min = INFINITY;
for (w = 0; w < G.numVertexes; w++) {
if (!final[w] && (*D)[w] < min) {
k = w;
min = (*D)[w];
}
}
final[k] = 1;
for (w = 0; w < G.numVertexes; w++) {
if (!final[w] && (min+G.arc[k][w] < (*D)[w])) {
(*D)[w] = min + G.arc[k][w];
(*P)[w] = k;
}
}
}
}
// 1 0
void ShortestPathBetweenTwoCites(MGraph G, int v0, int v) {
pathMatrix matrix;
shortPathTable table;
shortestPath_Dijkstra(G, v0, &matrix, &table);
int a = v;
printf("v%d到v%d的最短路径为:", v0, v);
while (a != v0) {
printf("v%d<-", a);
a = matrix[a];
}
printf("v%d\n", a);
printf("路径长度为:%d\n", table[v]);
}
void clbf() {
while (getchar() != '\n')
continue;
}
int main() {
MGraph G;
pathMatrix matrix;
shortPathTable table;
int option;
while (1) {
printf("选项\n");
printf("(1)输入城市信息\n");
printf("(2)打印城市信息和城市之间的直接可达距离\n");
printf("(3)计算任意两个城市之间的最短路径\n");
printf("(4)计算该网的最小生成树\n");
printf("(5)退出\n");
char ch1;
while (scanf("%d", &option) == 0 || option < 1 || option > 5 || (ch1 = getchar()) != '\n') {
printf("请输入从1到4的任意一个整数!\n");
clbf();
}
if (5 == option)
break;
switch (option) {
case 1:
createMGraph(&G);
break;
case 2:
printInfo(G);
break;
case 3:
printf("请输入起点城市序号和终点城市序号(用空格相隔)\n");
int s, d;
scanf("%d %d", &s, &d);
ShortestPathBetweenTwoCites(G, s, d);
break;
case 4:
printf("最小生成树:(普利姆)\n");
miniSpanTree_Prim(G);
printf("\n最小生成树:(克鲁斯卡尔)\n");
miniSpanTree_Kruscal(G);
printf("----------------------\n");
}
}
}