APP下载地址:http://sumtudou.cn/download.html
关于本帖的算法请见https://blog.youkuaiyun.com/qq_36752486/article/details/84189193
这里只是用java重写一遍,在架在android的框架上了。
先贴个截图抖个机灵。。。因为出结果会清空上面的输入框,所以看起来有点奇怪
虽然说得简单,但是实际操作起来还是有一点的难度。
首先是java的队列不像C++一般的单一,这里我们用的是Java中的集合Queue、LinkedList来模拟队列。
之后就是一个最大的bug,找了我快一天的时间。
举个栗子,就是一个java中对象之间的关系。
package com.company;
public class Main {
public static void main(String[] args) {
stu Q=new stu(13); ///Q.a=13
stu W=Q; ///这句话在java中并不是赋值语句,只是将W作为Q的引用
System.out.println("w.a="+W.a); ///当Q改变时,W的值会跟着改变
Q.a=10;
System.out.println( "------------------" );
System.out.println("w.a="+W.a);
System.out.println( "------大分割线------------" );
stu QQ=new stu(13); ///QQ.a=13
stu WW=new stu(QQ); ///这儿和以上就不用,这里用了重写的构造函数,将qq的值完全赋给了ww
System.out.println("ww.a="+WW.a); ///这样ww才是一个单独的对象实例。
Q.a=10;
System.out.println( "------------------" );
System.out.println("ww.a="+WW.a);
}
}
class stu {
public int a;
public stu(int k) {
this.a = k;
}
public stu(){}
public stu(stu b) {
this.a = b.a;
}
}
以上问题看懂之后,其他的就好说啦。都是些小操作了。首先贴一个c++改成Java的代码
package com.company;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.LinkedList;
import java.util.Queue;
class Node {
int Now[] = new int[3]; ///当前三个瓶子的水量
int step; ///步数
String operate="";
public Node(){}
public Node(Node q){
this.Now[0]=q.Now[0];
this.Now[1]=q.Now[1];
this.Now[2]=q.Now[2];
this.step=q.step;
this.operate= new String(q.operate);
}
}
public class Main {
Node Begin = new Node();
Node End = new Node();
int All[] = new int[3]; ///三个瓶子的总水量。
int vis[][][] = new int[101][101][101]; ///visit数组,记录是否访问过,1为真,0为假
int full_bottle, water, last_index;
int T, res;
boolean Sucess(Node a, Node b, int index) ///结束判断数组,判断是否到达终点
{
return (a.Now[index] == b.Now[index]);
}
public static void main(String[] args) throws Exception {
/* PrintStream out = new PrintStream("h:/javaout.txt"); //流输出,用来打印测试数据的。
System.setOut(out);*/
System.out.println("the first");
Main m = new Main();
m.All[0] = 10;
m.All[1] = 9;
m.All[2] = 7;
m.Begin.Now[0] = 0;
m.Begin.Now[1] = 0;
m.Begin.Now[2] = 5;
m.End.Now[0] = 4;
m.last_index = 0;
m.BFS();
}
void BFS() {
Queue<Node> Q; ///建立队列,这儿建队有个好处,不用每次完了清空
Q = new LinkedList<Node>();
for (int i = 0; i < 101; i++)
for (int j = 0; j < 101; j++)
for (int k = 0; k < 101; k++)
vis[i][j][k] = 0;
Q.offer(Begin);
vis[Begin.Now[0]][Begin.Now[1]][Begin.Now[2]] = 1;
while (Q.peek() != null) {
Node u =new Node(Q.poll()) ; ///!!!!! 这儿花了一天找bug……
System.out.println("w"+u.Now[0]+u.Now[1]+u.Now[2]+"w");
// System.out.println("\n\n\n");
// Q.pop();
if (Sucess(u, End, last_index)) ///出口
{
res = u.step;
System.out.print("\n 一共需要如下" + res + "步 \n");
System.out.println(u.operate);
break;
}
for (int i = 0; i <= 2; i++) ///三个瓶子之间倒水
{
for (int j = 0; j <= 2; j++) {
if (i != j) {
Node over = new Node(u);
if (over.Now[i] >= All[j] - over.Now[j]) ///1的水比2空的部分多huozhexiangdeng
{
over.Now[i] = over.Now[i] - (All[j] - over.Now[j]);
over.Now[j] = All[j];
} else {
over.Now[j] = over.Now[j] + over.Now[i];
over.Now[i] = 0;
}
over.step = over.step + 1;
String cz1 = " 把" + String.valueOf(All[i]) + "升瓶子倒到" + String.valueOf(All[j]) + "升瓶子 \n";
over.operate = over.operate + cz1;
if (vis[over.Now[0]][over.Now[1]][over.Now[2]] == 0) {
Q.offer(over);
System.out.println(over.operate + "1号"+"\n");
vis[over.Now[0]][over.Now[1]][over.Now[2]] = 1;
}
}
}
Node now = new Node(u); ///倒空某个瓶子
System.out.println("e"+u.Now[0]+u.Now[1]+u.Now[2]+"e");
now.Now[i] = 0;
now.step = now.step + 1;
// PR(now);
String cz = " 倒空" + String.valueOf(All[i]) + "升瓶子 \n";
now.operate = now.operate + cz;
System.out.println(now.operate + "2号"+ "\n");
Q.offer(now);
vis[now.Now[0]][now.Now[1]][now.Now[2]] = 1;
Node now_2 = new Node(u); ///倒满某个瓶子,其实这两段可以合成一段写的,太懒了,懒得整理
now_2.Now[i] = All[i];
now_2.step = now_2.step + 1;
String cz_2 = " 装满" + String.valueOf(All[i]) + "升瓶子 \n";
now_2.operate = now_2.operate + cz_2;
System.out.println(now_2.operate + "3号"+"\n");
// PR(now_2);
Q.offer(now_2);
vis[now_2.Now[0]][now_2.Now[1]][now_2.Now[2]] = 1;
}
}
}
}
-----------------------------------------我是分割线----------------------------------------------------
接下来上我们android的内容咯。
经过前面的内容,后面也没有什么可说的了。直接上代码吧。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/bg1"
android:scaleType = "centerCrop">
</ImageView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请分别输入三个瓶子的总容量:"
android:textSize="18sp"
android:layout_gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal">
<EditText
android:id="@+id/et_All_0"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
<TextView
android:layout_width="20dp"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/et_All_1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
<TextView
android:layout_width="20dp"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/et_All_2"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" 请对应输入三个瓶子的当前水量:"
android:textSize="18sp"
android:layout_gravity="center"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal">
<EditText
android:id="@+id/et_Now_0"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
<TextView
android:layout_width="20dp"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/et_Now_1"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
<TextView
android:layout_width="20dp"
android:layout_height="wrap_content"
/>
<EditText
android:id="@+id/et_Now_2"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="需要将"
android:textSize="18sp"/>
<EditText
android:id="@+id/et_Last_All"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="升瓶子装满"
android:textSize="18sp"/>
<EditText
android:id="@+id/et_Last_Now"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textSize="18sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="升水"
android:textSize="18sp"/>
</LinearLayout>
<Button
android:layout_marginTop="15dp"
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="确认"
/>
<TextView
android:id="@+id/tv_Sum"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Mainactivity。class
package com.example.a11630.waigua;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.LinkedList;
import java.util.Queue;
class Node {
int Now[] = new int[3]; ///当前三个瓶子的水量
int step; ///步数
String operate = "";
public Node() {
}
public Node(Node q) {
this.Now[0] = q.Now[0];
this.Now[1] = q.Now[1];
this.Now[2] = q.Now[2];
this.step = q.step;
this.operate = new String(q.operate);
}
}
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btn_ok;
EditText et_All_0, et_All_1, et_All_2, et_Now_0, et_Now_1, et_Now_2, et_Last_All, et_Last_Now;
TextView tv_Sum;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_ok = (Button) findViewById(R.id.btn_ok);
btn_ok.setOnClickListener(this);
et_All_0 = (EditText) findViewById(R.id.et_All_0);
et_All_1 = (EditText) findViewById(R.id.et_All_1);
et_All_2 = (EditText) findViewById(R.id.et_All_2);
et_Now_0 = (EditText) findViewById(R.id.et_Now_0);
et_Now_1 = (EditText) findViewById(R.id.et_Now_1);
et_Now_2 = (EditText) findViewById(R.id.et_Now_2);
et_Last_All = (EditText) findViewById(R.id.et_Last_All);
et_Last_Now = (EditText) findViewById(R.id.et_Last_Now);
tv_Sum = (TextView) findViewById(R.id.tv_Sum);
}
Node Begin = new Node();
Node End = new Node();
int All[] = new int[3]; ///三个瓶子的总水量。
int vis[][][] = new int[101][101][101]; ///visit数组,记录是否访问过,1为真,0为假
int full_bottle, water, last_index;
int T, res;
boolean Sucess(Node a, Node b, int index) ///结束判断数组,判断是否到达终点
{
return (a.Now[index] == b.Now[index]);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_ok) {
String All_0 = et_All_0.getText().toString();
String All_1 = et_All_1.getText().toString();
String All_2 = et_All_2.getText().toString();
String Now_0 = et_Now_0.getText().toString();
String Now_1 = et_Now_1.getText().toString();
String Now_2 = et_Now_2.getText().toString();
String Last_All = et_Last_All.getText().toString(); ///被子的容量
String Last_Now = et_Last_Now.getText().toString(); ///被子的水量
if (All_0.equals("") || All_1.equals("") || All_2.equals("") || Now_0.equals("") || Now_1.equals("") ||
Now_2.equals("") || Last_All.equals("") || Last_Now.equals("")) {
Toast.makeText(this, "请把以上空白填完哪~~~不然我好难给你办事哦", Toast.LENGTH_SHORT).show();
} else {
try{
All[0] = Integer.parseInt(All_0);
All[1] = Integer.parseInt(All_1);
All[2] = Integer.parseInt(All_2);
Begin.Now[0] = Integer.parseInt(Now_0);
Begin.Now[1] = Integer.parseInt(Now_1);
Begin.Now[2] = Integer.parseInt(Now_2);
full_bottle = Integer.parseInt(Last_All);
water = Integer.parseInt(Last_Now);
}catch (Exception e){
Toast.makeText(this, "输入有误,任意空必须为阿拉伯数字", Toast.LENGTH_SHORT).show();
}
int flag = 0;
for (int i = 0; i < 3; i++) {
if (All[i] == full_bottle) {
End.Now[i] = water;
last_index = i;
flag = 1;
}
}
if (full_bottle < water || flag == 0) {
if(flag==0&&full_bottle >=water){
Toast.makeText(this, "找不到要灌水的瓶子", Toast.LENGTH_SHORT).show();
} else
if(flag==1&&full_bottle <water){
Toast.makeText(this, "要灌水的瓶子要爆炸了", Toast.LENGTH_SHORT).show();
}else
{
Toast.makeText(this, "找不到瓶子,且要求的水有点过分", Toast.LENGTH_SHORT).show();
}
} else {
// System.out.println("hahaha "+All[0]+" "+All[1]+" "+All[2]+"\n");
// System.out.println("hehehe "+Begin.Now[0]+" "+Begin.Now[1]+" "+Begin.Now[2]+"\n");
// System.out.println("号子"+last_index+ "最后装了"+End.Now[last_index]+"\n");
BFS();
// System.out.println("hahaha "+full_bottle+" "+water+"\n");
// Log.d("MainActivity",All_0+All_1+All_2);
et_All_0.setText("");
et_All_1.setText("");
et_All_2.setText(""); //清空输入框。
et_Now_0.setText("");
et_Now_1.setText("");
et_Now_2.setText("");
et_Last_All.setText("");
et_Last_Now.setText("");
}
}
}
}
void BFS() {
Queue<Node> Q; ///建立队列,这儿建队有个好处,不用每次完了清空
Q = new LinkedList<Node>();
for (int i = 0; i < 101; i++)
for (int j = 0; j < 101; j++)
for (int k = 0; k < 101; k++)
vis[i][j][k] = 0;
Q.offer(Begin);
vis[Begin.Now[0]][Begin.Now[1]][Begin.Now[2]] = 1;
while (Q.peek() != null) {
Node u = new Node(Q.poll()); ///!!!!!
// System.out.println("w"+u.Now[0]+u.Now[1]+u.Now[2]+"w");
// System.out.println("\n\n\n");
// Q.pop();
if (Sucess(u, End, last_index)) ///出口
{
res = u.step;
// System.out.print("\n 一共需要如下" + res + "步 \n");
// System.out.println(u.operate);
String sum = "\n 一共需要如下" + res + "步 \n" + u.operate;
tv_Sum.setText(sum);
break;
}
if (u.step >= 9) {
String sum = "\n 我真都不会哦 \n";
tv_Sum.setText(sum);
break;
}
for (int i = 0; i <= 2; i++) ///三个瓶子之间倒水
{
for (int j = 0; j <= 2; j++) {
if (i != j) {
Node over = new Node(u);
if (over.Now[i] >= All[j] - over.Now[j]) ///1的水比2空的部分多huozhexiangdeng
{
over.Now[i] = over.Now[i] - (All[j] - over.Now[j]);
over.Now[j] = All[j];
} else {
over.Now[j] = over.Now[j] + over.Now[i];
over.Now[i] = 0;
}
over.step = over.step + 1;
String cz1 = " 把" + String.valueOf(All[i]) + "升瓶子倒到" + String.valueOf(All[j]) + "升瓶子 \n";
over.operate = over.operate + cz1;
if (vis[over.Now[0]][over.Now[1]][over.Now[2]] == 0) {
Q.offer(over);
// System.out.println(over.operate + "1号"+"\n");
vis[over.Now[0]][over.Now[1]][over.Now[2]] = 1;
}
}
}
Node now = new Node(u); ///倒空某个瓶子
// System.out.println("e"+u.Now[0]+u.Now[1]+u.Now[2]+"e");
now.Now[i] = 0;
now.step = now.step + 1;
// PR(now);
String cz = " 倒空" + String.valueOf(All[i]) + "升瓶子 \n";
now.operate = now.operate + cz;
// System.out.println(now.operate + "2号"+ "\n");
Q.offer(now);
vis[now.Now[0]][now.Now[1]][now.Now[2]] = 1;
Node now_2 = new Node(u); ///倒满某个瓶子,其实这两段可以合成一段写的,太懒了,懒得整理
now_2.Now[i] = All[i];
now_2.step = now_2.step + 1;
String cz_2 = " 装满" + String.valueOf(All[i]) + "升瓶子 \n";
now_2.operate = now_2.operate + cz_2;
// System.out.println(now_2.operate + "3号"+"\n");
// PR(now_2);
Q.offer(now_2);
vis[now_2.Now[0]][now_2.Now[1]][now_2.Now[2]] = 1;
}
}
}
}
androidmanifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.a11630.waigua">
<application
android:allowBackup="true"
android:icon="@drawable/tou"
android:label="水水的外挂"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:label="水水的外挂">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
最后贴上我的代码完整包吧。
链接:https://pan.baidu.com/s/1Jm0eK_mylXRftda3VIlqNg
提取码:r4cc
复制这段内容后打开百度网盘手机App,操作更方便哦
和我的app下载地址:http://sumtudou.cn/download.html
各位发现什么问题,欢迎留言。(虽然并不会有~~~[]~( ̄▽ ̄)~*)