• 常见机试题分析Java版


    1. 操作系统任务分为系统任务和用户任务两种。其中,系统任务的优先级<50,用户任务的优先级>=50<=255.优先级大于255的为非法任务,应予以剔除。现有一任务队列task[],长度为ntask中的元素值表示任务的优先级,数值越小,优先级越高。函数scheduler实现如下功能,将task[]种的任务按照系统任务、用户任务依次存放到system_task[]数组和user_task[]数组中,数组中元素的值是任务在task[]数组中的下标,并且优先级高的任务排在前面,优先级相同的任务按照入队顺序排列,数组元素为-1表示结束。例如:task[]={0,30,155,1,80,300,170,40,99} system_task[]=}0,3,1,7,-1} user_task[]={4,8,2,6,-1}。函数接口为void scheduler(int task[],int n,int system_task[],int user_task[])

    思路分析:

    (1)先看给定的函数接口,参数为任务队列数组、任务数、系统任务数组和用户队列数组,也就是说在main函数中调用该函数时,这些参数是已经初始化了的。这里系统任务数组和用户队列数组就要注意了,题目中说数组元素为-1表示结束,即数组中并不是所有元素都是任务下标,输出时用一个while循环判断一下不是-1就成。那就好办了,先按照任务数组的长度初始化系统任务数组和用户队列数组,Java会自动为它们赋初值为0,这样就可以传参了。

    (2)题目的核心是根据数组元素值的大小排列其下标,艾玛这不就是为HashMap量身定制的么。可以遍历任务队列,将系统任务和用户任务及其下标分别存入HashMap,然后对这两个HashMap分别按照值排序,再取出其键分别存入系统任务数组和用户任务数组,最后两个数组都添个-1就搞定了。

    代码如下:

    
    
    package cn.edu.xidian.crytoll;
    
    import java.util.*;
    
    import java.util.Map.*;
    
    public class Scheduler {
    
       public static void scheduler(int task[],int n,int system_task[],int user_task[]){
    
       Map<Integer,Integer> inputsystem = new HashMap<Integer,Integer>();
    
       Map<Integer,Integer> inputuser = new HashMap<Integer,Integer>();
    
       for(int i=0;i<n;i++){
    
       if(task[i]>=0&&task[i]<50) inputsystem.put(i,task[i]);
    
       else if(task[i]>=50&&task[i]<=255) inputuser.put(i,task[i]);
    
       }
    
       Map<Integer, Integer> outputsystem = sortByValue(inputsystem);
    
       Map<Integer, Integer> outputuser = sortByValue(inputuser);
    
       Set<Integer> systemset = outputsystem.keySet();
    
       Set<Integer> userset = outputuser.keySet(); 
    
       int systemn=0;
    
       int usern=0;
    
       for (Integer s:systemset) {
    
           system_task[systemn]=s;
    
           systemn++;
    
       } 
    
       for (Integer s:userset) {
    
           user_task[usern]=s;
    
           usern++;
    
       }
    
       system_task[systemn]=-1;
    
       user_task[usern]=-1;
    
       int i=0;
    
       while(system_task[i]!=-1){
    
       System.out.println(system_task[i]);
    
       ++i;
    
       }
    
       int j=0;
    
       while(user_task[j]!=-1){
    
       System.out.println(user_task[j]);
    
       ++j;
    
       }
    
       }
    
       public static <K, V extends Comparable<V>> Map<K, V> sortByValue(
    
               Map<K, V> map) {
    
           List<Entry<K, V>> list = new LinkedList<Entry<K, V>>(map.entrySet());
    
           Collections.sort(list, new Comparator<Entry<K, V>>() {
    
               public int compare(Entry<K, V> o1, Entry<K, V> o2) {
    
                   Comparable<V> v1 = o1.getValue();
    
                   V v2 = o2.getValue();
    
                   if (v1 == null) {
    
                       if (v2 == null) {
    
                           return 0;
    
                       } else {
    
                           return -1;
    
                       }
    
                   } else {
    
                       if (v2 == null) {
    
                           return 1;
    
                       } else {
    
                           return v1.compareTo(v2);
    
                       }
    
                   }
    
               }
    
           });
    
           Map<K, V> result = new LinkedHashMap<K, V>();
    
           Iterator<Entry<K, V>> it = list.iterator();
    
           while (it.hasNext()) {
    
               Entry<K, V> entry = it.next();
    
               result.put(entry.getKey(), entry.getValue());
    
           }
    
           return result;
    
       }
    
       public static void main(String[] args){
    
       int task[]={0,30,155,1,80,300,170,40,99};
    
       int n=task.length;        
    
       int system_task[]=new int[n];
    
       int user_task[]=new int[n];
    
       scheduler(task,n,system_task,user_task);
    
       }
    
    }                                               
    
    

    2. 输入一个表达式,没有括号,数字小于0-9之间,输出计算结果,所有的中间结果化为整形。例如:  输入:3+8×2/9-2。输出:

    思路分析:

    (1)输入的表达式是个字符串类型,要获取它的每个运算数和运算符需要用到charAt()方法。然后挨个字符地存入ArrayList,再使用get()方法遍历字符串。

    (2)四则表达式的运算符分两种优先级,需遍历两次,第一次处理乘法和除法,第二次处理加法和减法。遇到运算符后将其前后两个数的运算结果求出,然后使用add()方法将运算结果插入到前运算数的位置,再连续使用remove()方法将参与此次运算的运算符和两个运算数移除。最后ArrayList中只剩一个元素,即为该表达式的值。使用parseInt()方法将其格式化后返回。

    代码如下:

    package cn.edu.xidian.crytoll;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class getMyRet {
        public int getMyRet(String str){
            int len=str.length(); 
            List<String> list=new ArrayList<String>(); 
            for(int i=0;i<len;i++) 
                list.add(str.charAt(i)+"");
            for(int j=0;j<list.size();j++){                
                if(list.get(j).equals("×")){                    
                    int ji=Integer.parseInt(list.get(j-1))*Integer.parseInt(list.get(j+1)); 
                    list.add(j-1,ji+""); 
                    list.remove(j); 
                    list.remove(j); 
                    list.remove(j);                
                    j--; 
                 } 
                 else if(list.get(j).equals("/")){ 
                     int shang=Integer.parseInt(list.get(j-1))/Integer.parseInt(list.get(j+1)); 
                     list.add(j-1,shang+"");  
                     list.remove(j);  
                     list.remove(j);  
                     list.remove(j);  
                     j--; 
                 } 
             }            
             for(int k=0;k<list.size();k++){ 
                 if(list.get(k).equals("+")){ 
                     int he=Integer.parseInt(list.get(k-1))+Integer.parseInt(list.get(k+1)); 
                     list.add(k-1,he+"");  
                     list.remove(k);  
                     list.remove(k);  
                     list.remove(k);
                     k--;  
                 } 
                 if(list.get(k).equals("-")){ 
                     int cha=Integer.parseInt(list.get(k-1))-Integer.parseInt(list.get(k+1)); 
                     list.add(k-1,cha+"");  
                     list.remove(k);  
                     list.remove(k);  
                     list.remove(k);  
                     k--; 
                 } 
             } 
             int sum=Integer.parseInt(list.get(0)); 
             return sum;
        }
        public static void main(String[] args){
            String input="3+8×2/9-2";
            getMyRet getmyret=new getMyRet();
            System.out.println(getmyret.getMyRet(input));
        }
    }

     3. 将一个十进制(byte型)转换为二进制,将二进制数前后颠倒,再算出颠倒后对应的十进制数。

    思路分析:进制互转的话Java有现成的方法可以调用。十进制转二进制用Integer类的toBinaryString()方法,二进制转十进制用Integer类的valueOf()方法。

    代码如下:

    package cn.edu.xidian.crytoll;
    
    public class UpperToLower {
        //遍历字符串中的每个字符,如果是小写则直接添加进结果字符串
        //若是A-U的大写字母,将其转换成小写字母后加5,添加进结果字符串
        //若是V-Z的大写字母,将其转换成小写字母后减21,添加进结果字符串
        public String uptolow(String input){
            String output="";
            int len=input.length();
            for(int i=0;i<len;i++){
                if((input.charAt(i)+"").matches("[a-z]")) output=output+input.charAt(i);
                if((input.charAt(i)+"").matches("[A-U]")) output=output+((char)(input.charAt(i)+5)+"").toLowerCase();
                if((input.charAt(i)+"").matches("[V-Z]")) output=output+((char)(input.charAt(i)-21)+"").toLowerCase();
            }
            return output;
        }
        public static void main(String[] args){
            String input="AbCdEfGhIjKlMnOpQrStUvWxYz";
            System.out.println(new UpperToLower().uptolow(input));
        }
    }

     4. 输入一串数字,将第一个数字作为容量大小,从其它的数字中挑选出之和正好等于第一个数字的数字组合,若存在这样的数字组合其和等于第一个数字的大小,则输出1, 否则输出0

    输入:105342(大体上是这种形式的)输出:1

    思路分析:

    (1)先将输入格式化,第一个数字拿出来作为目标和,其余数字存入数组并升序排序

    (2)建立两个链表,一个用于存储备选数字,一个用于存储当前纳入选择的数字

    (3)将备选数字存入链表,为其设置迭代器,因为是双层循环,故需创建一个迭代器副本

    (4)设置已选数字的和并初始化为0,从第一个备选数字开始,清空已有和,比较当前数字数字与其他每个数字的和的情况

    (5)若第一个备选数字和目标和相等,则返回1;若第一个备选数字大于目标和,则返回0;若当前备选数字小于目标和,判断当前备选数字和已有和相加是否等于目标和,若等于则直接返回1;若当前备选数字和已有和相加小于目标和,将当前备选数字填入已选列表,更新当前和;若当前备选数字和已有和相加大于目标和,若减去之前插入已选列表的数字正好等于目标和,则返回1;若减去之后小于目标和,则更新当前和及已选列表,跳出循环和下一个数相比;若减去之后还大于目标和,就得不断从已选列表中剔除最新插入的数字并更新当前和,直到当前和小于或等于目标和为止

    代码如下:

    package cn.edu.xidian.crytoll;
    
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    
    public class IsEqual {
        public int isequal(String input){
            //将输入存入字符串型数组
            String[] all=input.split(",");
            //获取第一个数字作为目标和
            int needsum=Integer.parseInt(all[0]);
            //将备选数字存入整型数组
            int[] member=new int[all.length-1];
            for(int i=0;i<member.length;i++) member[i]=Integer.parseInt(all[i+1]);
            //对备选数字数组排序
            Arrays.sort(member);
            //建立两个链表,一个存储备选数字,一个存储当前纳入选择的数字
            List<Integer> list=new LinkedList<Integer>();
            List<Integer> content=new LinkedList<Integer>();
            //将备选数字存入链表,为其设置迭代器,因为是双层循环,故需创建一个迭代器副本
            for(int i=0;i<member.length;i++) list.add(member[i]);
            Iterator it=list.iterator();
            Iterator it0=it;
            //设置已选数字的和并初始化为0
            int sum=0;
            //从第一个备选数字开始,比较每一个数字与其他每个数字的和的情况
            while(it.hasNext()){
                it0=it;
                sum=0;
                while(it0.hasNext()){
                    int temp=(int)it0.next();
                    //若第一个备选数字和目标和相等,则返回1
                    if(temp==needsum) return 1;
                    //若第一个备选数字大于目标和,则返回0
                        if(temp>needsum) return 0;
                        //若当前备选数字小于目标和
                        if(temp<needsum){
                            //判断当前备选数字和已有和相加是否等于目标和,若等于则直接返回1
                            if(temp+sum==needsum) return 1;
                            //若当前备选数字和已有和相加小于目标和,将当前备选数字填入已选列表,更新当前和
                            if(temp+sum<needsum){
                                content.add(temp);
                                sum=sum+temp;
                            }
                            //若当前备选数字和已有和相加大于目标和,
                            else if(temp+sum>needsum){
                                while(content.size()>1){
                                    //若减去之前插入已选列表的数字正好等于目标和,则返回1
                                    if(temp+sum-content.get(content.size()-1)==needsum) return 1;
                                    //若减去之后小于目标和,则更新当前和,已选列表,跳出循环和下一个数相比
                                    if(temp+sum-content.get(content.size()-1)<needsum){
                                        sum=sum-content.get(content.size()-1)+temp;
                                        content.remove(content.size()-1);
                                        content.add(temp);
                                        break;
                                    }
                                    //若减去之后还大于目标和,就得不断从已选列表中剔除最新插入的数字并更新当前和,直到当前和小于或等于目标和为止
                                    else if(temp+sum-content.get(content.size()-1)>needsum){
                                        sum=sum-content.get(content.size()-1);
                                        content.remove(content.size()-1);
                                    }
                                }
                            }
                        }
                }
            }
            return 0;
        }
        public static void main(String[] args){
            String input="10,5,3,4,2";
            System.out.println(new IsEqual().isequal(input));
        }
    }

     5. 在给定字符串中找出单词( 单词由大写字母和小写字母字符构成,其他非字母字符视为单词的间隔,如空格、问号、数字等等;另外单个字母不算单词);找到单词后,按照长度进行降序排序,(排序时如果长度相同,则按出现的顺序进行排列),然后输出到一个新的字符串中;如果某个单词重复出现多次,则只输出一次;如果整个输入的字符串中没有找到单词,请输出空串。输出的单词之间使用一个空格隔开,最后一个单词后不加空格。

    思路分析:

    1)将单词门存入字符串型数组

    2)对inputs进行稳定的冒泡降序排序

    3)将长度大于一的单词加入结果字符串

    代码如下:

    package cn.edu.xidian.crytoll;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class MyWord {
        public String myword(String input,String output){
            int len=input.length();
            String temp="";
            //将单词门存入字符串型数组
            for(int i=0;i<len;i++){
                if((input.charAt(i)+"").matches("[a-zA-Z]")) temp=temp+input.charAt(i);
                if(!(input.charAt(i)+"").matches("[a-zA-Z]")) temp=temp+" ";
            }
            String[] inputs=temp.split("\s+");
            //对inputs进行稳定的冒泡降序排序
            for(int i=0;i<inputs.length-1;i++){
                for(int j=0;j<inputs.length-i-1;j++){
                    if(inputs[j].length()<inputs[j+1].length()){
                        String tempstr=inputs[j];
                        inputs[j]=inputs[j+1];
                        inputs[j+1]=tempstr;
                    }
                }
            }
            //将长度大于一的单词加入结果字符串
            for(int i=0;i<inputs.length;i++){
                if(inputs[i].length()>1&&output.indexOf(inputs[i])<0) output=output+inputs[i]+" ";
            }
            return output;
        }
        public static void main(String[] args){
            String input="DING Zhongli, academician of the Chinese Academy of Sciences (CAS) and a test";
            String output="";
            System.out.println(new MyWord().myword(input, output));
        }
    }
  • 相关阅读:
    哲学的初步认识7
    随机法解决TSP问题
    哲学的初步认识6
    dfs+dp思想的结合------hdu1078
    动态规划3-------poj1050
    动态规划2-----hdu1069
    动态规划1-----------poj1080
    js中Math.round、parseInt、Math.floor和Math.ceil小数取整小结【转】
    美术馆
    无刷新评论
  • 原文地址:https://www.cnblogs.com/cysolo/p/3666496.html
Copyright © 2020-2023  润新知