题目描述
实现一个可存储若干个单词的字典。用户可以:
1.在字典中加入单词
2.查找指定单词在字典中的兄弟单词个数
3.查找指定单词的指定序号的兄弟单词,指定序号指字典中兄弟单词按字典顺序排序后的序号
4.清空字典中所有的单词
定义,格式说明
1.单词:有小写英文字母组成,不含其它字符
2.兄弟单词:
给定一个单词X,如果通过任意交换单词中字母的位置得到不同的单词Y,那么定义Y是X的兄弟单词
举例:bca是abc的兄弟单词,abc与abc是相同单词不是兄弟单词
题目规格
1.0<=字典中所含单词个数<=1000
2.1<=单词所含字母数<=50
输入描述:
先输入字典中单词的个数,再输入n个单词作为字典单词。
输入一个单词,查找其在字典中兄弟单词的个数
再输入数字n
输出描述:
根据输入,输出查找到的兄弟单词的个数
输入例子:
3
abc
bca
cab
abc
1
输出例子:
2
bca
做本题的时候几个坑需要注意:
1.对于要查找的单词,可能包含若干个字符的重复,如aabbc,全排列后需要去重操作并且不能包含要查找的单词,选择TreeSet保存全部的兄弟单词集合
2.对于字典中的所有单词,查找时候可能存在若干个相同的兄弟单词,都要按照字典序全部保存下来
方法一:使用全排列
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
import java.util.TreeSet;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
int n = scan.nextInt();//获得单词的个数
String[] str = new String[n];
for(int i = 0 ; i < n ; i++){
str[i] = scan.next();
}
String key_word = scan.next();//获得要查找的单词
int index_bro = scan.nextInt();//获得兄弟节点的指定序号
//获得字符串全排列
String[] rs = getQuanPaiLie(key_word);
//去重操作,生成最终的兄弟字符串数组
TreeSet<String> bro_rs = dealString(rs , key_word);
//将存在的兄弟字符保存在一个字符串集合中
ArrayList<String> exist_bro = new ArrayList<String>();
//判断用户输入的字符数组中有几个兄弟字符
for(int i = 0 ; i < n ; i++){
if(bro_rs.contains(str[i])){
exist_bro.add(str[i]);
}
}
System.out.println(exist_bro.size());
Collections.sort(exist_bro);
//打印指定顺序的字符串
// 1.一定要加入判断,防止下标越界报错
if(exist_bro.size() >= index_bro)
System.out.println(exist_bro.get(index_bro - 1));
// 2.不会越界
// int index_result = 1;
// for(String bro_str : exist_bro){
// if(index_result == index_bro){
// System.out.println(bro_str);
// break;
// }
// index_result++;
// }
}//endwhile
scan.close();
}//endmain
/**
* 求一个字符串的全排列
* @param str
* @return
*/
public static String[] getQuanPaiLie(String str){
//判空操作
if(str == null||str.isEmpty()){
return null;
}
//初始字符串数组设置
//可以将key的所有兄弟找出并保存
int strLen = str.length();
int bro_num = 1;
//使用阶乘算出所有的兄弟个数,如果字母包含相同字符,相应减少
for(int i = strLen ; i > 0 ; i--){
bro_num *= i;
}
//rs保存最终获得的全排列字符串数组
String[] rs = new String[bro_num];
//长度等于1,直接保存
if(strLen == 1){
rs[0] = str;
}else if(strLen == 2){
//长度等于2,交换保存
rs[0] = str;
rs[1] = "" + str.charAt(1) + str.charAt(0);
}else if(strLen > 2){
//如果长度大于2,采用递归的方式获得排列
char c = str.charAt(strLen - 1);//首先保存字符串的最后一个元素
//保存插入字符之前的字符串,截取前面strLen-1个字符
String strBefore = str.substring(0 ,strLen - 1);
//保存获得的strBefore字符串全排列的个数
String[] tmpRsArr = getQuanPaiLie(strBefore);
int count = 0;//保存字符串数组中下标的索引
for(int i = 0 ; i < tmpRsArr.length ; i++){
String tmpRs = tmpRsArr[i];
//k代表插入的位置,例如3个字符可以有4个插入位置,也就是length()+1
for(int k = 0 ; k < tmpRs.length() + 1 ; k++){
//当k=0时,substring(0,0)不截取任何字符
rs[count++] = tmpRs.substring(0 , k) + c + tmpRs.substring(k);
}
}
}
return rs;//返回完整的全排列数组
}
/**
* 字符串处理
* 1.去重操作,还要将初始给的标准字符串删除,即数组中不能有一样的字符串并且不能和标准字符串相同
* 2.按照字典序排序
* @param rs需要操作的字符串
* @return
* */
public static TreeSet<String> dealString(String[] rs , String key){
TreeSet<String> ts = new TreeSet<String>();
int length = rs.length;
for(int i = 0 ; i < length ; i++){
if(rs[i].equals(key)) continue;
ts.add(rs[i]);
}
return ts;
}
}
方法二:判断字典单词和待查找单词包含的字符是否相同,判断是否兄弟单词
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
int n = scan.nextInt();//获得单词的个数
String[] str = new String[n];
for(int i = 0 ; i < n ; i++){
str[i] = scan.next();
}
String key_word = scan.next();//获得要查找的单词
char[] key_ch = key_word.toCharArray();
Arrays.sort(key_ch);
int index_bro = scan.nextInt();//获得兄弟节点的指定序号
//将存在的兄弟字符保存在一个字符串集合中
ArrayList<String> exist_bro = new ArrayList<String>();
for(int i = 0 ; i < n ; i++){
if(isBroWord(key_word, str[i], key_ch)){
exist_bro.add(str[i]);
}
}
System.out.println(exist_bro.size());
Collections.sort(exist_bro);
if(exist_bro.size() >= index_bro)
System.out.println(exist_bro.get(index_bro - 1));
}//endwhile
scan.close();
}//endmain
private static boolean isBroWord(String key , String dic_word , char[] key_ch){
//如果字典单词和要查找单词相同,或者两个单词的长度不相等,返回false
if(key.equals(dic_word) || key.length() != dic_word.length()) return false;
char[] dic_ch = dic_word.toCharArray();
Arrays.sort(dic_ch);
//Arrays.equals(char[] , char[])判断两个字符数组是否相同
return Arrays.equals(key_ch, dic_ch) ? true : false;
}
}