【问题标题】:How can I implement a function to return true if array or arrayList refers to a previous element?如果 array 或 arrayList 引用前一个元素,我如何实现一个函数以返回 true?
【发布时间】:2019-04-23 11:59:40
【问题描述】:

如果任何歌曲包含对播放列表中上一首歌曲的引用,则该播放列表被视为重复播放列表。否则,播放列表将以最后一首指向 null 的歌曲结束。

我需要实现一个函数 isRepeatingPlaylist,如果播放列表重复则返回 true,否则返回 false。

例如,以下代码打印“true”,因为两首歌曲相互指向。

Song first = new Song("Hello");
Song second = new Song("Eye of the tiger");    
first.setNextSong(second);
second.setNextSong(first);    
System.out.println(first.isRepeatingPlaylist());

再一次,这不是家庭作业,我正在做编码挑战,因为当我阅读有关编程概念的理论时,我几乎可以理解,但是当面对编写程序时,我不知道从哪里开始,或者如何开始申请。

public class Song {

    private String name;
    private Song nextSong;

    public Song(String name) {
        this.name = name;
    }

    public void setNextSong(Song nextSong) {
        this.nextSong = nextSong;
    }

    public boolean isRepeatingPlaylist() {
        //throw new UnsupportedOperationException("Waiting to be implemented.");
        List<String> list = new ArrayList<String>();
        list.add(one);
        list.add(two);
        list.add(three);
        list.add(four);

        if list.contains()
        return true;
        else
            return false;

    }

    public static void main(String[] args) {
        Song first = new Song("Hello");
        Song second = new Song("Eye of the tiger");
        Song third = new Song("a test");
        Song fourth = new Song("survivor");

        first.setNextSong(second);
        second.setNextSong(first);

        System.out.println(first.isRepeatingPlaylist();
    }
}

【问题讨论】:

  • 您的意思是“相同”还是“相等”?您应该从编写可编译的代码开始。尝试类似: String t = getTestSong();返回 list.contains(t);

标签: java arrays arraylist


【解决方案1】:

您可以循环播放播放列表并将每首歌曲添加到集合中,前提是它尚未在集合中。一旦您到达列表的末尾,您的列表就不是重复列表。如果你发现一首歌曲已经存在于集合中,你就有一个重复列表。

public boolean isRepeatingList(Song firstSong)
{
    Set<Song> uniqueSongs=new HashSet<>();
    uniqueSongs.add(firstSong);
    Song current=firstSong;
    while(current.getNextSong()!=null)
    {
        if(uniqueSongs.contains(current.getNextSong()))
            return true;
        // add the song to the set, and assign current to the next song
        uniqueSongs.add(current=current.getNextSong());
    }
    // we reached the end of the list without finding any doubles, so:
    return false;
}

【讨论】:

    【解决方案2】:

    请检查以下答案:

        public boolean isRepeatingPlaylist() {
                    Song slow = this.nextSong;
                    Song fast = slow == null ? null : slow.nextSong;
                    while (fast != null) {
                        if (slow == this || slow == fast)
                            return true;
                        slow = slow.nextSong;
                        fast = fast.nextSong;
                        if (fast != null)
                            fast = fast.nextSong;
                    }
                    return false;
                }
    

    【讨论】:

      【解决方案3】:

      我认为这可能有效:

      public boolean isRepeatingPlaylist() 
      {
          Set<Song> songs = new HashSet<Song>();
          songs.add(this);
          Song current = this.getNextSong();
          //if you did not implment a getter for the nextSong property I think you should
          while (current.getNextSong() != null && !songs.contains(current.getNextsong())) {
      
              songs.add(current);
              current = current.getNextSong();
          }
      
          return songs.contains(current.getNextsong()); 
      }
      

      编辑 1:正如该答案的 cmets 中所述,== 在某些情况下可能不是最好的,因为它比较了每个对象的 内存位置。为了解决这个问题,建议实现hashCode()equals()方法,如果你不知道它们是什么,请尝试阅读this

      【讨论】:

      • 很可能,==,虽然在技术上是正确的,但会导致不必要的情况
      • 这并不意味着两首歌曲不能引用同一首“下一首”歌曲。
      • 在以下情况下这不会是一个无限循环:1->2->3->4->2。所以循环会继续处理 2-3-4-2-3-4-2-3-4-...这些都不同于 1
      • 感谢 cmets。我会在该行中包含什么?我需要在那里传递一个参数来映射到函数,我假设? System.out.println(first.isRepeatingPlaylist());
      • 感谢 Henrique,这太棒了。它适用于一个小的测试条件,如果播放列表重复,最后一首歌应该跟着第一首歌,但我会尝试自己解决这个问题。珍惜你的时间
      【解决方案4】:

      这个问题可以认为是经典问题:链表有没有圆。你可以从here找到方法来解决,但是对于你来说构造链表并不容易,我们用另一种方法来解决这个问题:计算下一首歌曲,代码如下:

      public static boolean isRepeatingPlaylist(List<Song> songs) {
          int counts = 0;
          for (Song song : songs) {
              if (null !=song.getNextSong()){
                  counts ++;
              }
          }
          return songs.size() - counts != 1;
      }
      

      【讨论】:

        【解决方案5】:
        1. 大多数答案的问题(尤其是 Conffusion 的一个)是它没有谈论 hasCode()equals(...) 类的 equals(...) 方法,即使方法是正确的。如果这两种方法没有正确实现,uniqueSongs.contains 将不会给出正确的结果。

        OP 也没有显示Song 类的结构。

        1. OP 的代码示例中的第二件事是,哪个类应该承担哪个责任尚不清楚,如果我已经有一个自定义链表,则不需要 Java ArrayList - 尽管我已经添加了两个版本。单词的使用 - array & arrayList 问题标题令人困惑,因为 OP 有一个传统的 LinkedList & 与 Java 无关,而 arrayList 是Java 特定的 DS。

          公开课歌{

          private String data;
          private Song nextSong;
          
          public Song(String data) {
              this.data=data;
          }
          
          public String getData() {
              return data;
          }
          
          public void setData(String data) {
              this.data = data;
          }
          
          public Song getNextSong() {
              return nextSong;
          }
          
          public void setNextSong(Song nextSong) {
              this.nextSong = nextSong;
          }
          
          
          @Override
          public int hashCode() {
              final int prime = 31;
              int result = 1;
              result = prime * result + ((data == null) ? 0 : data.hashCode());
              return result;
          }
          
          
          @Override
          public boolean equals(Object obj) {
              if (this == obj)
                  return true;
              if (obj == null)
                  return false;
              if (getClass() != obj.getClass())
                  return false;
              Song other = (Song) obj;
              if (data == null) {
                  if (other.data != null)
                      return false;
              } else if (!data.equals(other.data)) {
                  return false;
              }
              return true;
          }
          

          }

        理想情况下,应该有一个 PlayList 类来创建播放列表和方法 isRepeatingPlaylist 应该属于那里。为了简单起见,我在主驱动程序类中添加了,

            import java.util.ArrayList;
            import java.util.HashSet;
            import java.util.List;
            import java.util.Set;
        
            public class RepetablePlaylist {
        
                public static void main(String[] args) {
        
                    // Begin - construct Song list 
                    Song first = new Song("Hello");
                    Song second = new Song("Eye of the tiger");
                    Song third = new Song("a test");
                    Song fourth = new Song("survivor");
        
                    first.setNextSong(second);
                    second.setNextSong(first);
        
                    List<Song> list = new ArrayList<>();
                    list.add(first);
                    list.add(second);
                    list.add(third);
                    list.add(fourth);
                    // End - construct Song list 
        
                    boolean isRepeatable = isRepeatingPlaylist(list);
                    System.out.println(" isRepeatable : "+isRepeatable);
        
        isRepeatable = isRepeatingPlaylist(first);
                System.out.println(" isRepeatable : "+isRepeatable);
                }
        
                 private static boolean isRepeatingPlaylist(List<Song> playList) {
                     Set<Song> previous = new HashSet<>();
                     for(Song song : playList) {
                         if(song.getNextSong() != null && previous.contains(song.getNextSong())) {
                             return true;
                         }
                         previous.add(song);
                     }
                     return false;
                 }
        
        private static boolean isRepeatingPlaylist(Song head) {
                 Set<Song> previous = new HashSet<>();
                 Song currentNode = head;
                 while(currentNode.getNextSong() != null ) {
                     if(previous.contains(currentNode.getNextSong())) {
                         return true;
                     }
                     previous.add(currentNode);
                     currentNode=currentNode.getNextSong();
                 }
                 return false;
             }
            }
        

        【讨论】:

        • 感谢 Sabir 的解释,非常感谢。
        【解决方案6】:

        我使用了这个代码,它可以工作,但网站告诉它不正确。 可以在类中添加另一个 int 成员吗?

        public class Song {
        private String name;
        private Song nextSong;
        private int rep = 0 ;
        
        public Song(String name) {
            this.name = name;
        }
        
        public void setNextSong(Song nextSong) {
            this.nextSong = nextSong;
        }
        
        public boolean isRepeatingPlaylist() {
            if (this.nextSong == null){
                return false;
            } else {
                rep++;
                if (rep > 1){
                    return true;
                }
                return this.nextSong.isRepeatingPlaylist();
            }
        
        }
        
        public static void main(String[] args) {
            Song first = new Song("Hello");
            Song second = new Song("Eye of the tiger");
        
        
        
            first.setNextSong(second );
            second.setNextSong(first );
        
            System.out.println(first.isRepeatingPlaylist());
        }
        

        }

        【讨论】:

          【解决方案7】:

          请检查以下答案:

          using System.Collections.Generic;
          
          
          public bool IsRepeatingPlaylist()
          {
              HashSet<Song> songs = new HashSet<Song>();
              Song current = this;
              while (current.NextSong != null && !songs.Contains(current.NextSong))
              {
                  songs.Add(current);
                  current = current.NextSong;
              }
              return songs.Contains(current.NextSong);
          }
          

          【讨论】:

          • 这与发布的其他答案有何不同?
          • 我认为这是 C# 考试任务,这是通过它的代码。它与 Henrique Sabino 非常相似,但我认为我的考试不接受答案。
          【解决方案8】:

          这是我的 c++ 代码,它运行得很好!

          #include <stdexcept>
          #include <iostream>
          #include <string>
          #include <set>
          using namespace std;
          
          class Song
          {
          public:
              Song(std::string name): name(name), nextSong(NULL) {}
          
              void next(Song* song)
              {
                  this->nextSong = song;
              }
          
              bool isRepeatingPlaylist()
          
              {
          
                  set<string> playlist;
                  Song *temp=this;
                  while(temp->nextSong!=NULL){
                      if (!playlist.insert(temp->name).second) return true;
                       temp=temp->nextSong;
                  }
                  return false;
          
              }
          
          private:
              const std::string name;
              Song* nextSong;
          };
          
          #ifndef RunTests
          int main()
          {
              Song* first = new Song("Hello");
              Song* second = new Song("Eye of the tiger");
          
              first->next(second);
              second->next(first);
          
              std::cout << std::boolalpha << first->isRepeatingPlaylist();
          }
          #endif  */
          

          【讨论】:

            猜你喜欢
            • 2017-02-06
            • 2017-01-29
            • 2016-06-18
            • 2017-02-28
            • 1970-01-01
            • 2022-11-25
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多