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

 

posted @ 2014-04-15 16:04  源子陌  Views(7704)  Comments(0Edit  收藏  举报