2

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

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

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

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

3 回答 3

4

由于这是一个家庭作业,我只会给出提示:

  • 您的Node班级需要一个额外的字段作为计数器。

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

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

于 2013-03-24T00:06:25.650 回答
0

建议:

“我知道没有任何线路从文件中获取信息。”. 您最好现在编写该代码,以便您可以测试您已经编写的内容。

另一个问题是您到目前为止所写的是一个通用链表,而忽略了说明如何使用该列表的要求。结果,您有:

  • 实现了一堆看似不必要的方法,并且
  • 未根据要求正确实现 Node 类。

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

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

于 2013-03-24T00:18:02.037 回答
0

我建议将程序分解为组成部分。正如塞巴斯蒂安上面所说,您知道您需要保留和更新计数。您还知道您需要能够将节点的计数与排名中高于它的节点的计数进行比较。您知道您需要能够交换两个节点。你应该有这些事情的方法。仔细考虑每种分解方法中需要发生的事情。

对于这类问题,我总是推荐一种物理方法来感受它们:尝试使用一组笔记卡或便利贴来做这件事。在每一个上,写一个对象名称和 Node 对象的字段。用铅笔写出字段值。在一张纸上记下其他字段(例如对第一个元素的引用)。然后逐步检查你的算法,看看每次更新需要改变什么。(注意:因为这是一个双向链表,所以您的更改应该在洗牌后仍然存在。试试看)

祝任务顺利!

于 2013-03-24T00:18:38.043 回答