我只是编程的初学者。 uf是一个union-find类,其方法union连接两个节点的根。 如果打开任何邻居,这段代码负责打开网格的站点并将站点与其邻居联合。如果其中一个邻居已满,则填写与该站点连接的所有节点。 这是实际的代码:
if(i == 1){
uf.union(len*len, xyTo1D(i,j));
if(existAndOpen(i+1,j)){
uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndOpen(i-1,j)){
uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndOpen(i,j-1)){
uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j == len && i == len)){
if(existAndOpen(i,j+1)){
uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
}
else{
if(existAndFull(i+1,j)){
uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndFull(i-1,j)){
uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndFull(i,j-1)){
uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j== len && i == len)){
if(existAndFull(i,j+1)){
uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
if(existAndOpen(i+1,j)){
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndOpen(i-1,j)){
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndOpen(i,j-1)){
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j== len && i == len)){
if(existAndOpen(i,j+1)){
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
}
}
如何简化代码?
答案 0 :(得分:6)
试试这个
boolean f1(int a, int b) { }
boolean f2(int a, int b) { }
void A(int a, int b) { }
void testAndA(BiPredicate<Integer, Integer> p, int a, int b) {
if (p.test(a, b))
A(a, b);
}
和
if(x == 1){
testAndA(this::f1, x + 1, y);
testAndA(this::f1, x, y + 1);
} else {
testAndA(this::f2, x + 1, y);
testAndA(this::f2, x, y + 1);
}
答案 1 :(得分:1)
你可以编写一个循环来遍历可以传递给f1()的所有不同值,例如:
for (int deltax = -1; deltax <= 1; deltax++) {
for (int deltay = -1; deltay <= 1; deltay++) {
if (f1(x + deltax, y + deltay)) {
A(x + deltax, y + deltay);
}
}
}
当然,根据您需要检查的条件,更改deltax和deltay的起始值和结束值。
答案 2 :(得分:1)
你说每个街区都有“更多if语句”。在行间阅读,我认为这意味着您需要拨打f1
/ f2
和A
,但使用不同的x
和y
抵消。
这是一个程序,它显示了重构代码以避免编码重复的方法。其主要特点是:
if
块。offsets
数组来表示每个内部x
块的y
/ if
偏移量。 doIt()
方法使用循环来调用内部if
块。
public class Main {
static interface F {
void f(int i, int j);
}
static class F1Caller implements F {
public void f(int a, int b) {
if (f1(a, b)) {
A(a, b);
}
}
}
static class F2Caller implements F {
public void f(int a, int b) {
if (f2(a, b)) {
A(a, b);
}
}
}
static boolean f1(int a, int b) { System.out.print(" f1. "); return true; }
static boolean f2(int a, int b) { System.out.print(" f2. "); return true; }
static void A(int a, int b) { System.out.println("a: " + a + ", b: " + b); }
static F1Caller f1Caller = new F1Caller();
static F2Caller f2Caller = new F2Caller();
// x and y offsets for each call to f1/f2.
// Add more offset rows, as needed.
static int offsets[][] = {
{1, 0},
{0, -1}
};
static void doIt(int x, int y) {
System.out.println("x: " + x + ", y: " + y);
F f = (x == 1) ? f1Caller : f2Caller;
for (int k = 0; k < offsets.length; k++) {
f.f(x + offsets[k][0], y + offsets[k][1]);
}
}
public static void main(String[] args) {
doIt(0, 0);
doIt(1, 0);
}
}
上述程序的输出是:
x: 0, y: 0
f2. a: 1, b: 0
f2. a: 0, b: -1
x: 1, y: 0
f1. a: 2, b: 0
f1. a: 1, b: -1
答案 3 :(得分:1)
您可以将功能组合在一起。
使用开关。
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
将其与for循环集成:
public static boolean func(int a, int b, int fun)
{
boolean output = false;
switch(fun)
{
case 1:
//do stuff
output = true;
break;
case 2:
//do stuff
output = true;
break;
default:
//unknown function handling
output = false;
}
return output;
}