- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
=> 最后去看看Edit2 :)
对不起,我的英语说得不太好..:)
问题很简单。我有一个包含 10000 点的 file.txt
。而且我必须计算可能的方 block 数。
例如:[-1,-1][2,1][4,-2][1,-4]是正方形
我用java做了一个算法但是有个大问题...要执行它,我需要 15 小时 !!!
我会给你我的代码,如果你认为我可以优化它,请告诉我如何优化! :)
主.java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import elements.*;
public class Main
{
public static void main(String[] parameters)
{
try
{
//String nameFile = parameters[0];
FileInputStream fileInputStream = new FileInputStream(new File("exercice4.txt"));
Processing processing = new Processing();
processing.read(fileInputStream);
processing.maxLenght();
//processing.changeTest();
processing.generateSquare();
try
{
FileWriter fileWriter = new FileWriter(new File("Square.txt"));
processing.write(fileWriter);
fileWriter.close();
}
catch (IOException exception)
{
System.out.println("Erreur lors de l'écriture dans le fichier");
}
System.out.println(processing.countSquare());
System.out.println("Fin");
try
{
fileInputStream.close();
}
catch (IOException exception)
{
System.out.println("Une erreur s'est produite lors de la fermeture de l'InputStream");
}
}
catch(FileNotFoundException exeption)
{
System.out.println("Le nom de fichier placé en paramètre est incorrect");
}
}
}
Processing.java
package elements;
import java.util.ArrayList;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.*;
import elements.*;
public class Processing
{
private ArrayList<Point> points;
private ArrayList<Square> squares;
private int maxY;
private int maxX;
private int minX;
public Processing()
{
this.points = new ArrayList<Point>();
this.squares = new ArrayList<Square>();
this.maxX = 0;
this.maxY = 0;
this.minX = 0;
}
public void read(FileInputStream f)
{
int readReturn;
int X = 0;
int Y = 0;
String string = "";
try
{
while ((readReturn = f.read()) != -1)
{
if(readReturn-48 == -38)
{
Y = Integer.parseInt(string);
Point point = new Point(X,Y);
if(!presentPoint(point))
{
points.add(point);
}
string = "";
}
else if(readReturn-48 == -16)
{
X = Integer.parseInt(string);
string = "";
}
else if(readReturn-48 == -3)
{
string += "-";
}
else
{
string += Integer.toString(readReturn-48);
}
}
}
catch(IOException exception)
{
System.out.println("Probleme lors de la lecture du fichier");
}
}
public void maxLenght()
{
Point reference = points.get(0);
int maxX = reference.getX();
int minX = reference.getX();
int maxY = reference.getY();
int minY = reference.getY();
for(Point point : points)
{
if(point.getX() < minX)
{
minX = point.getX();
}
else if(point.getX() > maxX)
{
maxX = point.getX();
}
if(point.getY() < minY)
{
minY = point.getY();
}
else if(point.getY() > maxY)
{
maxY = point.getY();
}
}
this.maxX = maxX;
this.maxY = maxY;
this.minX = minX;
}
public boolean samePoint(Point point1, Point point2)
{
boolean same = false;
if(point1.getX() == point2.getX() && point1.getY() == point2.getY())
{
same = true;
}
return same;
}
public boolean presentPoint(Point newPoint)
{
boolean present = false;
int counter = 0;
Point point;
while(present == false && counter < points.size())
{
point = this.points.get(counter);
if(samePoint(point, newPoint))
{
present = true;
}
counter++;
}
return present;
}
public boolean presentPoint(Point botomRight, Point topLeft, Point topRight)
{
boolean present = false;
boolean botomRightPresent = false;
boolean topLeftPresent = false;
boolean topRightPresent = false;
int counter = 0;
Point point;
while(present == false && counter < points.size())
{
point = this.points.get(counter);
if(samePoint(point, botomRight))
{
botomRightPresent = true;
}
if(samePoint(point, topLeft))
{
topLeftPresent = true;
}
if(samePoint(point, topRight))
{
topRightPresent = true;
}
if(botomRightPresent && topLeftPresent && topRightPresent)
{
present = true;
}
counter++;
}
return present;
}
public void generateSquare()
{
Point testBotomRight;
Point testTopLeft;
Point testTopRight;
int counter = 0;
for(Point point : this.points)
{
System.out.println(counter);
counter++;
for(int j = 0; j < this.maxY-point.getY(); j++)
{
for(int i = 1; i < this.maxX-point.getX(); i++)
{
if(verifiyBoundary(i, j, point))
{
testBotomRight = new Point(point.getX()+i, point.getY()+j);
testTopLeft = new Point(point.getX()-j, point.getY()+i);
testTopRight = new Point(point.getX()+i-j, point.getY()+i+j);
if(presentPoint(testBotomRight, testTopLeft, testTopRight))
{
Square square = new Square(point, testBotomRight, testTopLeft, testTopRight);
this.squares.add(square);
System.out.println(point.display());
System.out.println(testBotomRight.display());
System.out.println(testTopLeft.display());
System.out.println(testTopRight.display());
System.out.println("");
}
}
}
}
}
}
public boolean verifiyBoundary(int i, int j, Point point)
{
boolean verify = true;
if(point.getX() + i + j > this.maxY)
{
verify = false;
}
if(point.getX() - j < this.minX)
{
verify = false;
}
return verify;
}
public String countSquare()
{
String nbSquare = "";
nbSquare += Integer.toString(this.squares.size());
return nbSquare;
}
public void changeTest()
{
Point point = points.get(9);
point.setX(0);
point.setY(0);
point = points.get(100);
point.setX(0);
point.setY(2);
point = points.get(1000);
point.setX(2);
point.setY(2);
point = points.get(1886);
point.setX(2);
point.setY(0);
}
public void write(FileWriter fileWriter)
{
for(Square square : squares)
{
try
{
fileWriter.write(square.getVertexBottomLeft().display() + square.getVertexBottomRight().display() + square.getVertexTopRight().display() + square.getVertexTopLeft().display() + "\r\n");
}
catch (IOException e)
{
System.out.println("Erreur lors de l'écriture des carrés");
}
}
}
}
点.java
package elements;
public class Point
{
private int X;
private int Y;
public Point(int X, int Y)
{
this.X = X;
this.Y = Y;
}
public int getX()
{
return this.X;
}
public int getY()
{
return this.Y;
}
public void setX(int X)
{
this.X = X;
}
public void setY(int Y)
{
this.Y = Y;
}
public String display()
{
return ("[" + Integer.toString(this.X) + "," + Integer.toString(this.Y) + "]");
}
}
Square.java
package elements;
public class Square
{
private Point vertexBottomLeft;
private Point vertexBottomRight;
private Point vertexTopLeft;
private Point vertexTopRight;
public Square()
{
this.vertexBottomLeft = null;
this.vertexBottomRight = null;
this.vertexTopLeft = null;
this.vertexTopRight = null;
}
public Square(Point vertexBottomLeft, Point vertexBottomRight, Point vertexTopLeft, Point vertexTopRight)
{
this.vertexBottomLeft = vertexBottomLeft;
this.vertexBottomRight = vertexBottomRight;
this.vertexTopLeft = vertexTopLeft;
this.vertexTopRight = vertexTopRight;
}
public Point getVertexBottomLeft()
{
return this.vertexBottomLeft;
}
public Point getVertexBottomRight()
{
return this.vertexBottomRight;
}
public Point getVertexTopLeft()
{
return this.vertexTopLeft;
}
public Point getVertexTopRight()
{
return this.vertexTopRight;
}
}
我的程序在 Processing.java 的 generateSquare() 函数中停留了 15 小时
非常感谢您的帮助!
编辑:我需要降低复杂度 = 1,000,000,000,000 我该怎么做?
EDIT2:感谢@BarrySW19,我们减少了执行时间:现在为 5000 毫秒但我需要减少 200-500 毫秒,有人有想法吗?我给你Processing.java
的新代码package elements;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
public class Processing
{
private Set<Point> points;
private List<Square> squares;
private int maxY;
private int maxX;
private int minX;
public Processing()
{
this.points = new HashSet<Point>();
this.squares = new ArrayList<Square>();
this.maxX = 0;
this.maxY = 0;
this.minX = 0;
}
/*
* Fonction de lecture du fichier input qui stocke les points dans une structure de données adaptée
* Ici la structure choisi de stockage de données est un hashSet.
* param : InputStream lié au fichier dans lequel lire les données
*
* Suivant les valeur des entiers retournés on détecte un retour chariot (sauvegarde du point)
* ou un espace (saisie terminée de l'abscisse)
*/
public void read(FileInputStream f)
{
int readReturn;
int X = 0;
int Y = 0;
String string = "";
try
{
while ((readReturn = f.read()) != -1)
{
if(readReturn-48 == -38)
{
Y = Integer.parseInt(string);
Point point = new Point(X,Y);
if(!presentPoint(point))
{
points.add(point);
}
string = "";
}
else if(readReturn-48 == -16)
{
X = Integer.parseInt(string);
string = "";
}
else if(readReturn-48 == -3)
{
string += "-";
}
else
{
string += Integer.toString(readReturn-48);
}
}
}
catch(IOException exception)
{
System.out.println("Probleme lors de la lecture du fichier");
}
}
/*
* Fonction qui sauvegarde les abscisses et ordonnés minimum et maximum des points présents
* Ceci servira à l'optimisation du programme
*/
public void maxLenght()
{
int maxX = -10000;
int minX = 10000;
int maxY = -10000;
int minY = 10000;
for(Point point : points)
{
if(point.getX() < minX)
{
minX = point.getX();
}
else if(point.getX() > maxX)
{
maxX = point.getX();
}
if(point.getY() < minY)
{
minY = point.getY();
}
else if(point.getY() > maxY)
{
maxY = point.getY();
}
}
this.maxX = maxX;
this.maxY = maxY;
this.minX = minX;
}
/*
* A l'aide de la réécriture de la fonction hashCode() et equals() cette fonction nous renvoie si un objet est présent dans le hashSet
*/
public boolean presentPoint(Point newPoint)
{
return this.points.contains(newPoint);
}
/*
* A l'aide de la réécriture de la fonction hashCode() et equals() cette fonction nous renvoie si un objet est présent dans le hashSet
*/
public boolean presentPoint(Point botomRight, Point topLeft, Point topRight)
{
return (this.points.contains(botomRight) && this.points.contains(topRight) && this.points.contains(topLeft));
}
public void generateSquare()
{
for(Point p: points)
{
// Trouve tous les points pouvant servir de coin topRight
Set<Point> pointsUpAndRight = points.stream().filter(p2 -> p2.getX() > p.getX() && p2.getY() >= p.getY()).collect(Collectors.toSet());
for(Point p2: pointsUpAndRight)
{
// calcul les vecteurs de trasformation
int[] transform = new int[] { p2.getX() - p.getX(), p2.getY() - p.getY() };
if(p.getY()+transform[0] <= this.maxY && p.getX()-transform[1] >= this.minX)
{
// génère les 2 points manquants
Point p3 = new Point(p2.getX() - transform[1], p2.getY() + transform[0]);
Point p4 = new Point(p3.getX() - transform[0], p3.getY() - transform[1]);
if(points.contains(p3) && points.contains(p4))
{
Square s = new Square(p, p3, p2, p4);
squares.add(s);
}
}
}
}
}
/*
* Fonction de basique qui répond au problème de comptage de carré
*/
public String countSquare()
{
String nbSquare = "";
nbSquare += Integer.toString(this.squares.size());
return nbSquare;
}
/*
* Cette fonctionalité suplémentaire permet de stocker dans un fichier .txt les carrés présents parmi la liste de points
*/
public void write(FileWriter fileWriter)
{
for(Square square : squares)
{
try
{
fileWriter.write(square.getVertexBottomLeft().display() + square.getVertexBottomRight().display() + square.getVertexTopRight().display() + square.getVertexTopLeft().display() + " est un carré valide " + "\r\n");
}
catch (IOException e)
{
System.out.println("Erreur lors de l'écriture des carrés");
}
}
}
}
最佳答案
检查一个值是否包含在一个集合中的时间复杂度为 O(1),而检查一个值是否包含在一个数组列表中的时间复杂度为 O(n)。
所以加快速度的一种方法是使用 Set
而不是 ArrayList
要使用 set 你需要覆盖 hashCode
和 equals
方法:
将以下内容添加到您的 Point
类
class Point{
...
int hashCode=-1;
@Override
public int hashCode(){
if(hashCode==-1){
hashCode=Objects.hash(x,y);
}
return hashCode;
}
@Override
public boolean equals(Object o){
if(o instanceOf this.getClass()){
Point p=(Point) o;
return p.x==x && p.y==y;
}
return false;
}
}
在类 Processing
中更改:
private ArrayList<Point> points;
到:
private HashSet<Point> points;
然后将您的方法 presentPoint
更改为:
public boolean presentPoint(Point p ){
return points.contains(p);
}
public boolean presentPoint(Point p1,Point p2,Point p3 ){
return points.contains(p1) && points.contains(p2) && points.contains(p3);
}
关于java - 简单练习的算法速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33366853/
K&R 前。 4.2 要求您修改给定的(非标准)atof 函数,该函数缺少处理指数的指数处理机制(如 123e6 或 456e-7)。我添加了一个最小的更改来处理正确输入的、无空格的个位数指数。为了检
我正在学习计算机科学入门类(class)的考试,我对“常规”算法和递归算法中的复杂性主题有疑问(通常我们将这些问题写成 C 代码). 我想知道 Internet 和/或书籍中是否有涵盖该主题的基础级别
console.log( ‘blah’.repeatMe( 3 ) ); 使用 Javascript 编写代码,使前面的函数打印: 输出:blahblahblah 最佳答案 噢,放弃函数式解决方案太有
我正在准备 Java SE 7 认证考试,并且正在做一些关于继承和访问修饰符的无聊练习。 但是现在我在应用继承时遇到了意外的行为。在我的基础包 com.testpkg 中,我有一个抽象类: packa
我刚刚开始了 C 语言队列的第一课,我得到了创建队列、向队列添加元素和删除元素的练习。但是,我在检查队列是满还是空时遇到了麻烦。 #include typedef struct FloatQueue
请问我从昨天开始就被困在下面这个问题中了。下面是问题: Write a program that uses console.log to print all the numbers from 1 to
我最近尝试了一些 Java,希望对我的风格进行一些评论。如果你喜欢看这个放在图像中的练习,并告诉我我的风格是否足够好?或者是做的还不够好,可以告诉我应该在哪方面多下工夫,帮我改进一下? exercis
我对手动编写 SQL 查询还很陌生,而且我有一个我似乎无法解决的练习。 我了解解决此问题所需的工具,但我就是想不出解决方案。 你能帮助我理解如何以一种能让我在未来解决类似练习的方式解决这个问题吗? 我
好吧,这就是练习: Define a class named student, containing three grades of students. The class will have a f
我是一个 JS 菜鸟,试图制作这个“你好,先生/小姐 你的名字!”干净的。我看不到在 if/else 中重构警报的方法,因为那样我就失去了 var b 的值。 JS: "use strict
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
反转二维数组的值,可以扩展 n 次。 [1, [2, [3, ... [n, null]]]] 给定: 所有数组的长度始终为 2 列表中的最后一个数组将包含一个 null 索引 1 示例: [1, [
我试图通过 Jason Hickey 笔记自学 OCaml,下面的练习让我难住了。 问题:编写一个函数 sum 给定两个整数边界 m,n 和函数 f 计算求和。 我正在尝试这个: let r
这是一个生成斐波那契数列的程序,这里是引用:http://sicp.org.ua/sicp/Exercise1-19 据说我们可以将程序视为“a <- bq + aq + ap and b <- bp
所以,我正在努力通过 SICP。 第 4 章的第一个练习是: Exercise 4.1. Notice that we cannot tell whether the metacircular eva
这个问题已经有答案了: Count the number of occurrences of a character in a string in Javascript (39 个回答) 已关闭 6
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭10 年前。 Improve th
我目前正在学习 JS,并且正在尝试进行编码练习。到目前为止,我已经成功地使用离线和在线部分代码的大量资源拼凑了以下代码。我已经非常接近了 - 只是结果中的数字无法正确。 一些背景:在函数中输入一个对象
我需要创建一个回收器 View 练习,这是一个带有简单的单个回收器的应用程序加载大小为 20 的页面,并且可以容纳无限数量的项目。 现在我不想做出重新加载越来越多的项目的幼稚解决方案,而是一个优雅的解
下面的实现正确吗? 输入:Oldrecords(GameRecord 对象数组)和 newRecords (GameRecord) 我将检查 oldRecords 数组中的 newRecord 值。如
我是一名优秀的程序员,十分优秀!