Wepay OA

√base10
√可以每1000用逗号分位,要出现就都出现 //大概就是for循环,然后必须要用i + 3这样吧

√必须有货币符号作为前缀:$€¥
√负数的表示:负号或者括号,但是不能重复出现。负号在货币前面

√$€的分币可以有小数点+两位小数(有小数点的话,就必须制定后面的小数),¥没有小数点
√不能有前导0,除非是0或者0.几的$€
// 0
// $€0.25
// -$€0.25
// ($€0.25)
//总结就是$€0.可以,$€0不行


√不能有前导空白、尾随空白
√不能有其它的无效字符

应该true
$450
-€23
(¥2400)
$4,500.00
€0.25

应该false的
cat
£25
$45,0
(€350
(-$3.50)
¥120.00
$-50
€43.25
$65.
€82.1
48.50
¥1200,000

 

 

package wePayOA;

import java.util.*;

public class Solution {
    public boolean isCurrency(String s) {
        if (s == null) return false;
        
        if (s.length() != s.trim().length())
            return false;
        int n = s.length();
        
        if (n == 0) return false;
        
        // flags 定义一些标志
        int signCount = 0;
        int leftBracketCount = 0;
        int rightBracketCount = 0;
        int commaIdx = 0;
        int preCommaIdx = 0;
        boolean hasNum = false;
        boolean hasPoint = false;
        Set<String> symbols = new HashSet<>(Arrays.asList("$", "€", "¥")); 
        
        //必须有货币符号作为前缀:$€¥。0 || 第一位是 || 负号就第二位是
        if ((s.length() == 1 && !s.equals("0")) || 
            (s.length() == 2 && !symbols.contains(Character.toString(s.charAt(0)))) ||
            (s.length() > 2 && (s.contains("(") || s.contains("-")) && !symbols.contains(Character.toString(s.charAt(1)))) ||
            (s.length() > 2 && (!s.contains("(") && !s.contains("-")) && !symbols.contains(Character.toString(s.charAt(0))))            
             ) 
            return false;

        for (int i = 0; i < n; i++) {
            char c = s.charAt(i);
            
            // invalid character 不属于有效的字符,可以直接滚蛋了
            if (!isValid(c)) return false;
            
            // digit is always fine 数字的情况都可以标记hasNum = true
            if (c >= '0' && c <= '9') hasNum = true;            
            
            // decimal place 小数点的情况
            if (c == '.') {
                // . cannot appear twice
                //小数点不能出现两次
                if (hasPoint) return false;
                // if . is the last one, digits must be in front of it, e.g. "7."
                //小数点如果是最后一位,前面必须有数字
                if (i == n - 1 && !hasNum) return false;
                
                hasPoint = true;
            }

            //美元的情况
            if (c == '$') {
                //$€ 不是第0 1位不行
                if (i != 0 && i != 1) return false;
                //如果有小数点 不是2位小数不行
                if (s.contains(".")) {
                    if ((n - s.indexOf(".") != 3) && 
                        (!s.contains(")"))) 
                        return false;
                    if ((n - s.indexOf(".") != 4) && 
                            (s.contains(")"))) 
                        return false;
                }

                //前置0:$0.可以,$0不行
                if (s.contains("$0") && !s.contains("$0."))
                    return false;
            }

            //欧元的情况
            if (c == '€') {
                //$€ 不是第0 1位不行
                if (i != 0 && i != 1) return false;
                //如果有小数点 不是2位小数不行
                if (s.contains(".")) {
                    if ((n - s.indexOf(".") != 3) && 
                        (!s.contains(")"))) 
                        return false;
                    if ((n - s.indexOf(".") != 4) && 
                            (s.contains(")"))) 
                        return false;
                }

                //前置0:€0.可以,€0不行
                if (s.contains("€0") && !s.contains("€0."))
                    return false;
            }

            //日元不能有小数点
            if (c == '¥') {
                if (s.contains(".")) return false;
            }
            
            // signs 减号的情况 
            if (c == '-') {
                // no more than 2 signs 不能超过2个加减号
                if (signCount == 2) return false;
                // sign cannot be the last one 最后一位不能是加减号
                if (i == n - 1) return false;
                //其实只能是第0位吧!
                if (i != 0) return false;

                signCount++;
            }

            //括号的情况
            //先把左右括号的数量分别数清楚
            if (c == '(') {
                leftBracketCount++;
            }

            if (c == ')') {
                rightBracketCount++;
            }

            //括号的情况,左括号只能出现在第一位,不能有负号,要配对
            if (c == '(') {
                if (i != 0) return false;
                if (signCount > 0) return false;
                //提前有右括号了,不行
                if (rightBracketCount > 0) return false;
            }

            //括号的情况,右括号只能出现在最后一位,不能有负号,要配对
            if (c == ')') {
                if (i != n - 1) return false;
                if (signCount > 0) return false;
                //左边等于0,不行
                if (leftBracketCount == 0) return false;
            }

            //左右括号超过1个也不行
            if (leftBracketCount > 1 || rightBracketCount > 1) {
                return false;
            }

            //逗号的情况,记录第一个index,后面的index不等于它加三就不行
            if (c == ',') {
                preCommaIdx = commaIdx;
                commaIdx = i;

                //都动了的情况下
                if (preCommaIdx != 0) {
                    if ((commaIdx - preCommaIdx) != 3) {
                        return false;
                    }
                }
            }
        }

        //最后再检查一下到逗号或者到末尾的距离
        if ((commaIdx != 0) && (!s.contains(".")) && (n - commaIdx != 3)) 
            return false;
        if ((commaIdx != 0) && (s.contains(".")) && (s.indexOf('.') - commaIdx != 4)) 
            return false;
        
        //最后检查一下左右括号的数量是否相等
        if (leftBracketCount != rightBracketCount) {
            return false;
        }
            
        return true;
    }
    
    //允许的所有字符范围,加上括号、逗号、三个货币符号吧
    boolean isValid(char c) {
        return c == '.' || c == '-' || (c >= '0' && c <= '9') || c == ',' || c == '(' || c == ')' || c == '$' || c == '€' || c == '¥';
    }
}
View Code

 

原文地址:https://www.cnblogs.com/immiao0319/p/14131257.html