仿QQ输入法诗人模式格式化字符串

仿QQ输入法-诗人模式-格式化字符串

直接上代码吧,没啥好说的,

关键:如何计算出分成列,每列的高度是多少

package ;

import android.content.Context;

import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

/**
 * createTime: 2020/3/19.11:26
 * updateTime: 2020/3/19.11:26
 * author: singleMan.
 * desc: 诗人模式格式化字符串
 */
public class BardFormatUtil {

    private static final int MAX_ROW_LENGTH = 7;//普通模式下一列最大的高度

    public static String format(Context context, String input){
        if(input.contains(" ")){
            return input;
        }
        input = input.replace("\n", "").trim();
        String oneSymbolStr = context.getString(R.string.a4);
        StringBuilder sb =new StringBuilder();

        List<List<String>> lists = new ArrayList<>();
        //如果输入的是带有标准标点符号的,优先按照标点符号分组
        if(hasSymbol(input) && !hasConsecutiveSymbol(input)){
            List<String> bdSplit = splitBySymbol(input);
            for(String s : bdSplit){
                List<String> item = new ArrayList<>();
                for(char c : s.toCharArray()){
                    item.add(String.valueOf(c));
                }
                lists.add(item);
            }
        }else {
            char[] chars = input.toCharArray();
            int length = chars.length;
            List<String> mList = new ArrayList<>();
            for(char c : chars){
                mList.add(String.valueOf(c));
            }
            //
            int x = smartCompute(length);
            while (Math.ceil(length / x) > MAX_ROW_LENGTH){
                x += smartCompute(Math.ceil(length / x));
            }
            System.out.println("Input:"+input+"分:"+x);
            List<List<String>> list = mSubList(mList, x);
            lists.addAll(list);
        }

        int maxLength = lists.get(0).size();
        for (int i = 0; i < lists.size(); i++){
            if (maxLength < lists.get(i).size()){
                maxLength = lists.get(i).size();
            }
        }
        for(int a=0;a < maxLength; a++){
            for(int i = lists.size()-1; i>=0; i--){
                List<String> zu = lists.get(i);
                if(a < zu.size()){
                    String s = zu.get(a);
                    switch (hasSymbolCount(s.charAt(0))){
                        case 1:
                            sb.append(oneSymbolStr);
                            sb.append(oneSymbolStr);
                            sb.append(s);
                            sb.append(oneSymbolStr);
                            break;
                        case 2:
                            sb.append(oneSymbolStr);
                            sb.append(s);
                            sb.append(oneSymbolStr);
                            break;
                        case 4:
                            sb.append(s);
                            break;
                    }

                    if(i > 0) {
                        sb.append(" ");
                    }
                }else {
                    sb.append(" "+" ");
                }
            }
            if(a < maxLength -1) {
                sb.append("\n");
            }
        }
        System.out.println("结果:\n"+sb.toString());
        System.out.println("---------------------------");
        return sb.toString();

    }


    //
    private static int smartCompute(double totalLength){
        if(totalLength <= 5d){
            return 1;
        }
        if(totalLength % 5d == 0d){
            return (int) Math.ceil(totalLength / 5d);
        }
        if(totalLength % 7d == 0d){
            return (int) Math.ceil(totalLength / 7d);
        }
        return 2;
    }

    /**
     * 根据分n组截取字符串到list
     * @param source
     * @param n     分成几组
     * @return
     */
    private static List<List<String>> mSubList(List<String> source, int n) {
        List<List<String>> result = new ArrayList<List<String>>();
        int oneSize = (int) Math.ceil(Double.valueOf(source.size()) / Double.valueOf(n));
        System.out.println("一个:"+oneSize);
        for(int i = 0;i < n; i++){
            int start = i * oneSize;
            int end = (i+1) * oneSize;
            if(end <= source.size()){
                result.add(source.subList(start,end));
            }else {
                result.add(source.subList(start,source.size()));
            }
        }
        return result;
    }

    /**
     * 判断标点符号所占的宽度  单位:1/4 空格
     * @param c
     * @return
     */
    private static int hasSymbolCount(char c){
        if (Character.getType(c) == Character.OTHER_LETTER || isChinesePunctuation(c)) {
            return 4;
        } else if (Character.isDigit(c)) {
            return 2;
        } else if (Character.isLetter(c)) {
            return 2;
        } else {
            return 1;
        }
    }


    /**
     * 是否有两个相邻的标点符号
     * @param str
     * @return
     */
    private static boolean hasConsecutiveSymbol(String str){
        List<Integer> indexList = takeOutSymbol(str);
        for(int i = 0;i < indexList.size()-1;++i){
            System.out.println("标点::"+(indexList.get(i+1) - indexList.get(i)));
            if(indexList.get(i+1) - indexList.get(i) == 1){
                System.out.println("连续标点");
                return true;
            }
        }
        return false;
    }

    /**
     * 获取到所有的标点的字符
     * @param str
     * @return
     */
    private static List<Integer> takeOutSymbol(String str){
        List<Integer> list = new ArrayList<>();
        int index = 0;
        for(char c : str.toCharArray()){
            if(!(Character.getType(c) == Character.OTHER_LETTER)
                    && !(Character.isDigit(c))
                    && !(Character.isLetter(c))){
                list.add(index+1);
            }
            index++;
        }
        if(!list.contains(str.length())){
            list.add(str.length());
        }
        System.out.println(JSON.toJSONString(list));
        return list;
    }

    // 判断char 是否为中文字符
    private static boolean isChinesePunctuation(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
                || ub == Character.UnicodeBlock.VERTICAL_FORMS) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 判断有没有标点符号
     * @param s
     * @return
     */
    private static boolean hasSymbol(String s) {
        boolean b = false;
        String tmp = s;
        tmp = tmp.replaceAll("\\p{P}", "");
        if (s.length() != tmp.length()) {
            b = true;
        }
        return b;
    }

    /**
     * 根据标点符号截取诗句
     * @param str
     * @return
     */
    private static List<String> splitBySymbol(String str){
        StringBuilder sb = new StringBuilder(str);
        List<Integer> splitSymbolList = takeOutSymbol(str);
        List<String> list = new ArrayList<>();
        if(splitSymbolList.size() == 0){
            list.add(str);
            return list;
        }
        int def = 0;
        for(int index : splitSymbolList){
            int indexStart = def;
            int indexEnd = index;
            def = indexEnd;
            String substring = sb.substring(indexStart, indexEnd);
            System.out.println("add:"+substring);
            list.add(substring);
        }
        return list;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值