题目描述:
清一色是麻将番种之一,指由一种花色的序数牌组成的和牌.
数字1-9,每个数字最多有4张牌
我们不考虑具体花色,我们只看数字组合。
刻子:三张一样的牌;如: 111, 222, 333, ..., 999
顺子:三张连续的牌;如: 123, 234, 345, ..., 789
对子:两张相同的牌;如: 11, 22, 33, ..., 99
需要实现一个程序,判断给定牌,是否可以和牌(胡牌)。
和牌要求:
- 麻将牌张数只能是 2, 5, 8, 11, 14
- 给定牌可以组合成,除1个对子以外其他都是刻子或顺子
举例: - "11" -> "11", 1对子,可以和牌
- "11122233" -> "111"+"222"+"33", 2刻子,1对子,可以
- "11223344567" -> "11"+"234"+"234"+"567", 1对子,3顺子,可以
-> "123"+"123"+"44"+"567", 另一种组合,也可以
输入描述:
合法C字符串,只包含'1'-'9',且已经按从小到大顺序排好;字符串长度不超过15。同一个数字最多出现4次,与实际相符。
输出描述:
C字符串,"yes"或者"no"
示例1
输入
2244
输出
24 //此处是试题原本模样,应该输出no

思路:

重点在于理解和牌时出牌的顺序问题,代码实现采用了组合分类思想,暂时未想到技巧性的方式

代码:
import java.util.Scanner; import java.util.regex.Pattern; /** * Created by
1443754157@qq.com since 2018年9月12日 下午11:23:21. */ public class Mahjong { static
final String duizi =
"[1][1]|[2][2]|[3][3]|[4][4]|[5][5]|[6][6]|[7][7]|[8][8]|[9][9]"; static final
String shunzi =
"[9][8][7]|[8][7][6]|[7][6][5]|[6][5][4]|[5][4][3]|[4][3][2]|[3][2][1]"; static
final String kezi =
"[1]{3}|[2]{3}|[3]{3}|[4]{3}|[5]{3}|[6]{3}|[7]{3}|[8]{3}|[9]{3}"; public static
void main(String[] args) { Mahjong mahjong = new Mahjong(); Scanner scanner =
new Scanner(System.in); while (scanner.hasNextLine()) { String input =
scanner.nextLine(); int len = input.length(); if (len > 15 || len < 1 ||
!input.matches("^[1-9]{1,15}$")) { System.out.println("输入数据有误,no"); continue; }
// 可以和牌的输入数据长度只有2/5/8/11/14 if (len == 2 || len == 5 || len == 8 || len == 11
|| len == 14) { String reverse = new StringBuilder(input).reverse().toString();
System.out.println(mahjong.judge(reverse) ? "yes" : "no"); } else {
System.out.println("输入数据长度无法胡牌,no"); } } scanner.close(); } /** *
判断是否可以和牌,输入数据已经过校验且被反转 * * @param data * @return */ public boolean judge(String
data) { System.out.println(data); if (data.length() == 0) { return true; } else
{ // 判断输入是否有对子/刻子/顺子,若有则移除 boolean hasDuizi = hasDuizi(data); boolean hasShunzi
= hasShunzi(data); boolean hasKezi = hasKezi(data); if (hasDuizi) { // 有对子 if
(hasShunzi) { // 有顺子 if (hasKezi) { // 有刻子--->三种都有 String middle =
data.replaceAll(shunzi, ""); return judge(middle); } else { // 没有刻子--->只有对子和顺子
String middle = data.replaceAll(duizi, ""); return judge(middle); } } else { //
没有顺子 // 1.有刻子--->只有对子和刻子eg:45556/22266 2.没有刻子--->只有对子 String middle =
data.replaceAll(duizi, ""); return judge(middle); } } else { // 没有对子 if
(hasShunzi) { // 有顺子 // 1.有刻子--->只有顺子和刻子 2.没有刻子--->只有顺子 String middle =
data.replaceAll(shunzi, ""); return judge(middle); } else { // 没有顺子 if
(hasKezi) { // 有刻子--->只有刻子 String middle = data.replaceAll(kezi, ""); return
judge(middle); } else { // 没有刻子--->三种都没有 return false; } } } } } public boolean
hasDuizi(String data) { return Pattern.compile(duizi).matcher(data).find(); }
public boolean hasShunzi(String data) { return
Pattern.compile(shunzi).matcher(data).find(); } public boolean hasKezi(String
data) { return Pattern.compile(kezi).matcher(data).find(); } }
 

技术
©2019-2020 Toolsou All rights reserved,
Vue页面跳转传递参数及接收关于多租户系统的思考(精华)2020年7月12日 webpack 常见插件的使用Spark SQL-编程在vue+element-ui中,select选项值动态从后台获取,同时将选中值的id传给后台的方法迷宫的最短路径之BFS算法(python实现)mybatis-config.xml设置默认值配置rk3399_android7.1调试USB蓝牙模块小结 程序员与架构师华山论道keras数据生成器--数据增强