华为机试---查找兄弟单词



题目描述
实现一个可存储若干个单词的字典。用户可以:
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;
 }
}




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值