當年某大公司面試的綜合編程題

題目:

解法一:

package sorting;

import com.sun.org.apache.xalan.internal.xsltc.compiler.util.CompareGenerator;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 實現如下函數:
 * String mostFrequentLeters(String s)
 * 該函數完成如下功能,對於輸入的字符串s,忽略大小寫,返回按照英文字母出現頻率從高到低排序的小寫字符串,
 * 對於出現次數相同的字母,按照字典序排序,如果輸入字符串不包含英文字母,返回空字符串,注意數字,標點,
 * 空格都不是英文字母
 * <p>
 * 例如:mostFrequentLeters("We Attack at Dawn"),返回"atwcdekn"
 * 解釋:在這個例子中不區分大小寫,字母'a'出現了4次,字母't'出現了3次,字母'w'出現了2次,字母'c',
 * 'd','e','k','n'均出現1次,對於次數相同的字母,按照字典序排序,例如按照字典序字母'a'排在't'之前,
 * 所有輸出結果爲"atwcdekn"。
 */
public class StreamTest {
    public static void main(String[] args) {
        mostFrequentLeters();
    }

    private static void mostFrequentLeters() {
        String str = "We Attack at Dawn";
        System.out.println("原始數據: " + str);

        String[] formatList = str.toLowerCase().split("");
        String formatStr = String.join("", formatList).replace(" ", "");
        System.out.println("格式化: " + formatStr);

        List<String> list = Arrays.stream(formatList)
                .sorted((s1, s2) -> compare(formatStr, s1, s2))
                .distinct()
                .collect(Collectors.toList());
        System.out.println("結果爲: " + String.join("", list));
    }

    // 比較頻次,頻次相同按字典序
    private static int compare(String originStr, String s1, String s2) {
        int result = charCounter(originStr, s2) - charCounter(originStr, s1);
        if (result == 0) {
            return s1.charAt(0) - s2.charAt(0); // 字典序
        }
        return result;
    }

    // 計算字符串中每個字符出現頻次
    private static int charCounter(String originStr, String targetStr) {
        int times = 0;
        for (int i = 0; originStr.length() > i; i++) {
            if (originStr.charAt(i) == targetStr.charAt(0)) {
                times++;
            }
        }
        return times;
    }
}

解法二:

package sorting;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 實現如下函數:
 * String mostFrequentLeters(String s)
 * 該函數完成如下功能,對於輸入的字符串s,忽略大小寫,返回按照英文字母出現頻率從高到低排序的小寫字符串,
 * 對於出現次數相同的字母,按照字典序排序,如果輸入字符串不包含英文字母,返回空字符串,注意數字,標點,
 * 空格都不是英文字母
 * <p>
 * 例如:mostFrequentLeters("We Attack at Dawn"),返回"atwcdekn"
 * 解釋:在這個例子中不區分大小寫,字母'a'出現了4次,字母't'出現了3次,字母'w'出現了2次,字母'c',
 * 'd','e','k','n'均出現1次,對於次數相同的字母,按照字典序排序,例如按照字典序字母'a'排在't'之前,
 * 所有輸出結果爲"atwcdekn"。
 */
public class StreamTest {
    public static void main(String[] args) {
        mostFrequentLeters();
    }

    private static void mostFrequentLeters() {
        String str = "We Attack at Dawn";
        System.out.println("原始數據: " + str);

        String[] formatList = str.toLowerCase().split("");
        String formatStr = String.join("", formatList).replace(" ", "");
        System.out.println("格式化: " + formatStr);

        List<String> list = Arrays.stream(formatList)
                .sorted((s1, s2) -> compare(formatStr, s1, s2))
                .distinct()
                .collect(Collectors.toList());
        System.out.println("結果爲: " + String.join("", list));
    }

    // 比較頻次,頻次相同按字典序
    private static int compare(String originStr, String s1, String s2) {
        int result = charCounter(originStr, s2) - charCounter(originStr, s1);
        // 字典序
        return result == 0 ? s1.charAt(0) - s2.charAt(0) : result;
    }

    // 計算字符串中每個字符出現頻次
    // 法一:
    private static int charCounter(String originStr, String targetStr) {
        int times = (int) IntStream.range(0, originStr.length())
                .filter(i -> originStr.charAt(i) == targetStr.charAt(0))
                .count();
        return times;
    }
}

解法三:

package com.company;

import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by jianwen on 2018/5/19.
 */
public class Solution {
    private static final String LOWER_STRING = "abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {

        String targetStr = "We Attack at Dawn";

        String lowerStr = lowerFormat(targetStr);

        int[] rateArray = rateArray(lowerStr);

        int[] sortArray = sortArray(rateArray);

        solution(rateArray, sortArray);

    }

    private static String lowerFormat(final String originStr) {
        if (StringUtils.isEmpty(originStr)) {
            return "";
        }
        String tmpStr = originStr.toLowerCase();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < tmpStr.length(); i++) {
            if (tmpStr.charAt(i) != ' ') {
                sb.append(tmpStr.charAt(i));
            }
        }
        System.out.println("原始數據: " + originStr);
        System.out.println("格式化數據: " + sb.toString());
        return sb.toString();
    }

    private static int[] rateArray(final String formatStr) {
        int[] rateArray = new int[26];

        List<Integer> rateList = new ArrayList<>();
        for (int i = 0; i < LOWER_STRING.length(); i++) {
            rateList.add(0);
        }
        int index = -1;
        for (int i = 0; i < formatStr.length(); i++) {
            index = formatStr.charAt(i) - 'a';
            rateArray[index]++;
            Integer rate = rateList.get(index);
            rate ++;
            rateList.set(index, rate);
        }

        List<Integer> sortList = rateList.stream().sorted((o1, o2) -> o2 - o1).collect(Collectors.toList());

        System.out.println("頻率數組: " + Arrays.toString(rateArray));
        System.out.println("排序list " +Arrays.toString(sortList.toArray()));

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < rateArray.length ; i++) {
            if (rateArray[i] != 0) {
                sb.append(LOWER_STRING.charAt(i))
                        .append(rateArray[i]).append(" ");
            }

        }

        System.out.println("頻率數組: " + sb.toString());
        return rateArray;
    }

    private static int[] sortArray(final int[] rateArray) {
        int[] sortArray = new int[26];
        int j = 0;
        for (int i = 0; i < rateArray.length; i++) {
            if (rateArray[i] != 0) {
                sortArray[j] = rateArray[i];
                j++;
            }
        }
        int temp = 0;
        for (int i = 0; i < sortArray.length; i++) {
            for (int n = 1; n < i; n++) {
                if (sortArray[n] > sortArray[n - 1]) {
                    temp = sortArray[n];
                    sortArray[n] = sortArray[n - 1];
                    sortArray[n - 1] = temp;
                }
            }
        }


        return sortArray;
    }

    private static void solution(final int[] rateArray, final int[] sortArray) {
        Set<String> stringSet = new LinkedHashSet<>();

        for (int i = 0; i < sortArray.length; i++) {
            for (int k = 0; k < rateArray.length; k++) {
                if (rateArray[k] != 0 && rateArray[k] == sortArray[i]) {
                    String key = String.valueOf((char) ('a' + k));
                    stringSet.add(key);
                }
            }
        }

        StringBuilder solutionSB = new StringBuilder();

        for (String aStringSet : stringSet) {
            solutionSB.append(aStringSet);
        }

        System.out.println("結果爲: " + solutionSB.toString());
    }


}

以上是我自己當時的解法記錄,這道題的最短解法我同事當時記錄是十幾行代碼,歡迎留言挑戰解題!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章