Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我的编码似乎效率低下。。。有没有办法加快速度?_Java - Fatal编程技术网

Java 我的编码似乎效率低下。。。有没有办法加快速度?

Java 我的编码似乎效率低下。。。有没有办法加快速度?,java,Java,所以我尝试了这个程序,它应该能找出这些门的位置。它们一开始是关着的,然后你打开每扇门。下次你每秒钟切换一次,然后每三、四次切换一次,依此类推。我把代码编对了,但似乎效率很低。如果我尝试使用更大的数字,那么程序将花费太长时间。有没有办法更有效地做到这一点?这是我的代码: public class doors { public static void main(String [] args) { int x, y = 1; boolean [] doors = new b

所以我尝试了这个程序,它应该能找出这些门的位置。它们一开始是关着的,然后你打开每扇门。下次你每秒钟切换一次,然后每三、四次切换一次,依此类推。我把代码编对了,但似乎效率很低。如果我尝试使用更大的数字,那么程序将花费太长时间。有没有办法更有效地做到这一点?这是我的代码:

 public class doors
 {
  public static void main(String [] args)
  {
    int x, y = 1;
    boolean [] doors = new boolean[100];
    for (int a = 0; a < doors.length; a++)
      doors[a] = false; //false means closed
    do
    {
      for (x = 0; x < doors.length - 1; x++)
      {
        if ((x+1) % y == 0)
        {
          if (doors[x] == true)
            doors[x] = false;
          else if (doors[x] == false)
            doors[x] = true;
        }        
      }
      y++;
    }while (y <= doors.length);
    for (boolean b : doors)
    System.out.println(b);
  }
}
    // Thanks!!!
公共类门
{
公共静态void main(字符串[]args)
{
int x,y=1;
布尔值[]门=新布尔值[100];
对于(int a=0;a}(y而不是使用for语句,而是使用foreach和switch

范例

for(boolean i:doors){
   //do something  
            }

首先,您的
doors
数组中的默认值为false(但您可以使用
数组。如果需要,可以使用
填充
来填充)。接下来,您只需将循环增加
y
。然后您可以使用
doors[x]=!doors[x];
。类似于

int y = 1;
boolean[] doors = new boolean[100];
// Arrays.fill(doors, false);
do {
    for (int x = y - 1; x < doors.length; x += y) {
        doors[x] = !doors[x];
    }
    y++;
} while (y <= doors.length);
System.out.println(Arrays.toString(doors));

正如上面提到的,你可以做很多事情来简化代码。通过这样做,你将开始更好地看到正在使用的算法,从而看到它们可以改进的地方

对于这样的代码,简化if语句通常更多的是为了澄清代码而不是提高性能。我之所以说这是因为现在的编译器非常适合优化代码,虽然可能会删除一些指令,但性能差异可能很小

你更有可能获得显著改进的地方是有循环的地方。减少循环中的迭代次数通常会对总时间产生显著影响。为此,我可以看到两个可能的地方,你可以改进事情

首先,可能不需要初始设置循环。我没有检查,但是默认情况下,门的数组可能为false,因此可能会放弃通过循环进行初始化

第二,内环增加1,然后测试该门是否与y匹配。通过简单地将内环增加y,您可以短路很多。这样,您将始终处于要翻转的门上。这意味着您可以放弃对正确门的测试,只需翻转它。随着y的增加,x循环的迭代次数将增加减少。意味着每次y增加时它都会加速


最后,当我看到这样的代码时,我总是推荐一件事。总是在if语句上加括号。如果不使用括号,很容易引入细微的错误。

让我们一步一步地简化代码


1) 分配数组时,所有元素都初始化为其默认值,这意味着
0
false
null
。在您的情况下,这意味着
false
,因此无需循环执行

// before
boolean [] doors = new boolean[100];
for (int a = 0; a < doors.length; a++)
    doors[a] = false; //false means closed

// after
boolean[] doors = new boolean[100];

3a)
doors[x]==true
doors[x]
相同
doors[x]==false
!doors[x]
相同

3b)
if(x){}else if(!x){}
if(x){}else{}
相同。
else
之后的测试是多余的

3c)
如果(x)x=false;否则x=true;
x=!x;
相同

3d)您可以通过执行
^=true
(XOR)跳过双重计算


4a)
(x+1)%y==0
仅对
y-1
2*y-1
3*y-1
等的
x
值有效,因此循环从
y-1
开始,并以
y
递增,从而消除了
if
语句的需要

4c)由于循环后不使用
x
,因此可以在循环中声明

// before
int x, y = 1;
do
{
    //code
    y++;
}while (y <= doors.length);

// after
int x;
for (int y = 1; y <= doors.length; y++)
{
    //code
}
// before
int x;
for (x = 0; x < doors.length - 1; x++)
{
    if ((x+1) % y == 0)
    {
        //code
    }
}

// after
for (int x = y - 1; x < doors.length - 1; x += y)
{
    //code
}

6a)每行打印一个布尔值
true
/
false
的数组不是很容易让人读懂。打印是作为一行上的二进制数进行的

// before
for (boolean b : doors)
    System.out.println(b);

// after
for (boolean b : doors)
    System.out.print(b ? '1' : '0');
System.out.println();

7a)将打印移动到外环内,您将看到一个有趣的图案

boolean[] doors = new boolean[100];
for (int y = 1; y <= doors.length; y++) {
    for (int x = y - 1; x < doors.length; x += y)
        doors[x] ^= true;
    for (boolean b : doors)
        System.out.print(b ? '1' : '0');
    System.out.println();
}

现在,当您查看结果的模式(最后一行)时,您将看到您的代码可以简化为(非常快):


这更适合codereview.stackexchange.com,应该移到那里。在一个小问题上提问,就是删除
if/else
检查值更改,只需执行
doors[x]=!doors[x]
。它将删除比较检查。但是,为了更好地审查,codereview网站是一个不错的选择。同意这是离题的,但您的整个4行真/假翻转可能是
doors[x]=!doors[x]
而不是if。对不起,我是新手,不知道该把什么放在哪里……感谢您的输入。如何使用foreach更改当前值?
(x+1)%y==0
对于
x
的以下值是正确的:
y-1
2*y-1
3*y-1
,…,所以循环应该从
int x=y-1
开始---另外,外部
do while
循环也可以是一个简单的
循环。简化了代码。代码已经
y,谢谢,这很有帮助。原谅我,但我是fa我对编程很陌生。^=是什么意思?@SamuelBrice
^=
类似于
+=
,也就是说,
a^=b
a=a^b
的缩写
^
是异或运算符,可以用于OR,这就是我在这里要做的。
boolean[] doors = new boolean[100];
for (int y = 1; y <= doors.length; y++)
    for (int x = y - 1; x < doors.length - 1; x += y)
        doors[x] ^= true;
for (boolean b : doors)
    System.out.println(b);
// before
for (int x = y - 1; x < doors.length - 1; x += y)

// after
for (int x = y - 1; x < doors.length; x += y)
// before
for (boolean b : doors)
    System.out.println(b);

// after
for (boolean b : doors)
    System.out.print(b ? '1' : '0');
System.out.println();
boolean[] doors = new boolean[100];
for (int y = 1; y <= doors.length; y++) {
    for (int x = y - 1; x < doors.length; x += y)
        doors[x] ^= true;
    for (boolean b : doors)
        System.out.print(b ? '1' : '0');
    System.out.println();
}
boolean[] doors = new boolean[100];
for (int idx = 0, incr = 1; idx < doors.length; idx += (incr += 2))
    doors[idx] = true;
//print here