zoukankan      html  css  js  c++  java
  • 小米面试

    linux命令处理文本:

    awk 将文本文件的内容按行读取,并可以指定分割符号,然后打印出具体某列的值。主要是用来处理列的。例如,某个data文件有多行,每行的字段以分号隔开,现要求打印出第3列的信息:cat data | awk -F ';' '{print $3}'      或者    awk -F ';' '{print $2}' data        (-F指定分隔符)

    sed命令也是处理每一行,它主要是对每一行的内容进行替换,但是它并没有修改源文件的内容,只是把修改后的内容输出而已。例如:将文本data中每一行中出现book的单词换成books:

    sed 's/book/books/g' data (如果没有g,只能匹配并替换第一次出现的单词,如果有g,则全部替换)。sed -i 's/book/books/g' data 如果加了-i参数,则直接在文本中替换内容。

    sort可以对每一行进行排序(按照首字母升序排序),uniq可以去除重复的行,但是必须是相邻的,所以通常需要结合sort命令和uniq命令一起使用。uniq -c 可以输出每行出现的次数(-c 代表count),sort -r 可以逆序排序(-r 代表reverse),head命令默认输出前10行,如果指定输出3行,则head -3。例如,某个data文件有多行,每行有一个单词,输出出现次数top 10 的单词:cat data | sort | uniq -c | sort -r | head 

    vi编辑一个文本,如果要在文本中显示每一行的行号,则

    :set nu

    算法题目:

    1.有一个一维数组int a[100],里面存储的是1到100的这100个数,不过是乱序存储;这时把其中某一位置的数值改成-1;请用最优的空间复杂性和时间复杂性求出该位置和值, 请写出代码, 语言不限。

    思路:遍历数组得到-1的位置并记录,同时把非-1的值相加得到sum

     void find(int[] nums) {
            int sum=0, idx=-1;
            for(int i=0;i<nums.length;i++){
                if(nums[i]==-1){
                    idx=i;
                }else{
                    sum+=nums[i];
                }
            }
            System.out.println(5050-sum);
            System.out.println(idx);
        }

    2.有两个String类型的变量a, b, a的长度大于b, 两个变量都是由数字组成且长度均大于100, 求字符串变量代表的数字的差, 禁止使用java的BigInt等类似的类型.

    public class Main {
        public static void main(String[] args) {
            String a="10465";
            String b="687";
            System.out.println(minus(a,b));
        }
     
        //将String(逆序)转换成数组,为数组每一位相减做准备
        static int[] stringToArray(String str){
            int length=str.length();
            int[] arr=new int[length];
            for(int i=0;i<str.length();i++){
                //char类型的数字,通过这种方式变成int类型的数字
                arr[i]=str.charAt(str.length()-1-i)-'0';
            }
            return arr;
        }
            
        //将数组(逆序)转换成String作为结果输出
        static String arrayToString(int[] a){
            StringBuffer sb=new StringBuffer();
            int i=a.length-1;
            //如果数组最末尾有0,则需要删除掉
            while(i>=0 && a[i]==0 ){
                i--;
            }
            for(;i>=0;i--){
                sb.append(a[i]);
            }
            return sb.toString();
            
        }
        private static String minus(String a, String b) {
            int[] x ;
            int[] y ;
            x=stringToArray(a);
            y=stringToArray(b);
            int jw=0;
            for(int i=0;i<y.length;i++){
                //此处一定要加上进位
                x[i]=x[i]+jw-y[i];
                if(x[i]<0){
                    jw=-1;
                    x[i]+=10;
                }else{
                    jw=0;
                }
            }
            int j=y.length;
            //如果第y位结束,则需要判断第y位之后的数字该怎么处理
            while(jw == -1){
                x[j]+=jw;
                if(x[j]<0){
                    x[j]+=10;
                    j++;
                }else{
                    jw=0;
                }
            }
            return arrayToString(x);
        }
    
    
    }

    3.如何判断一个单链表是否有环?
    思路:设置两个快慢指针fast、slow,fast每次走两步,slow每次走一步,如果两个指针在将来某个时刻会相遇,则说明有环。
    class Node{
            public int value;
            public Node next;
        }
    
    //传入参数为一个指针,该头指针即代表整个链表
        public  boolean hascycle(Node head) {
            Node fast,slow;
            slow=fast=head;
            while(fast!=null && fast.next!= null){
                fast=fast.next.next;
                slow=slow.next;
                if(fast==slow){
                    return true;
                }
            }
            return false;
        }
    
    
    

    4.有一个非负整数数组,拼接起来组成小数点之后的部分,目标是拼接成一个最小的小数,String格式输出。

    例如:[74,8,23,5]输出“0.235748”

    [74,7,79,5]输出“0.574779”

    思路:如何获得数字的每一位呢?先将数字转化成String类型的,然后通过charAt()获得每一位.

    此题也需要技巧,不能暴力破解:即通过重写compare方法,重新定义数字的排序规则。

    private static String calculateMin(int[] arr) {
            List<String> list=new ArrayList<String>();
            StringBuffer sb=new StringBuffer();
            sb.append("0.");
            for(int i=0;i<arr.length;i++){
    //将int转换成String list.add(String.valueOf(arr[i])); } Collections.sort(list,
    new Comparator<String>() { public int compare(String o1, String o2) {
    //得到两个数中较大的那个值
    int len=Math.max(o1.length(), o2.length()); for(int i=0;i<len;i++){
    //此步最重要,如果位数相同,则一位一位比较,如果不同(例如o1比o2长),那么之后比较o1的下一位与o2的第0位。
    char ca=o1.charAt(i>(o1.length()-1)?0:i); char cb=o2.charAt(i>(o2.length()-1)?0:i); if(ca!=cb){ return ca>cb?1:-1; } } return 0; } }); for(String s:list){ sb.append(s); } return sb.toString(); } }

    5.歌德巴赫猜想:任何一个大于4的偶数,都可以拆成两个质数的和。现在希望你在十万的范围内验证歌德巴赫猜想。如果猜想成立,输出OK,否则输出具体的反例。

    思路:小学生的做法是,首先判断一个数a是否为质数(2,3,5,7,11,13,15,17...),让i从2增加到a/2(因为除数如果比被除数的一半还要大的,一定不能被整除),如果a%i==0(能整除)则说明a不是质数。如果a为质数,然后再判断偶数M-a是否也为质数。此种方法时间复杂度很高,因为除法在计算机中速度是最慢的,而且所有数字在判断为质数之后,还会一遍又一遍的进行判断。

    大学生的做法是,用一个boolean数组保存每一位的值,如果第i位是质数则为T,否则为F,然后再将所有质数保存到素数表list中。

    专家的做法是,费马小定理。

    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        static final int N = 100000;
    //boolean数组
    static boolean[] prime = new boolean[N + 1];
    //素数表
    static List<Integer> plist = new ArrayList<Integer>();
    //首先获得100000以内的所有质数
    static void getPrime() { int i, j; prime[0] = false; prime[1] = false; prime[2] = true; plist.add(2);
    //先把所有偶数置为F
    for (i = 4; i <= N; i += 2) prime[i] = false;
    //把所有奇数质为T
    for (i = 3; i <= N; i += 2) prime[i] = true; i = 3; while (i <= N) {
    //从3开始,遇到奇数则加入到plist,遇到偶数则跳过
    while (i <= N && !prime[i]) i++; if (i <= N) plist.add(i);
    //如果i是质数,就把i的所有倍数全部置为F
    for (j = i + i; j <= N; j += i) { prime[j] = false; } i++; } } public static void main(String[] args) { getPrime(); for (int i = 6; i <= N; i += 2) { boolean found = false; for (int j = 0; j < plist.size(); j++) { int p = plist.get(j); if (i - p < 0) break;
    //判断一个数是否为质数,直接通过boolean判断
    if (prime[i - plist.get(j)]) { found = true; break; } } if (!found) { System.out.println(i); return; } } System.out.println("OK"); } }

    6.判断两个单向链表是否相交.

    1)如果两个链表都没有环,则说明是两条线性链,如果相交,只可能是Y型,不可能为X型。

    首先遍历两个链表,记下两个链表的长度,长链表从起点先前进dif步,然后两个链表再一起前进,每次一步,相遇的第一个点即为相交的第一个点。

    2)如果两个链表都有环,则不可能是环与环相交,只可能是两条线接一个圆。

    3)如果一个链表有环,另外一个没有环,则必定不相交。

    如何找到环的入口点?

    head指针每次走一步,encounter指针也每次走一步,他们会在Entry(入口点)相遇。

    证明:设慢指针slow每次走一步,快指针fast每次走两步,快慢指针的相遇点为encounter,环的入口点为Entry,head到Entry的距离为x,Entry到encounter的距离为y,r为环的长度。

    当快慢指针相遇时,慢指针走的距离为s,快指针走的距离为2s,有

    x+y=s

    s+nr=2s

    所以x+y=nr,刚好构成一个圆(假设n=1的话)。所以head指针走x,encounter指针也走x,刚好在Entry相遇。

    Node findCycleEntry(Node head,Node encounter){
    
           while(head!=encounter){
    
                  head=head.next;
    
                  encounter=encounter.next;
    
           }
    
           return head;
    
    }

    7.面板:

    1  2  3

    4  5  6

    7  8  9

    0  D

    显示屏:

    123

    一百二十三

    要求:当面板中按顺序点击1,2,3时,显示屏对应显示两行,123和一百二十三,D是回退键,如果此时点击回退键,则显示12和十二。

    写程序实现该功能,面板点击可以认为是标准输入,显示屏输出可以认为是标准输出。

    import java.util.Scanner;
    
    public class Main {
        static long getValue() {
            Scanner scan = new Scanner(System.in);
            String str = scan.nextLine();
            long num = 0;
            //将字符串转换成long类型的整数,因为输入可能有回退键D
            for (int i = 0; i < str.length(); i++) {
                char ch = str.charAt(i);
                if (ch >= '0' && ch <= '9') {
                    num = num * 10 + ch - '0';
                } else {
                    num = num / 10;
                }
    
            }
            return num;
        }
            
            通过StringBuilder组合字符串
        private static String translateToChinese(String s) {
            String[] unitArray = { "", "十", "百", "千", "万", "十", "百", "千", "亿", "十",
                    "百", "千" };
            String[] numArray = { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
            StringBuilder sb = new StringBuilder();
            for (int i = s.length() - 1; i >= 0; i--) {
                int num = s.charAt(i) - '0';
                if (num != 0) {
                    if (unitArray[s.length() - i - 1].equals("亿")
                            && sb.charAt(0) == '万') {
                        sb.setCharAt(0, '亿');
                    } else {
                        //先放单位
                        sb.insert(0, unitArray[s.length() - i - 1]);
                    }
                    //再放数字
                    sb.insert(0, numArray[num]);
                } else {
                    //处理数字中夹杂着零的情况
                    if (sb.length() != 0 && sb.charAt(0) != '零'
                            && sb.charAt(0) != '万' && sb.charAt(0) != '亿') {
                        sb.insert(0, numArray[num]);
                    }
                    if (unitArray[s.length() - i - 1].equals("万")
                            || unitArray[s.length() - i - 1].equals("亿")) {
                        if (sb.charAt(0) == '万') {
                            sb.setCharAt(0, '亿');
                        } else {
                            sb.insert(0, unitArray[s.length() - i - 1]);
                        }
                    }
                }
    
            }
            //如果是12,要求打印出十二,而不是一十二
            if (sb.length() == 3 && sb.charAt(0) == '一') {
                sb.deleteCharAt(0);
            }
    
            return sb.toString();
        }
    
        public static void main(String[] args) {
            while (true) {
                long value = getValue();
                String s = String.valueOf(value);
                //边界值判断
                if (s.length() > 12) {
                    System.out
                            .println("exceed the limit of length,please input a new number");
                    continue;
                }
                String chinese = translateToChinese(s);
                System.out.println(value);
                System.out.println(chinese);
            }
    
        }
    
    }

     

  • 相关阅读:
    Hadoop集群(三) Hbase搭建
    Hadoop集群(二) HDFS搭建
    Hadoop集群(一) Zookeeper搭建
    Redis Cluster 添加/删除 完整折腾步骤
    Redis Cluster在线迁移
    Hadoop分布式HA的安装部署
    Describe the difference between repeater, bridge and router.
    what is the “handover” and "soft handover" in mobile communication system?
    The main roles of LTE eNodeB.
    The architecture of LTE network.
  • 原文地址:https://www.cnblogs.com/james111/p/7466517.html
Copyright © 2011-2022 走看看