当年某大公司面试的综合编程题

题目:

解法一:

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


}

以上是我自己当时的解法记录,这道题的最短解法我同事当时记录是十几行代码,欢迎留言挑战解题!

猜你喜欢

转载自blog.csdn.net/LYX_WIN/article/details/106272405
今日推荐