2013-03-23 71 views
2

好的,我的教授(数据结构类)分配了这个:你的任务是编写一个程序,可以在双链表中更新字符访问频率。程序应该从包含许多字符的文本文件中一次读取一个字符。为了更容易,不要计算空格。每次访问字符时,在列表的节点中将其访问频率递增1。如果当前节点的频率高于其前一个节点的频率,则需要在列表中交换两个节点。继续为所有先前的节点这样做,直到没有更多的前一个节点具有较低的访问频率。最终,频率最高的字符将出现在列表的开头,次高的字符将出现在下一个节点等。您的程序还需要根据列表的顺序打印出列表中的字符。Java双链表

这是我迄今为止制作的程序。这只是一个双向链表。 我的主要问题是我应该如何去做:“每次访问一个字符时,在列表的节点中将其访问频率增加1,如果当前节点的频率高于其前一个节点的频率,则两个节点需要在列表中交换。“?

我知道没有任何行从文件中获取信息。我将在稍后补充。 任何帮助表示赞赏!

public class DoublyLinkedList { 
private class Node { 
    String value; 
    Node next,prev; 

    public Node(String val, Node n, Node p) { 
     value = val; 
     next = n; 
     prev=p; 
    } 

    Node(String val) { 
     this(val, null, null); 
    } 
} 
private Node first; 
private Node last; 

public DoublyLinkedList() { 
    first = null; 
    last = null; 
} 
public boolean isEmpty(){ 
    return first==null; 
} 
public int size(){ 
    int count=0; 
    Node p=first; 
    while(p!=null){ 
     count++; 
     p=p.next; 
    } 
    return count; 
} 
public void add(String e) { 

    if(isEmpty()){ 
     last=new Node(e); 
     first=last; 
    } 
    else{ 
     last.next=new Node(e, null, last); 
     last=last.next; 
    } 
} 
public void add(int index, String e){ 
    if(index<0||index>size()){ 
     String message=String.valueOf(index); 
     throw new IndexOutOfBoundsException(message); 
    } 
    if(index==0){ 
     Node p=first; 
     first=new Node(e,p,null); 
     if(p!=null) 
      p.prev=first; 
     if(last==null) 
      last=first; 
     return; 
    } 
    Node pred=first; 
    for(int k=1; k<=index-1;k++){ 
     pred=pred.next; 
    } 
    Node succ=pred.next; 
    Node middle=new Node(e,succ,pred); 
    pred.next=middle; 
    if(succ==null) 
     last=middle; 
    else 
     succ.prev=middle; 
} 
public String toString(){ 
    StringBuilder strBuilder=new StringBuilder(); 
    Node p=first; 
    while(p!=null){ 
     strBuilder.append(p.value+"\n"); 
     p=p.next; 
    } 
    return strBuilder.toString(); 
} 
public String remove(int index){ 
    if(index<0||index>=size()){ 
     String message=String.valueOf(index); 
     throw new IndexOutOfBoundsException(message); 
    } 
    Node target=first; 
    for(int k=1; k<=index;k++){ 
     target=target.next; 
    } 
    String element=target.value; 
    Node pred=target.prev; 
    Node succ=target.next; 
    if(pred==null) 
     first=succ; 
    else 
     pred.next=succ; 
    if(succ==null) 
     last=pred; 
    else 
     succ.prev=pred; 
    return element; 
} 
public boolean remove(String element){ 
    if(isEmpty()) 
     return false; 
    Node target=first; 
    while(target!=null&&!element.equals(target.value)) 
     target=target.next; 
    if(target==null) 
     return false; 
    Node pred=target.prev; 
    Node succ=target.next; 
    if(pred==null) 
     first=succ; 
    else 
     pred.next=succ; 
    if(succ==null) 
     last=pred; 
    else 
     succ.prev=pred; 
    return true; 
} 
public static void main(String[] args){ 
    DoublyLinkedList list1=new DoublyLinkedList(); 
    String[] array={"a","c","e","f"}; 
    for(int i=0; i<array.length; i++){ 
     list1.add(array[i]); 
    } 
    list1.add(1,"b"); 
    list1.add(3,"d"); 
    System.out.println(list1); 

} 


} 

回答

4

由于这是一门功课分配新建分配FY,我只给出提示:

  • Node类需要一个额外的字段的计数器。

  • 您需要遍历列表以查找所访问的字符并增加其计数器值。

  • 您需要一个临时的Node对象来交换节点。先尝试一下,然后谷歌它。这是每个程序员必须知道的基本过程。

+0

*您的Node类需要一个额外的字段为计数器*我不会推荐这个,而是使用不同于'String'的类作为包含'counter'和字符的'Node'的值。请记住链表节点应该只有数据和指向其他节点的指针。 – 2013-03-24 00:09:36

+0

@LuiggiMendoza为什么?它只有两个字段,为什么要将它们聚合到一个类中? – Sebastian 2013-03-24 00:11:34

+2

@LuiggiMendoza - 请阅读问题。他就是这样告诉**解决问题的。这是学习编码的学习/教学练习,而不是寻找解决问题的最佳算法的练习。 ('因为我们都知道这将是使用TreeMap ...) – 2013-03-24 00:21:16

0

建议:

“我知道有没有得到该文件中的信息的任何行。”。现在写这些代码会更好,这样你就可以测试你已经写的东西了。

另一个问题是,你到目前为止写的是一个通用的链表,忽略了要求如何使用列表的要求。其结果是,你必须:

  • 实现了一堆,似乎是不必要的方法,并
  • 不是要求正确实施的节点类。

回去看看需求,找出你真正需要的方法,然后实现它们。 (到目前为止,你所做的是一种“自下而上”的设计,很大程度上忽略了最高级别的需求,用“自上而下”的方法会更好。)

你被要求解决的问题正在整理字符,而不是创建“通用”链接列表数据结构。

0

我会建议将程序分解成组件。你知道你需要保持和更新计数,正如塞巴斯蒂安上面所说的。你也知道你需要能够比较一个节点的数量和排名中它上面的节点的数量。你知道你需要能够交换两个节点。你应该有这些东西的方法。思考每种分解方法需要发生的事情。

我总是推荐一种物理方法来解决这些问题,以获得它们的感觉:尝试使用一组便签纸或便签纸做这件事。在每一个上,写一个对象名称和Node对象的字段。用铅笔写字段值。记下一张纸上的其他字段(如第一个元素的引用)。然后遍历算法并查看每次更新需要更改的内容。 (注意:因为这是一个双向链接列表,所以你的改变应该可以在洗牌过程中生存下来)试试吧,看看)

祝你好运!