JAVA的SUDOKU问题,求各位高手帮忙指点(见最后一层)
我是新手,请高手帮忙解答一下,先谢谢拉.java我们不要求学那么深,但是基础性的编程都应该掌握.但是到现在,越学越晕了.一般一个最简化的java程序,一共包括三部分:
1,konstruktor,
可以先定一些数值,做初始化的工作.
2,static void main methode,
整个程序的主要环节,也是程序运行的流程.
3,还有methode.
具体执行程序所用的不同方法.
问题是: 我做的好多例题,都不太一样,有的直接在konstruktor里设置量,有的却在main methode里才做,konstruktor是空的.到底什么东西是一定在konstruktor里先设定的呢?konstruktor和main methode都有哪些具体区别和具体功用呢?
[ 本帖最后由 abendrobotor 于 2006-7-6 07:58 编辑 ] Main 严格的来讲是不属于类的。只是定义了一个程序开始(和结束)的地方。你完全可以在main里面写一些同类毫无关系的代码。
同样。你在main中也不能直接调用类的非static的属性和方法。也就是说,你根本不能在main中调用类对象的函数--除非你在main中新建了一个类的实例。
konstruktor是属于类的。在类对象被构造的时候自动执行。用于初始化变量什么的。konstruktor并不一定要存在。也可以用一些其它类似的方法初始化变量。 楼上的解释的正确,我再补充一下^_^:
Java是对象编程,每一个类都可以看作是一个对象。如果你想用这个对象,或者是给对对象(类)里的变量
负值,你可以在konstruktor里边进行,也可以通过类里的方法负值。
static void main methode只能操作static的方法或者变量。
举个例子:
public class Bla{
private static int a;
private int b;
public Bla() {
}
public Bla(int b) {
this.b=b;
}
public void setB(int b) {
this.b=b;
}
public int getB() {
return this.b;
}
public static void main(String args[]) {
a=10;
Bla bla = new Bla(20);
//Bla bla = new Bla();
//bla.setB(20);
System.out.println("a: "+a + ", b: " + bla.getB());
}
} l类可以理解为是对象的种类!楼主的理解有些偏颇,basset 说得很好,不过如果楼主现在学的是基础编程可以暂时如此理解,但是如果学的是数据结构等其他课程,最好还是好好弄清楚中间的区别! 哦,看了各位的解释,清楚一点了.谢谢各位.
各位都说了,"在main中也不能直接调用类的非static的属性和方法",但不是所有的变量和方法都要定义为static才能运用的吧?比如我在main里要运用到一系列的方法,但都没有定义static阿.那么这个static到底是什么意思呢?(不是问这个词是什么意思)
明天课上要给上个星期的例题答案,这个题对我有点复杂,等我研究一下,周末再来问问,希望高手支持. 看了楼上几位的回答,俺实在受不了,想说两句。
1。对象是对象,类是类,对象是类的一个实例。
2。konstruktor不是可有可无的,每个类都有!如果你没有显示的为类定义一个konstruktor,那么java会自动创建一个默认的无参konsturktor.
3。为什么只有static的变量和方法才能被直接调用?因为static数据与对象无关!static在类创建的时候就已经产生了自己的数据空间,而一般的数据空间只有在类产生对象的时候才有!这就是之间的区别。
[ 本帖最后由 大厨 于 2006-6-23 01:33 编辑 ] 呵呵,看到有些不同的意见了,不知道哪个更正确一点?
今天好不容易有点时间,来分析分析星期五留下来的作业.弄了半天还是差点儿.我想这里有不少人都是java精通的了,像我这样学java,前不着村,后不着店儿的,才知道点皮毛,自然无法像各位一样从oop整体上来解决问题.还是我走到哪,碰到了些什么问题,就来向各位请教的好.
aufgabe是做个sudoku的简单游戏,如果各位不知道大概是个什么,有图.
http://www.wiley-vch.de/dummies/sudoku/images/74.jpg
一共81个方格,9个为一组(panel),每组方格有1-9的数字,不能重复,程序初始,每个panel里给出若干个从1到9数字.整个frame里的81个方格,纵向,横向任何一条,都像单个panel一样,只允许从1-9不能重复的九个数字.这个游戏的任务就是逻辑的推算出刨除每个panel初始时给的几个数的其他所有数字.
这个游戏要求本学期结束前完成,教授每个星期带着大家大概说一点,所以具体的主要工作还要自己独立完成.到下节课前,应该把这个程序大结构完成,虽然没有deklaration的演算,
1,但是frame,81个button,9个panel都应该显示出来,
2,包括颜色,button的format等等.
möglich3,如何公式化这81个button,使之成组,为以后的schleife打基础.
我编了这个结构,但是运行不了,看不出解决问题的方法.希望高手指点一二:
问题一:
制作button我当然用array喽:button[9][9],这样也好管理,可是语法总觉得不对.
konstruktor里我先写:
Button[][] feld = new Button;
Panel[] p = new Panel;
后边在一个methode里用循环语句让81个button显示出来的语句就运行不了:
add(feld);
是应该这样写的嘛???
[ 本帖最后由 abendrobotor 于 2006-6-26 00:44 编辑 ] 这个要看你自己觉得怎么样合适了,一般而言,如图的排列,当然是整个作为一个panel,使用gridlayout比较好,但是这样的话,为了显示出9个小方块的区别,又要做一番显示上的代码处理。但是如果为了显示的方便使用9个小panel(也要使用gridlayout),那么就有两种按钮分配方式,一是每个panel分配数组中的一行/列,这样检查小方块比较方便,而为了检查每行每列必须满足不能重复的条件,为了不丧失使用数组的优势,就势必要有一点代码来将这81个按钮打破数组顺序分配给9个panel了。
所以觉得这样做,倒不如简单一些,声明一个81项的一维数组。这样在进行行列检查时也比较方便,行检查时对数组内一个范围检查,列检查时是对数组内以9为间隔的元素的检查。而在往小panel中添加时,也可以分别通过数组索引除9的整数和余数来确定行和列。 这里只考虑排列,不考虑以后的校验和菜单、事件的响应。
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
public class Soduku extends JFrame {
/**
* create jframe
*/
public Soduku(String title) {
super(title);
largepanel = new JPanel(new GridLayout(3, 3));
int row, col, rrow, ccol;
for (int i = 0; i < 81; i++) {
row = i / 9;
col = i % 9;
rrow = row / 3;
ccol = col / 3;
System.out.println(row + "\t" + col + "\t" + rrow + "\t" + ccol);
buttons = new JButton();
buttons.setText("" + i);
if (smallpanel == null) {
smallpanel = new JPanel(new GridLayout(3, 3));
smallpanel.setBorder(new LineBorder(Color.BLUE, 2));
largepanel.add(smallpanel);
}
smallpanel.add((buttons));
}
this.getRootPane().setLayout(new BorderLayout());
this.getRootPane().add(largepanel, BorderLayout.CENTER);
statuspanel = new JPanel(new BorderLayout());
status = new JLabel("");
exitbutton = new JButton(new AbstractAction("Exit") {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
statuspanel.add(status, BorderLayout.CENTER);
statuspanel.add(exitbutton, BorderLayout.EAST);
this.getRootPane().add(statuspanel, BorderLayout.SOUTH);
this.pack();
}
public static void main(String [] args) {
Soduku app = new Soduku("Soduku");
Point center = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
app.setLocation((int) (center.getX() - app.getWidth() / 2), (int) (center.getY() - app.getHeight() / 2));
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.setVisible(true);
}
JButton [] buttons = new JButton;
JPanel largepanel = null;
JPanel statuspanel = null;
JLabel status = null;
JPanel [][] smallpanel = new JPanel;
//JButton checkbutton = null;
JButton exitbutton = null;
}
原帖由 greenflute 于 2006-6-26 08:47 发表
这里只考虑排列,不考虑以后的校验和菜单、事件的响应。
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
public class Soduku e ...
大哥,一看你就是高手,信手拈来就写了这么多,佩服!!
import javax.swing.*;
import javax.swing.border.LineBorder;
可是这几类我都还没有学,你程序里写的好多命令我都不知道做什么用的,看来你这宰牛刀用在我这鸭子身上了.你的构思我大概看懂了,但是现在只是这个程序的第一步,以后一定要考虑到校验问题的,所以不为以后打基础,以后改起来更麻烦.
用array[][],这是教授给的tipp,双层array本身就简化了校验,纵向和横向的检查直接就在array里就可以完成了,剩下的就集中在9个小panel里每个小panel里的九个数字的检查了.教授给的tipps不用,估计以后不好交作业啊. 现在我的问题是这行句柄,添加array里所有的button的这个,这个有什么错误呢?
add(feld);
所有81个button都添加完了,我才能进行分配数字的下一步啊.谁能帮我啊,add();怎么用在array上啊?
这个要看你自己觉得怎么样合适了,一般而言,如图的排列,当然是整个作为一个panel,使用gridlayout比较好,但是这样的话,为了显示出9个小方块的区别,又要做一番显示上的代码处理。但是如果为了显示的方便使用9个小panel(也要使用gridlayout),那么就有两种按钮分配方式,一是每个panel分配数组中的一行/ 列,这样检查小方块比较方便,而为了检查每行每列必须满足不能重复的条件,为了不丧失使用数组的优势,就势必要有一点代码来将这81个按钮打破数组顺序分配给9个panel了。
所以觉得这样做,倒不如简单一些,声明一个81项的一维数组。这样在进行行列检查时也比较方便,行检查时对数组内一个范围检查,列检查时是对数组内以9为间隔的元素的检查。而在往小panel中添加时,也可以分别通过数组索引除9的整数和余数来确定行和列。
int row, col, rrow, ccol;
for (int i = 0; i < 81; i++) {
row = i / 9;
col = i % 9;
rrow = row / 3;
ccol = col / 3;
System.out.println(row + "\t" + col + "\t" + rrow + "\t" + ccol);
buttons = new JButton();
buttons.setText("" + i);
if (smallpanel == null) {
smallpanel = new JPanel(new GridLayout(3, 3));
smallpanel.setBorder(new LineBorder(Color.BLUE, 2));
largepanel.add(smallpanel);
}
smallpanel.add((buttons));
}
这样做是可以减少一部分校验代码的麻烦程度的。至于教授的tipp,
如果只是为了熟悉双循环大可不必,后面的多重循环多着呢:):)
关于你的代码的问题
1、panel和button都需要实例化的,生成一个数组并不能代替数组内元素的生成。
2、add方法要有施动者,不管是数组里的panel,还是主窗口,代码大致应该是这
个样子的,至于怎么放到循环里面,就看你愿意使用哪种循环了。
Button[][] feld = new Button;
Panel[] p = new Panel;
// new panel
p=new Panel();
// new Button
feld=new Button();
// add button
p.add(feld);
3、不管使用Swing还是AWT,使用多个组件时都要使用布局管理器的 Vielen dank für alle und eure Beiträge,ich habe davon sehr viel gelernt,besonders von greenflute.
Ich bin an der Uni,kann nur Deutsch schreiben.
Insofern bin ich so weit und habe das Programm geschrieben. Die weitere Aufgabe kommt am Freitag wieder.Ich werd dem verfolgen.
mein Programm lautet:
import java.awt.*;
public class Sudoku extends Frame
{
Button [][]feld = new Button;
Panel[] kleinePanel = new Panel;
int hori, vert,horiinPanel,vertinPanel;
int getButtonZahl;
public static void main (String[] args)
{
new Sudoku ();
}
public Sudoku()
{
setLayout(new GridLayout(3,3,3,3));
for (int p = 0; p < 9; p++) {
kleinePanel = new Panel(new GridLayout(3,3,1,1));
add(kleinePanel);
}
//set all the Buttons in 9 Panels
for (int y = 0; y < 9; y++) {
vert = (y / 3);
vertinPanel = (y % 3);
for (int x = 0; x < 9; x++) {
hori = (x / 3);
vertinPanel = (x % 3);
getButtonZahl++;
feld = new Button();
kleinePanel[(vert * 3) + hori].add(feld);
}
}
//setColor
Color HELLBLAU = new Color(127,127,255);
Color HELLGELB = new Color(255,255,127);
setBackground(HELLGELB);
for (int c = 0; c < 8; c++) {
if ((c % 2) == 0)
kleinePanel.setBackground(HELLBLAU);
else
kleinePanel.setBackground(HELLBLAU);
}
//setFont
Font f = new Font("SansSerif", Font.PLAIN, 30);
setFont(f);
setSize(458,458);
show();
}
} 不错不错;);) 原帖由 greenflute 于 2006-6-29 12:16 发表
不错不错;);)
谢谢支持啊,后边校验的程序我还没想出来呢,明天上完课后,让我这个周末想想. 乱了好几天,今天回来问问我周末出的个小问题.
我想在button上加数字,这个数字是变量中携带的.我所知道的语句是:
1,setText(String);
2,setLabel(String label)
这两个语句是不是都是在konstruktor里用的啊?怎么我用在后边的methode里就不行呢,说找不到symbol.
第一个语句是最长用的,greenflute里给的程序里也有个:buttons.setText("" + i); 如果不直接输入string,而是个变量,是不是一定要setText("" + i);这样写呢?怎么我这样照搬都不行,说identifier experted呢? 哎,坐电脑前2个半小时了,还是没有想出来如何安排预先固定的那些数.我是不是应该每个小panel都作成一个单独的对象呢,这样也比较容易生成数,直接用个方法随机出数,然后p.Erzeugen();,还是再弄一个循环,让他出数呢.
哎呀~我是晕了.我再想想.16层的问题也没有解决,后边还有校验的程序等着,估计作业要泡汤~
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
/**
* small cube panel
*/
public class SodukuPanel extends JPanel {
public SodukuPanel() {
super();
buttons = new ArrayList<SodukuTeil>();
}
public Component add(Component comp) {
//if (buttons.size() <= 9 && !buttons.contains(comp)) {
buttons.add((SodukuTeil) comp);
//}
return super.add(comp);
}
public ArrayList<SodukuTeil> getButtons() {
return buttons;
}
private ArrayList<SodukuTeil> buttons = null;
}
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
/**
* Suduku Button
*/
public class SodukuTeil extends JButton {
/**
* construct a new Button, specify its location in the panel
*
* @param row
* @param col
*/
public SodukuTeil(int row, int col) {
super();
this.row = row;
this.col = col;
}
public Integer getRow() {
return row;
}
public Integer getCol() {
return col;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
if (value != null) {
this.setText(value.toString().trim());
}
}
/* row and col */
private Integer row = null, col = null;
/* value of this button */
private Integer value = null;
}
buttons = new SodukuTeil(row, col);
//buttons.setValue(i);
buttons.setText(" ");
smallpanel = new SodukuPanel();
SodukuTeil [] buttons = new SodukuTeil;
SodukuPanel [][] smallpanel = new SodukuPanel;
我坚持不住了,明天早上再来继续研究你给的tipps,不过import javax.swing.*因为我不会,所以吃力点.
先谢谢你啊,还是从你给的程序里学了不少,因为我接触的程序少,语句掌握的也少,所有有你这么一个高手在前面走,我后边跟着真是占了不少便宜. greenflute,我研究了半天你18,19楼给的程序,同时还查java的dokumentation,最后还是失败了,你用的对我来说都太高级了,短时间内你给的那些语句我掌握不了啊.
不过最有建设性意见的还是你给我的那个短消息,super()现在我还不太敢用,(主要接触的例题太少了,没有什么借鉴之处),不过弄了差不多的,先用这个弱智点的,如果不行,再考虑用父类和子类.
又加了一个array,里边通过简单计算存储了预先分配给每个小panel里随机分配的3到5个数字(网上查了查,原来sudoku研究的人挺多的,那些预先安排的数字其实不是随机给的,都是从数据库里随机提出来的样板),然后在添加到小panel里,我先写了只有一个panel的,不过还是有点问题,不知道怎么回事,出错在Math.random上,求高手们指导一下啊.
import java.awt.*;
public class Test extends Frame
{
public Button [] b = new Button;
public Panel [] p = new Panel;
public static void main (String[] args)
{
new Test();
}
public Test() {
// format
setLayout(new GridLayout(3,0));
for (int i = 0; i < 9; i++) {
p = new Panel(new GridLayout(1,1));
add(p);
b = new Button();
p.add(b);
}
setSize(180,180);
show();
//schleife
boolean [][] gezogen = new boolean;
int neuezahl,
anzahl = 0, mal;
mal = (int)(Math.random() * 2);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
gezogen = false;
}
}
anzahl = 0;
while (anzahl != (mal + 3)) {
neuezahl = (int)(Math.random() * 9);
for (int i = 0; i < 9; i++) {
if (!gezogen) {
gezogen = true;
anzahl++;
}
}
}
anzahl = 0;
while (anzahl != (mal + 3)) {
neuezahl = (int)(Math.random() * 9);
for (int i = 0; i < 9; i++) {
if (!gezogen) {
gezogen = true;
anzahl++;
}
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (gezogen) {
b.setText(j);
}
}
}
}
}
高手们,指导一下嘛.出错的原因说can not resovle symble
[ 本帖最后由 abendrobotor 于 2006-7-6 00:15 编辑 ] 高手都忙,咱们这是互相帮助,共同提高,呵呵$汗$$汗$
你用的是AWT包下的组件,Button是没有setText()方法的,应该用setLabel()。
而且由于这两个方法都直接受String类型参数,所以要用""+j的方式强制转换一下。
Math.random并没有错,虽然已经不推荐使用这个随机数了。
另外boolean初始就是false,不需要再重置一遍了。
你还是找一个IDE比较好,减小在编码和调试过程中的难度。
关于数独,看一下别人的:《完美数独》(Perfect Sudoku) 关于比较简洁的介绍java特性和入门的书,java ist auch eine insel这本在线书挺不错的,也可以下载。
http://www.galileocomputing.de/download/cover/9783898427470.gif
Java ist auch eine Insel
von Christian Ullenboom Programmieren
für die Java 2-Plattform in der Version 5 坐思又想还是觉得22楼那个太傻了,弄的那么复杂,出了几个错误,到现在错误还没有排除,就算排除了,估计也不好用,弄的太麻烦了,这么晕,会死人的.所以决定不在小panel上做文章了,还是以大panel里每个zeile或者每个reihe随机出几个数,只要不重复,就好,这样看着也简单,实际操作起来也方便.
弄了半天在Math.random上出问题了,原来这个random用过的啊,应该没有问题才对,以前还做过个练习,lotto随机出数的程序,现在看看,以前编的程序都有错误了,怎么回事啊.贴上来请高手看看
class Lotto {
Lotto () {
boolean [] gezogen = new boolean;
int neuezahl,
anzahl = 0;
for (int i = 0;i < 49;i++) gezogen = false;
while (anzahl != 6) {
neuezahl = (int)(Math.random() * 49);
if (!gezogen) {
gezogen = true;
anzahl++;
}
}
for (int i = 0;i < 49;i++)
if (gezogen) System.out.println(i + 1);
}
public static void main (String [] args){
new Lotto ();
}
}
还有,greenflute说出随机数还有别的,我查了查,dokumentation里有,但是有命令,没有实例,我弄不太清楚啊,具体怎么用?比如:Random();protected int next(int bits);还有public int nextInt(int n);都怎么用啊,高手们,能不能给个简单的例子啊? 谢谢拉 靠~java的API上头都什么跟什么啊,按照上边写的根本无效,谁知道这个都是怎么用的?
想简单运用一下,怎么都不行啊,缺什么东西呢?
import java.util.Random;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
public int nextInt(int n);
System.out.println(n);
protected int next(int bits) {
System.out.println(seed);
}
}
}
不知道你的开发环境是怎么搞的,试了一下,上面的代码没有问题。
关于随机数,除了Math的random方法以外,还有java.util.Random
An instance of this class is used to generate a stream of pseudorandom numbers. The class uses a 48-bit seed, which is modified using a linear congruential formula. (See Donald Knuth, The Art of Computer Programming, Volume 2, Section 3.2.1.)
和java.security.SecureRandom
This class provides a cryptographically strong random number generator (RNG).
A cryptographically strong random number minimally complies with the statistical random number generator tests specified in FIPS 140-2, Security Requirements for Cryptographic Modules, section 4.9.1. Additionally, SecureRandom must produce non-deterministic output. Therefore any seed material passed to a SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in RFC 1750: Randomness Recommendations for Security.
至于其他软件包,就不在这里讨论了
public Test() {
public int nextInt(int n);
System.out.println(n);
protected int next(int bits) {
System.out.println(seed);
}
}
你这已经是构造函数了,就不能再声明方法了,也不能在变量前加访问限制符了. 原帖由 greenflute 于 2006-7-7 00:09 发表
public Test() {
public int nextInt(int n);
System.out.println(n);
protected int next(int bits) {
System.out.println(seed);
}
}
你这已经是构造函数了,就不 ...
啊,其他方法也不能用了,那它这个有什么用啊,出个数,也用不了? 变量/方法的声明和使用是完全不同的概念。
页:
[1]
2