【问题标题】:Creating a magic square (Java)创建魔方 (Java)
【发布时间】:2021-07-15 17:23:57
【问题描述】:

我有点纠结于如何处理这个方阵编码项目。

每当我尝试输入任何值时,结果总是为真,并且方阵是魔方。例如,这会变成真的:

16 03 02 13
05 10 11 08
09 06 07 12
04 15 14 01

但是当我输入如下值时:

03 04 16 02
05 01 02 10
05 08 07 12
03 14 13 09

这应该返回 false,但它仍然返回 true,表示它是一个幻方。

要求是我需要所有的方法

"public void add(int i, int row, int col)":在矩阵的指定位置添加一个整数。

公开

"public boolean allInRange":判断矩阵中的所有值是否都在合适的范围内

"public boolean allUnique":判断矩阵中的所有值是否只出现一次

"public boolean isMagic":确定矩阵是否表示幻方。这意味着:

  • 用户为某个数字 n 输入了 n^2 个数字

  • 数字只在 1 和 n^2 之间,包括 1 和 n^2

  • 每个数字在矩阵中只出现一次

  • 每行、每列、每条对角线元素之和相等

    公共类 SquareMatrix {

    private int[][] array; 
    
    
    public SquareMatrix(int size) 
    { 
      array = new int[size][size]; 
    }
    
    
    public void add(int i, int row, int column) {array[row][column] = i;} 
    
    
    //Just checks if the #of rows & columns are between 1-n^2
    public boolean allInRange()
    {
      int n = array.length;
    
      for (int row = 0; row < n; row++)
      {
        for (int col = 0; col < array[row].length; col++)
        {
          if (array[row][col] < 1 || array[row][col] > n*n)
            return false; 
        }
      }
    
      return true;
    }
    
    public boolean allUnique()
    {
      for (int i =0; i < array.length - 1; i++)
      {
        for (int j = i + 1; j < array.length; j++)
        {
          if(array[i]==array[j])
            return false;
        }
      }
      return true;
    }
    
    
    //Supposed to call the other methods (allInRange & allUnique)
    public boolean isMagic()
    {
    
      for(int[] row : array)
      {
        for (int num : row)
        {
          if (num == 0)
            return false;
        }
      }
    
    
      boolean range = allInRange();
      if (range == true)
        return true;
      if (range == false)
        return false;
    
      boolean unique = allUnique();
      if (unique == true)
        return true;
      if (unique == false)
        return false;
    
    
    
      int sumRow;
      int sumCol;
      int sum1 = 0;
      int sum2 = 0;
    
      //Sum of Left to Right Diaganol
      for (int i = 0; i < array.length; i++)
      {
        sum1 += array[i][i];
      }
    
      //sum of right to left diaganol
      for (int j = 0; j < array.length; j++)
      {
        sum2 += array[j][array.length-1-j];
      }
    
      if (sum1 != sum2)
        return false;
    
    
      //Sum of Rows
      for (int row = 0; row < array.length; row++)
      {
        sumRow = 0;
        for (int col = 0; col < array[row].length; col++)
          sumRow += array[row][col];
    
        if (sumRow != sum1)
          return false;
      }
    
    
      //Sum of Col
      for (int i = 0; i < array.length; i++)
      {
        sumCol = 0;
        for (int j = 0; j < array.length; j++)
          sumCol = array[j][i];
    
        if (sumCol != sum1)
          return false;
    
      }
    
      return true;    
    }
    
    
    
    public String toString()
    {
      int n = array.length;
    
      String lol = "";
    
      for (int[] row : array)
      {
        for (int num : row)
        {
          String hi = String.format("%0"+(n*n+"").length()+"d",num);
    
          lol += hi + " ";
        }
        lol += "\n";
      }
      return lol;
    }
    

    }

这是我的驱动程序类

 import javax.swing.*;


public class SquareMatrixDriver { 
  
  public static void main(String[] args) { //My favorite line in history  
    
    
    JFrame bot = new JFrame(); //We can use JFrame to read the inputs 
    
    do 
    {
      //We have to make sure that it is a valid input or else I am doomed
      int size = 0;
      do 
      {
        size = Integer.parseInt(JOptionPane.showInputDialog(bot, "Enter the size of the matrix."));
        if (size < 1) 
        {
          JOptionPane.showMessageDialog(bot, "Invalid size! Enter a number greater than 0.");
        }
      } 
      while(size < 1);
      
      SquareMatrix matrix = new SquareMatrix(size);
      
      for (int i=0; i<size; i++) 
      {
        //Gets thhe User's Input
        
        String[] stringInput;
        do 
        {
          stringInput = JOptionPane.showInputDialog(bot, "Enter the row number" + (i + 1) + ", with " + size + " elements, split by commas.").split(",");
          if (stringInput.length != size) 
          { //In this code we basically enter the numbers with commas
            JOptionPane.showMessageDialog(bot, "Invalid size! " + stringInput.length + " elements entered but " + size + " required.");
          }
        } 
        while(stringInput.length != size);
        
        int[] intInput = new int[size];
        for (int o=0; o<size; o++) 
        { 
          
        }
        
        for (int o=0; o<size; o++) 
        {
          matrix.add(Integer.parseInt(stringInput[o]), i, o); //Here we would put everything into the Matrix
        }
      }
      
      
      JOptionPane.showMessageDialog(bot, "The matrix is " + (matrix.isMagic()? "very" : "not") + " correct"); //This line will output if the Matrix works or doesnt work 
      
      JOptionPane.showMessageDialog(bot, matrix); // Enters out the final output
    } while (JOptionPane.showConfirmDialog(bot, "Do you wish to exit?", "Exit", JOptionPane.YES_NO_OPTION) == 1); //Asks the User if they would like to exit the program
  }
}






      
      
     

【问题讨论】:

  • 你坚持哪一部分?您遇到的具体问题是什么?您的问题不清楚。
  • @zero298 您好,很抱歉造成混淆。我遇到的问题是,每当我在方阵中输入任何值时,它都会返回说它不应该是幻方。如果有帮助,我编辑了帖子以提供一个示例
  • 您使用的是 Eclipse 还是 IntelliJ 之类的 IDE?你应该......它们带有调试器,允许您逐行执行代码,并且在每一行之后您可以看到哪些变量具有哪些值。您的 isMagic 函数返回得太早。你有if (range == true) return true;,这意味着任何数字在范围内的输入都被认为是魔法。删除它。下面的唯一检查也是如此。对于幻方,您需要所有条件都为真,而不仅仅是一个。 (但只要不满足一个条件就返回false也没关系。)
  • 您的所有独特功能都有很大的优势。您正在检查数组 [I] = 数组 [j]。这是没有意义的,因为数组是二维的,所以 array[I] 和 Array[j] 是一维数组。所以它不是平等的,而是返回真正的魔法。您可以做的是将 2D 数组展平为 1D 并检查是否有任何元素重复(可以为此使用 Set)
  • @Robert 所以我尝试删除'if (range == true) return true;'但是现在当我尝试应该返回 true 的原始示例现在返回 false

标签: java magic-square


【解决方案1】:

目测可以发现的错误:

allUnique() 完全错误,您必须检查每个数字是否在矩阵中只出现一次,但是您正在比较完全不同的行数组,检查唯一性的最佳方法通常是使用哈希集,但是因为这里你有一个非常定义的数字范围(从 1 到 n2),所以使用任何 n2 布尔数组。扫描方阵并测试/设置数组中的对应元素,如果已经设置返回false。

public boolean allUnique() {
  int n=array.length;
  boolean[] set=new boolean[n*n];
  for (int i=0; i < n; i++) {
    for (int j=0;j < n; j++) {
      //Here assuming that you already sucessfully called allInRange, 
      //otherwise we must check bounds to avoid an index out of bounds exception
      if(set[array[i][j]-1]) {
        return false;
      }
      set[array[i][j]-1] = true;
    }
  }
  return true;
}

在方法 isMagic() 中,所有这部分都是错误和多余的

 boolean range = allInRange();
  if (range == true)
    return true;  //WRONG, this will immediately return with true, without further checks
  if (range == false)
    return false;

  boolean unique = allUnique();
  if (unique == true)
    return true;  //WRONG, same as before
  if (unique == false)
    return false;

替换为

if (!allInRange()) {
    return false;
}
if (!allUnique()) {
    return false;
}

最后在 isMagic() 中计算列的总和时,缺少加法

sumCol = array[j][i];

必须替换为

sumCol += array[j][i];

【讨论】:

  • 我已经尝试过了,它给出了一个 'java.lang.ArrayIndexOutOfBoundsException: -1'
  • @Zenzu 哎呀!把括号左移了,你能用编辑后的版本再试一次吗?
猜你喜欢
  • 2016-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多