常见机试题分析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));

    }

}

 

你可能感兴趣的:(java)