zoukankan      html  css  js  c++  java
  • 百度笔试题

    笔试题

    下面是来自于百度的编程笔试题,感兴趣的同学可以先自己想想解题思路:

    你现在有一个文件,文件中顺序存有N个记录,R1,R2,...,RN,这些记录不是有序的,但是你知道一个整数M, 这些记录满足R1<R2<...<RM以及RM+1<RM+2<...RN.

    1. 设计一个算法或编写一个程序,将文件中的记录排序为R1',R2',...,RN',算法或程序读取文件的次数为O(N),不限内存使用

    2. 设计一个算法或编写一个程序,将文件中的记录排序为R1',R2',...,RN',算法或程序读写文件的次数为O(N),空间复杂度为O(1),亦即,你使用的内存大小和M,N均无关。

    --------------我是华丽丽的分隔线----------------

    内排序和外排序

    根据在排序过程中待排序的记录是否全部被放置在内存中,排序可以分为内排序和外排序。

    内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中。外排序是由于排序的记录个数太多,不能同时放置在内存,整个排序过程需要在内外存之间多次交换数据才能进行。

    排序算法的时间性能

    排序算法的时间开销是衡量其好坏的最重要的标志。

    在内排序中,主要进行两种操作:比较和移动。内排序算法的时间复杂度是比较次数加上移动次数的总和;

    在外排序中,除了比较和移动,还有读写文件的操作。外排序算法的时间复杂度是比较次数,移动次数以及读写文件次数的总和。

    高效率的排序算法应该是具有尽可能少的比较次数,移动次数及读写文件的次数。

    排序算法的空间性能

    评价排序算法的另一个主要标准是执行算法所需要的辅助存储空间。辅助存储空间是除了存放待排序所占用的存储空间之外,执行算法所需要的其他存储空间。

    回到笔试题

    基础知识介绍完毕,如果大家还有不明白的地方,可以先找找相关的资料参考一下。

    5.1 对题目的理解

    要解决一个问题,首先需要明确问题:

    初始条件下,有N个数据数据都存放在一个文件中,并且有一个整数M,使得这些记录满足R1<R2<...<RM以及RM+1<RM+2<...RN。举一个例子来说,对于以下10N=10)个数23471015689),M2时,分成两个序列(23)和(471015689),由于第二个序列不是依次增大的,所以不满足条件。当M5时,分成两个序列234710)和(15689)都是依次增大,因此满足条件。

    然后我们需要将这些记录排序,其实就是合并这两个子序列。以例子来看,其实就是需要把234710)和(15689)两个有序序列合并成(12345678910)一个有序序列。细心的同学可能会想起归并排序。是的,这个合并过程其实是归并排序中的一个子步骤。

    题目的要求,第一个要求是读取文件次数为O(N),但是不限制内存的使用;第二个要求是读取文件次数为O(N),但是空间复杂度为O(1)。区别在于限不限制内存的使用。

    如果不限制内存的使用,我们可以将文件中的内容全部读取到内存中,保存为数组,然后再对数组进行排序;如果限制内存的使用,我们可以采用外排序来解决这个问题,外排序一般会借助于文本文件。

    最后的实现代码(java)如下:

    /**

     * Sample code

     */

    public class FileRecordSortMain {

        final static String SOURCE_FILE_NAME = "file.txt";

        final static String TEMP_FILE_NAME1 = "file_temp1.txt";

        final static String TEMP_FILE_NAME2 = "file_temp2.txt";

        final static int N = 10;

        final static int M = 5;

        /**

         * 第一种方法:

         * 将原文件中的记录顺序读取到内存中,以数组保存,然后以M为分隔将

         * 数组看为两组,互相比较两组元素之后输出,最后输出剩下的元素。

         * 

         * 性能分析:

         * 1. 时间复杂度是O(N),因为读取原文件N次,比较小于4N次,输出N次,

         * 加在一起的数量级是N的一次方

         * 2. 空间复杂度是N,因为将原文件中的记录事先读取到内存中,以数组

     * 保存,这个辅助空间的长度是N

         */

        static void sortInManner1() {

            //1. 将原文件中的记录顺序读取到内存中,以数组保存

            BufferedReader reader = getFileReader(SOURCE_FILE_NAME);

            int[] arry = new int[N];

            

            String str = "";

            int index = 0;

            try {

                while ((str=reader.readLine()) != null) {

                    arry[index++] = Integer.valueOf(str);

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

            

            //2. 将index<M数组元素看为一组,将index>=M的数组元素看为另一组

            //3. 互相比较两组元素,输出较小者,然后将较小者所在组的index+1

            int i = 0;

            int j = M;

            

            System.out.println("Sort Manner 1 Result:");

            

            while (i<M && j<N) {

                if (arry[i] < arry[j]) {

                    System.out.print(arry[i++] + " ");

                } else {

                    System.out.print(arry[j++] + " ");

                }

            }

            

            //4. 输出比较之后剩下来的元素

            while (i < M) {

                System.out.print(arry[i++] + " ");

            }

            

            while (j < N) {

                System.out.print(arry[j++] + " ");

            }

            

            System.out.println();

        }

        

        /**

         * 第二种方法:

         * 将原文件中的记录以M分隔,读取后保存到两个临时文件file_temp1.txt

         * 和file_temp2.txt中,然后将这两个临时文件中保存的数组看为两组,

         * 分别从这两个临时文件中读取元素,比较后输出,最后读取并输出剩下

         * 的元素。

         * 

         * 性能分析:

         * 1. 时间复杂度是O(N),因为读取原文件N次,写临时文件N次,读取临时

     * 文件N次,比较小于6N次,输出N次,加在一起是N的一次方

         * 2. 空间复杂度是1(与M,N均无关系),因为:

         * 在步骤1中,使用1个String和1个int作为辅助空间

         * 在步骤2,3,4中,使用1个String和1个String作为辅助空间,加在一起

     * 与M,N均无关系

         */

        static void sortInManner2() {

            //1. 将原文件中的记录以M分隔,读取后保存到两个临时文件

            //file_temp1.txt和file_temp2.txt

            BufferedReader sourceReader = getFileReader(SOURCE_FILE_NAME);

            BufferedWriter writer1 = getFileWriter(TEMP_FILE_NAME1);

            BufferedWriter writer2 = getFileWriter(TEMP_FILE_NAME2);

            

            String str = "";

            int index = 0;

            try {

                while ((str=sourceReader.readLine()) != null) {

                    if (index < M) {

                        writer1.write(str+"\n");

                    } else {

                        writer2.write(str+"\n");

                    }

                    ++index;

                }

            } catch (IOException e) {

                e.printStackTrace();

            } finally {

                try {

                    writer1.close();

                    writer2.close();

                } catch (IOException e) {

                    e.printStackTrace();

                }

            }

            

            //2. 将file_temp1.txt中的元素看为一组,将file_temp1.txt中的元

            //素看为另一组

            //3. 互相比较两组元素,输出较小者,然后继续从较小者所在的临时

            //文件中读取元素

            BufferedReader tempReader1 = getFileReader(TEMP_FILE_NAME1);

            BufferedReader tempReader2 = getFileReader(TEMP_FILE_NAME2);

            String numTemp1 = "";

            String numTemp2 = "";

            try {

                numTemp1 = tempReader1.readLine();

                numTemp2 = tempReader2.readLine();

                System.out.println("Sort Manner 2 Result:");

                

                while (numTemp1!=null && numTemp2!=null) {

                    if (Integer.valueOf(numTemp1) < 

                            Integer.valueOf(numTemp2)) {

                        System.out.print(numTemp1 + " ");

                        numTemp1 = tempReader1.readLine();

                    } else {

                        System.out.print(numTemp2 + " ");

                        numTemp2 = tempReader2.readLine();

                    }

                }

                

                //4. 输出比较之后剩下来的元素

                while (numTemp1 != null) {

                    System.out.print(numTemp1 + " ");

                    numTemp1=tempReader1.readLine();

                }

                

                while (numTemp2 != null) {

                    System.out.print(numTemp2 + " ");

                    numTemp2=tempReader2.readLine();

                }

            } catch (IOException e) {

                e.printStackTrace();

            }

            

            System.out.println();

        }

        

        public static void main(String[] args) {

            sortInManner1();

            sortInManner2();

        }

        

        static BufferedReader getFileReader(String filename) {

            String souceFileAbsoluteName = getAbsolutePathName() + 

                    File.separator + filename;

            

            InputStream is = null;

            BufferedReader reader = null;

            try {

                is = new FileInputStream(souceFileAbsoluteName);

                reader = new BufferedReader(new InputStreamReader(is));

            } catch (FileNotFoundException e) {

                e.printStackTrace();

            }

            

            return reader;

        }

        

        static BufferedWriter getFileWriter(String filename) {

            String souceFileAbsoluteName = getAbsolutePathName() + 

                    File.separator + filename;

            

            OutputStream os = null;

            BufferedWriter writer = null;

            try {

                os = new FileOutputStream(souceFileAbsoluteName);

                writer = new BufferedWriter(new OutputStreamWriter(os));

            } catch (FileNotFoundException e) {

                e.printStackTrace();

            }

            

            return writer;

        }

        

        static String getAbsolutePathName() {

            File directory = new File("");

            return directory.getAbsolutePath();

        }

    }

  • 相关阅读:
    PAT甲级——1110 Complete Binary Tree (完全二叉树)
    PAT甲级——1111 Online Map (单源最短路经的Dijkstra算法、priority_queue的使用)
    PAT甲级——1112 Stucked Keyboard (字符串+stl)
    PAT甲级——1114 Family Property (并查集)
    PAT甲级——1118 Birds in Forest (并查集)
    Pre- and Post-order Traversals(先序+后序序列,建立二叉树)
    PAT甲级——1123 Is It a Complete AVL Tree (完全AVL树的判断)
    AVL树(自平衡二叉查找树)
    PAT甲级——1126 Eulerian Path
    团队项目-选题报告
  • 原文地址:https://www.cnblogs.com/FredCong/p/2787674.html
Copyright © 2011-2022 走看看