JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数

示例如下

至少需要九个元素:"A","B","C","D","E","F","G","H","I"

我们打印一个30*15的二维数组

刚好限制每一个元素出现50次

I    D    H    A    C    F    E    G    B    E    F    C    B    I    A
G    A    E    D    H    I    B    F    H    G    D    G    H    C    E
D    F    I    B    C    A    C    G    D    B    I    A    E    F    H
A    H    C    G    I    D    B    E    F    E    H    G    B    C    D
F    I    A    F    C    A    G    I    H    D    B    E    A    I    F
D    E    H    G    B    E    C    A    F    I    G    H    D    C    B
F    B    C    I    D    H    G    E    G    A    E    C    I    A    H
D    H    F    B    F    C    I    A    B    D    G    H    E    D    I
C    E    A    G    H    B    F    C    E    F    I    B    G    A    F
D    G    I    B    A    C    D    H    B    G    E    D    H    C    I
E    A    F    C    H    F    E    G    I    D    A    B    G    A    E
I    C    H    D    B    G    C    F    E    H    F    D    I    B    C
A    D    E    F    H    A    I    G    B    C    A    H    G    D    E
I    F    B    A    C    G    F    H    E    I    D    B    A    H    B
D    G    I    E    F    B    C    D    G    A    H    I    E    C    F
H    C    B    G    D    I    F    E    F    B    D    A    G    I    H
A    E    F    C    E    H    B    C    I    G    I    H    D    A    C
F    G    B    D    A    C    E    F    D    B    E    A    G    I    H
C    H    I    F    B    D    A    G    E    F    D    I    B    E    G
A    G    C    H    I    F    C    D    H    B    E    A    H    D    B
E    I    F    A    G    B    I    G    C    A    C    F    E    A    H
D    B    G    D    I    F    E    H    F    I    E    B    C    G    D
A    C    H    B    A    H    D    I    E    G    C    F    D    B    A
F    I    E    C    G    B    E    H    C    D    A    G    H    F    I
D    H    G    I    F    C    A    B    E    F    E    B    I    G    D
A    C    A    H    G    B    D    F    C    H    I    F    E    C    A
I    H    G    B    E    C    A    B    D    F    G    D    H    I    E
A    D    C    H    I    F    E    G    C    B    I    A    G    B    D
E    H    F    E    A    C    B    D    F    H    G    H    I    E    G
C    A    D    B    I    F    H    C    G    I    F    E    B    A    D
A_50    B_50    C_50    D_50    E_50    F_50    G_50    H_50    I_50    

代码如下:

package com.lc.array;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;

/**
 * 生成数组
 * @author Cheng
 */
public class MatrixManage {
    private Integer hight = 30;
    private Integer wide = 15;
    private Integer max = 50;
    /** 每个元素出现的个数  **/
    private TreeMap<String, Integer> keyNumMap = new TreeMap<>();
    /** 目标数组 **/
    private String[][] arr = new String[hight][wide];
    /** 每个点 可使用的元素集合 **/
    private Map<String,Set<String>> pointMap = new TreeMap<>();

    public MatrixManage(String[] keys, Integer hight, Integer wide, Integer max) {

        if((hight*wide)>max*(keys.length)){
            System.out.println("二逼,("+hight+"*" + wide + ")大于("+max+"*"+keys.length+")了,还玩毛");
            return;
        }

        this.hight = hight;
        this.wide = wide;
        this.max = max;
        this.arr = new String[hight][wide];

        for(String key :keys){
            keyNumMap.put(key, 0);
        }
    }

    private void addKeyNumMap(String key){
        keyNumMap.put(key, keyNumMap.get(key)+1);
    }

    private void subtractKeyNumMap(String key){
        keyNumMap.put(key, keyNumMap.get(key)-1);
    }

    public static void main(String[] args) {
        MatrixManage entity = new MatrixManage(new String[]{"A","B","C","D","E","F","G","H","I"},30,15,50);
        entity.print();
    }

    private void print() {

        for(int i=0;i<hight;i++){

            for(int j=0;j<wide;j++){

                while(true){

                    String pointKey = i + "_" + j;//点的key

                    if(pointMap.containsKey(pointKey)){// 是否存储过该点 

                        Set<String> pointSet = pointMap.get(pointKey);//获取该点可用的元素集合

                        subtractKeyNumMap(arr[i][j]); //更新元素的数量

                        pointSet.remove(arr[i][j]);   //删除目前的元素

                        if(pointSet.isEmpty()){//该点没有可用的元素

                            pointMap.remove(pointKey);//删除该点、后退

                            if(j==0){
                                i--;
                                j=wide-1;
                            }else{
                                j--;
                            }

                        }else{

                            TreeMap<Integer, List<String>> usableMap = getUsableMap(pointSet, false);

                            if(usableMap.isEmpty()){//该点没有可用的元素

                                pointMap.remove(pointKey);//删除该点、后退

                                arr[i][j]=null;
                                if(j==0){
                                    i--;
                                    j=wide-1;
                                }else{
                                    j--;
                                }
                            }else{
                                arr[i][j] = getKey(usableMap);
                                break;
                            }
                        }

                    }else{

                        Set<String> set = getRoundSet(i, j);//(右上方4个)环绕的数组集合

                        TreeMap<Integer, List<String>> usableMap = getUsableMap(set, true);

                        if(usableMap.isEmpty()){

                            if(j==0){
                                i--;
                                j=wide-1;
                            }else{
                                j--;
                            }

                        }else{

                            Set<String> tempSet = new HashSet<>();
                            for(List<String> l:usableMap.values()){
                                tempSet.addAll(l);
                            }

                            arr[i][j] = getKey(usableMap);

                            tempSet.remove(arr[i][j]);
                            pointMap.put(pointKey, tempSet);
                            break;
                        }
                    }
                }

                //修改元素的数量
                addKeyNumMap(arr[i][j]);
            }
        }
        printArr();
        printKeyNum();
    }

    /**
     * 获取key
     * @param usableMap
     * @return
     */
    private String getKey(TreeMap<Integer, List<String>> usableMap) {
        Map.Entry<Integer,List<String>> entry = usableMap.firstEntry();
        Random random = new Random();
        int s = random.nextInt(entry.getValue().size());
        return entry.getValue().get(s);
    }

    /**
     * 获取可用集合
     * @param treeMap
     * @param set
     * @param b 1、true set包含 2、 false set不包含
     * @return
     */
    private TreeMap<Integer, List<String>> getUsableMap(Set<String> set,boolean b) {
        TreeMap<Integer,List<String>> usableMap = new TreeMap<>();
        for(Map.Entry<String, Integer> entry:keyNumMap.entrySet()){
            if(entry.getValue() < max){
                if((b==true && !set.contains(entry.getKey())) || (b==false && set.contains(entry.getKey()))){
                    if(usableMap.get(entry.getValue())==null){
                        usableMap.put(entry.getValue(),new ArrayList<>());
                    }
                    usableMap.get(entry.getValue()).add(entry.getKey());
                }
            }
        }
        return usableMap;
    }

    /**
     * 获取周围的元素集合
     * @param i
     * @param j
     * @return
     */
    private Set<String> getRoundSet(int i, int j) {
        Set<String> set = new HashSet<>();
        for(int x=1;x>=0;x--){
            if((i-x)>=0){
                for(int y=-1;y<2;y++){

                    if(x==0 && y==0){
                        break;
                    }

                    if((j+y)>=0 && (j+y)<wide){
                        set.add(arr[i-x][j+y]);
                    }
                }
            }
        }
        return set;
    }

    /**
     * 打印数组
     */
    private void printArr() {
        for(int i=0;i<arr.length;i++){
            for(int j=0;j<arr[i].length;j++){
                System.out.print(arr[i][j]+"\t");
            }
            System.out.println();
        }
    }

    /**
     * 打印数组数
     */
    private void printKeyNum() {
        for(Map.Entry<String, Integer> entry:keyNumMap.entrySet()){
            System.out.print(entry.getKey()+"_"+entry.getValue()+"\t");
        }
    }

}

注:支持后退操作,解决了不符合条件的情况

原文地址:https://www.cnblogs.com/tusheng/p/8302071.html

时间: 2024-10-17 09:17:04

JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数的相关文章

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

任意定义一个二维数组,实现矩阵的转置——java

import java.util.Scanner; /* * 任意定义一个二维数组,编写程序实现矩阵的转置. * */ public class MatrixTransposition { public static void main(String[] args) { //create the rowNumber and columnNumber of the matrix Scanner input = new Scanner(System.in); System.out.println("

返回一个二维数组最大联通子数组的和

一.题目 输入一个二维整形数组,数组里有正数也有负数. 求所有子数组的和的最大值. 二.设计思想 方法一:首先若要对二维数组进行分析,之前我们已经做过关于一位数组的练习,所以我们可以把它化简成为一个一维数组.再先求每个一维数组的最大子数组和,并记下每行最大一维子数组的下标.这是就会分两种情况:第一种是行之间的最大子数组是相连的,这时就可以直接相加得到:第二种是不相连的,,这时候就把每行的最大子数组看成一个整体,再使每个最大数组块进行相连,求使其相连的最小代价.最后得到的结果就是最大联通子数组的和

Java基础---Java中的二维数组(三十四)

Java 中的二维数组 所谓二维数组,可以简单的理解为是一种"特殊"的一维数组,它的每个数组空间中保存的是一个一维数组. 那么如何使用二维数组呢,步骤如下: 1. 声明数组并分配空间 或者 如: 2. 赋值 二维数组的赋值,和一维数组类似,可以通过下标来逐个赋值,注意索引从 0 开始 也可以在声明数组的同时为其赋值 如: 3. 处理数组 二维数组的访问和输出同一维数组一样,只是多了一个下标而已.在循环输出时,需要里面再内嵌一个循环,即使用二重循环来输出二维数组中的每一个元素.如: 运行

java中的二维数组

简单讲:java中的二维数组就是"特殊的一维数组",称为一维数组中的一维数组. 只不过元素是一维数组而已. 也是有两种初始化方式:静态初始化和动态初始化. 访问最后一个元素: int[] []a=? a[a.length-1][a[a.length-1].length-1]这个表示是最后一个元素 遍历二维数组: for(int i=0;i<a.length;i++){     for(int j=0;j<a[i].length;j++){         System.ou

Java中的“二维”数组

二维数组是一维数组,其数组元素是一维数组:三位数组也是一维数组,其数组元素是二维数组. 从这个角度看,Java语言里没有多为数组. class ArrayList {  public static void main(String[] args) { int[][] arr = new int [3][3];//定义一个二维数组 int sum =0;//记录长度 for(int a = 0 ;a<arr.length;a++) //获取行的长度  //a数组当成一位数组处理 { for(int

Java基础概述——二维数组

二维数组 所谓二维数组就是数组中的数组,它的定义格式和一维数组很像. 格式一:int[][] arr = new int[3][4]; [3]:该数组中有三个一维数组 [4]:每个一维数组的长度为4 格式二:int[][] arr = new int[3][]; 这种格式没有定义出每个一维数组的长度,需要自己去定义,arr[0] = new int[2];所以这种方法比较麻烦,不常用 格式三:int[][] arr = {{1,2,3},{4,5},{6,7,8},{9,0}}; 这种定义方式简

java基础:java中的二维数组

二维数组的概念: 一个元素为一维数组的数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的元素有多少个. 注意: A:以下格式也可以表示二维数组 a:数据类型 数组名[][] = new 数据类型[m][n]; b:数据类型[] 数组名[] = new 数据类型[m][n]; B:注意下面定义的区别 int x; int y; int x,y; int[] x; int[] y[]; int[] x,y[

动态申请和释放一个二维数组

动态申请一个二维数组也很常见,下面是常见的两种形式. //方法1 unsigned char** pImg= new unsigned char*[m]; for(int i=0;i<m;i++){ pImg[i]=new unsigned char[n]; } //方法2 unsigned char** pImg= new unsigned char*[m]; unsigned char* arr= new unsigned char[m*n]; for(int i=0;i<m;i++){

new一个二维数组(转)

转自:http://www.cnblogs.com/irvinow/archive/2009/02/21/1395340.html 定义二维数组char array[x][y]; 1.只定义个一维的就可以了 char *array; array = new char[x*y]; 访问的时候*(array+i*y+j)表示array[i][j] 2.定义一个二维数组 char **array1 array1 = new char *[x]; for(i=0;i<x;++i) array1[i] =