优化java代码以缩短时间对array/arraylist进行排序
我正在为一个测验编写一个程序,该程序要求我对一些数字进行排序并打印相应的字符串 为此,我创建了一个类优化java代码以缩短时间对array/arraylist进行排序,java,arrays,arraylist,comparator,Java,Arrays,Arraylist,Comparator,我正在为一个测验编写一个程序,该程序要求我对一些数字进行排序并打印相应的字符串 为此,我创建了一个类Song,并获取了这个类的一个对象数组。我必须根据变量qi进行排序。问题是,根据法官的说法,我的解决方案耗时太多,效率不够。早些时候,我尝试了对象的ArrayList,并切换到可以在一定程度上优化它的数组思维,但没有任何帮助 如何进一步优化它 我的代码: class Song{ long fi; long qi; String si; public Song
Song
,并获取了这个类的一个对象数组。我必须根据变量qi
进行排序。问题是,根据法官的说法,我的解决方案耗时太多,效率不够。早些时候,我尝试了对象的ArrayList
,并切换到可以在一定程度上优化它的数组思维,但没有任何帮助
如何进一步优化它
我的代码:
class Song{
long fi;
long qi;
String si;
public Song(long fi,String si, long qi){
this.fi = fi;
this.si = si;
this.qi = qi;
}
}
public class Zipf {
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
long fi;
long qi;
String si;
int noOfSongs = scan.nextInt();
int selection = scan.nextInt();
List<Song> list=new ArrayList<Song>(); // all songs
TreeSet<Song> set = new TreeSet<Song>(new treeComparator());
for(int i=0; i< noOfSongs;i++)
{
fi=(scan.nextLong());
si=(scan.next());
qi=(fi*(i+1));
list.add(new Song(fi,si,qi));//adding all songs to list
}
for(int i=0; i< selection;i++)
{
set.add(list.get(i));//adding no of songs to be selected into set
}
Song min = set.first();
for (int i = selection; i < list.size(); i++) {
Song song = list.get(i);
if (song.qi > min.qi) {
set.remove(min);
set.add(song);
min = set.first();
}
}
Iterator<Song> iterator = set.descendingIterator();
//Displaying the Tree set data
for(int i=0;i<selection;i++){
System.out.println(iterator.next().si);
}
}
}
class treeComparator implements Comparator<Song>{
@Override
public int compare(Song o1, Song o2) {
if (o1.qi <= o2.qi) return -1;
if (o1.qi > o2.qi) return 1;
return 0;
}
}
class歌曲{
长fi;
龙琦;
串硅;
公歌(龙菲、弦丝、龙琦){
this.fi=fi;
this.si=si;
这个。气=气;
}
}
公共类Zipf{
公共静态void main(字符串[]args)
{
扫描仪扫描=新扫描仪(System.in);
长fi;
龙琦;
串硅;
int noOfSongs=scan.nextInt();
int selection=scan.nextInt();
List List=new ArrayList();//所有歌曲
树集=新树集(新树比较器());
for(int i=0;i民齐){
设置。移除(最小值);
设置。添加(歌曲);
min=set.first();
}
}
迭代器迭代器=set.degenerationIterator();
//显示树集数据
对于(int i=0;i,就大O复杂性而言,您的解决方案是最优的。无论您使用的是数组还是ArrayList,排序都需要O(nlogn)
您可以在小范围内进行优化,例如避免在compare
方法中创建新的丢弃对象。但在大范围内,这将对性能产生边际影响
因此,你确定你对任务的一般方法是正确的吗?我的意思是,你真的需要对列表进行排序吗?例如,如果任务只是为了找到最小的qi
,你可以不对整个列表进行排序。这可以概括为n
最小的qi
,如下:
List<Song> list; // all songs
int n; // provided by user
TreeSet<Song> set = new TreeSet<Song>(new Comparator() ...);
for (int i = 0; i < n; i++) {
set.add(list.get(i));
}
Song max = set.last();
for (int i = n; i < list.size(); i++) {
Song song = list.get(i);
if (song.qi < max.qi) {
set.remove(max);
set.add(song);
max = set.last();
}
}
您也可以使用TreeMap
,键为qi
,值为Song class
的对象,这样在创建时它就会被排序。如果排序是您的主要目的,那么就选择TreeSet
,如果它需要经常获取数据,那么ArrayList
是一个不错的选择
编辑
ArrayList
具有预定的max size
更快,因为它减少了增量重新分配的数量。因此,如果您知道歌曲的最大数量,那么这将更快。您的法官是否特别抱怨排序?这里我唯一的一点是不要创建Long
对象并使用Long.comparee(宋1.qi,宋2.qi)
取而代之。也许你没有发布代码中的其他内容?我尝试使用Long.compare,但我的eclipse显示错误。我代码中的其余部分只是根据此排序扫描输入和打印。有多少首歌曲需要判断/排序?最大限制为50000首。测验问题的确切措辞是什么?谢谢你的回答。我没有找到比较两个long的其他工作方法。在eclipse中使用long.compare会出现错误。我确实需要对元素进行排序!我必须按降序打印n个元素。n取自用户输入。通过减法进行比较会带来溢出风险。您编辑的代码非常有帮助。我将遵循此操作并重试。非常感谢。@assyli非常好的一点是,我去掉了减法。谢谢。@assylias很酷-我实际上在API文档中寻找了这个方法,但它不在那里…但现在我明白了,因为它是在1.7中添加的,我看了1.6(我不喜欢最近的API文档的外观和感觉,我认为该方法(如果有的话)从早期版本就已经存在了。)我需要根据qi进行排序,并为n(用户输入)打印si已排序的对象。使用它会更有效吗?请在这里添加哪个操作将发生更多的时间排序或打印。存储对象的数据结构只需要排序一次,然后在此基础上,首先要打印n个已排序对象的si。我希望我没有误解你的问题。是的,这是正确的我想知道的是。所以最好的选择是使用ArrayList
。
public int compare(Song s1, Song s2) {
if (s1.qi < s2.qi) return -1;
if (s1.qi > s2.qi) return 1;
return 0;
}