二进制搜索歌曲列表中的歌曲年份

时间:2019-03-24 19:22:33

标签: java arrays binary-search

我正在尝试获取代码来搜索特定年份制作的歌曲

我已经尝试实现自己的二进制搜索代码,但是它并没有打印出当年制作的所有歌曲,只有一首 类:

 public class MusicV3
{
// instance variables
private int year;
private String title;
private String artist;

// Constructor for objects of class Music
public MusicV3(String t, int y, String a)
{
    // initialize instance variables
    title = t;
    year = y;
    artist = a;
}

public String getTitle()
{
    return title;
}

public void setTitle(String t)
{
    title = t;
}

public String getArtist()
{
    return artist;
}

public void setArtist(String a)
{
    artist = a;
}

public int getYear()
{
    return year;
}

public void setTitle(int y)
{
    year = y;
}

public String toString()
{
    String str = String.format( "%-25s %4d   %-20s ", title,  year , artist);
    return str;
}
}

测试器类:

 public class MusicV3Tester2{
 public static void main(String[]args)
 {
    int find = 0;
    MusicV3[] songs = new MusicV3[10];
    MusicV3[] sortedSongs = new MusicV3[songs.length];
    songs[0] = new MusicV3("Sugar", 2014, "Maroon 5");
    songs[1] = new MusicV3("Mercy", 2016, "Shawn Mendes");
    songs[2] = new MusicV3("Shape of You", 2017, "Ed Sheeran");
    songs[3] = new MusicV3("Photograph", 2014, "Ed Sheeran");
    songs[4] = new MusicV3("Closer", 2016, "The Chainsmokers");
    songs[5] = new MusicV3("Galway Girl", 2017, "Ed Sheeran");
    songs[6] = new MusicV3("Counting Stars", 2013, "OneRepublic");
    songs[7] = new MusicV3("7 Years", 2015, "Lukas Graham");
    songs[8] = new MusicV3("Night Changes", 2014, "One Direction");
    songs[9] = new MusicV3("What Makes You Beautiful", 2011, "One Direction");

    printSongs(songs);
    System.out.println();

    sortedSongs = sortByYear(songs);
    System.out.println("Song list sorted by year:");
    //printSongs(sortedSongs);
    System.out.println();

    System.out.println("Searching for the year: 2000");
    find = findYear(songs, 2000);
    if(find != -1){
        System.out.println("We found songs made in the year 2000 in the song list: ");
        System.out.println(sortedSongs[find]);
    }
    else
        System.out.println("Songs made in the year 2000 are not in the song list");
    System.out.println();

    System.out.println("Searching for the year: 2014");
    find = findYear(songs, 2014);
    if(find != -1){
        System.out.println("We found songs made in the year 2014 in the song list: ");
        System.out.println(sortedSongs[find]);
    }
    else
        System.out.println("Songs made in the year 2014 are not in the song list");
    System.out.println();
}

public static void printSongs(MusicV3[] s)
{
    System.out.println("Song                      Year   Artist");
    System.out.println("-------------------------------------------------------");
    for(int i = 0; i < s.length; i++)
        System.out.println(s[i]);
    }

public static MusicV3[] sortByYear(MusicV3 [] movies){
    MusicV3[] sortedList = movies;
    int i;
    int k;
    int posmax;
    MusicV3 temp;
    for ( i = movies.length - 1 ; i >= 0 ; i-- )
    {
       posmax = 0;
         for ( k = 0 ; k <= i ; k++ )
         {
             if (movies[k].getYear()> movies[posmax].getYear())
             posmax = k;
            }

            temp = movies[i];
            movies[i] = movies[posmax];
            movies[posmax] = temp;
}
return sortedList;
}

public static int findYear(MusicV3[] songs, int year){
 int high = songs.length;
 int low = -1;
 int probe;

 while (high - low > 1)
 {
 probe = ( high + low ) / 2;
if (songs[probe].getYear() > year)
  high = probe;
else 
 low = probe;
} 

if(low >= 0 && songs[low].getYear() == year){
    return low;
}
else{
return -1;
}
}

}

应该从阵列中获取2000年和2014年的所有歌曲,但由于某种原因,对2000的搜索是正确的,但2014年并不正确,它只是说2014年只有一首歌曲,而有几首< / p>

2 个答案:

答案 0 :(得分:2)

songs[probe].getYear() == year的while循环中,您似乎没有检查findYear

也许:

public static int findYear(MusicV3[] songs, int year) {
    int high = songs.length;
    int low = -1;
    int probe = -1;

    while (high - low > 1) {
        probe = (high + low) / 2;
        int probeSongYear = songs[probe].getYear();

        if (probeSongYear == year) {
            break;
        } else if (probeSongYear > year)
            high = probe;
        else
            low = probe;
    }

    if (probe >= 0 && songs[probe].getYear() == year) {
        while (songs[--probe].getYear() == year) {
        }
        return probe + 1;
    }

    return -1;
}

不要忘记添加“ find =”,如下所示:

    System.out.println("Searching for the year: 2014");
    find = /* <--- ADD THIS */ findYear(songs, 2014);

要打印有关年份的所有歌曲(按评论要求):

    System.out.println("Searching for the year: 2014");
    find = findYear(songs, 2014);
    if (find != -1) {
        System.out.println("We found songs made in the year 2014 in the song list: ");
        while (sortedSongs[find].getYear() == 2014) {
            System.out.println(sortedSongs[find++]);
        }
    }

答案 1 :(得分:0)

我认为,独自实现每一件事并不总是最好的方法。

对于我来说,我会制作一个HashMap<Integer, ArrayList<MusicV3>>,它将把年份存储到歌曲列表中。

这就是最终代码的样子。

HashMap<Integer, ArrayList<MusicV3>> songs = new HashMap<>();

void addSong(MusicV3 song) {
    ArrayList<MusicV3> list = songs.get(song.year);

    if (list == null) {
        list = new ArrayList<>();
        songs.put(song.year, list);
    }

    list.add(song);
}

ArrayList<MusicV3> findSongsByYear(int year) {
    ArrayList<MusicV3> list = songs.get(year);
    if (list != null)
        return list;
    else
        return new ArrayList<>();
}