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);
            }
    
        }
    
    }

     

  • 相关阅读:
    TSQL编程的全局变量
    一、读大学,究竟读什么?
    受用一生的心理寓言
    字符串函数
    android wait notify实现线程挂起与恢复
    Java Thread.interrupt 中断JAVA线程
    android实现文件下载功能的3种方法
    Android startActivityForResult 和 setResult的使用
    Android 软键盘盖住输入框的问题
    Android蓝牙操作
  • 原文地址:https://www.cnblogs.com/james111/p/7466517.html
Copyright © 2011-2022 走看看