简体   繁体   English

java-根据分配的整数值对字符串的链表进行排序

[英]java- sort linked list of strings based on their assigned integer values

I have a linked list of strings, each of those strings has an integer value from calculation. 我有一个字符串链接列表,这些字符串中的每个字符串都有一个计算得出的整数值。 To explain things easier, I have a linked list of strings representing nodes. 为了简化说明,我有一个表示节点的字符串链接列表。 Each node has a distance. 每个节点都有一个距离。 To get the distance, you use a method I created in my program to return that node's distance. 要获取距离,请使用我在程序中创建的方法来返回该节点的距离。 I want that linked list to be sorted by each of the string's distance, from lowest to highest. 我希望按每个字符串的距离(从最低到最高)对链接列表进行排序。 How would I do that? 我该怎么做? Here is a psedocode 这是一个psedocode

Queue<String> someStringList = new LinkedList<String>();

... ...

for each of the nodes in the list

String node = ((LinkedList<String>) someStringList).get(i);
distance = theNodesDistance(node);
sort the linked list by the node's distance
...

public int theNodesDistance(String str){
return distance;

} }

The first option is to create a comparator and then sort the collection. 第一种选择是创建一个比较器,然后对集合进行排序。 I would do something like: 我会做类似的事情:

  public static void main(String... arg) {
        LinkedList<String> someStringList = new LinkedList<>();

        someStringList.add("2");
        someStringList.add("1");

        System.out.println(someStringList);

        Collections.sort(someStringList, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return theNodesDistance(s1).compareTo(theNodesDistance(s2));
            }

        });
        System.out.println(someStringList);

    }
    public static Integer theNodesDistance(String str){
        return Integer.parseInt(str); // here return the distance
    }

Another option is to create a class Node with an id and distance: 另一个选择是创建一个具有ID和距离的类Node:

public class Node implements Comparable<Node> {

    String id;
    Integer distance;

    public Node(String id) {
        this.id = id;
        this.distance = theNodesDistance(id);
    }

    @Override
    public int compareTo(Node node) {
        return this.distance.compareTo(node.distance);
    }

    public String toString() {
        return id;
    }

    public Integer theNodesDistance(String str){
        return Integer.parseInt(str);
    }
}

Then, sort your list doing: 然后,对列表进行排序:

LinkedList<Node> nodes = new LinkedList<>();

nodes.add(new Node("2"));
nodes.add(new Node("1"));

System.out.println(nodes);

Collections.sort(nodes);
System.out.println(nodes);

Finally, you can use a PriorityQueue which organizes the elements whenever you insert a new node. 最后,您可以使用PriorityQueue在插入新节点时组织元素。 I mean, you can remove each node in order. 我的意思是,您可以按顺序删除每个节点。

Queue<Node> nodes = new PriorityQueue<>();
nodes.add(new Node("10"));
nodes.add(new Node("3"));
nodes.add(new Node("2"));
nodes.add(new Node("1"));
nodes.add(new Node("4"));

System.out.println(nodes.remove());
System.out.println(nodes.remove());
System.out.println(nodes.remove());
System.out.println(nodes.remove());
System.out.println(nodes.remove());

In this case, the output will be: 在这种情况下,输出将是:

1
2
3
4
10

If you can afford to waste CPU in repeated calculations of the distance, then you could use the JDK sorting methods with a Comparator implementation which would figure the distance from any 2 strings and compare them. 如果您可以浪费CPU来重复计算距离,则可以将JDK排序方法与Comparator实现一起使用,该实现将计算出任意两个字符串之间的距离并进行比较。 This is the simplest. 这是最简单的。

If you would prefer calculating only once the distance for each string (presuming this is costly), then you either: 如果您只希望为每个字符串计算一次距离(假设这是昂贵的),那么您可以:

a) construct a new collection of tuples (string and distance), and sort the tuples by the distance (again with a comparator, or by making the tuple class comparable). a)构造一个新的元组集合(字符串和距离),并按距离对元组进行排序(再次使用比较器,或者使元组类具有可比性)。

b) or you can try to cache the distances in a hashmap of strings-to-distance which the comparator would rely on. b)或者您可以尝试将距离存储在比较器将依赖的字符串到距离的哈希图中。

You can use TreeMap.. Following is a normal demonstration - 您可以使用TreeMap。以下是正常演示-

    TreeMap<Integer, String> tmap = new TreeMap<Integer, String>(); 
/*Adding elements to TreeMap*/
 tmap.put(1, "Data1"); 
tmap.put(23, "Data2"); 
tmap.put(70, "Data3"); 
tmap.put(4, "Data4"); 
tmap.put(2, "Data5"); 
/* Display content using Iterator*/ 
Set set = tmap.entrySet();
 Iterator iterator = set.iterator();
 while(iterator.hasNext()) { 
Map.Entry mentry = (Map.Entry)iterator.next();
 System.out.print("key is: "+ mentry.getKey() + " & Value is: ");
 System.out.println(mentry.getValue()); 
} 

The output :: 输出 ::

key is: 1 & Value is: Data1 
key is: 2 & Value is: Data5 
key is: 4 & Value is: Data4 
key is: 23 & Value is: Data2 
key is: 70 & Value is: Data3

You can use sort algo. 您可以使用排序算法。 like selectionsort, bubblesort... This is insertionsort 像selectionsort,bubbleort ...这是insertssort

double temp;
for(int i = 1;i<yourList.size();i++)
{
temp = thenodedistance(yourlist.get(i));
int j = i;
    while(j>0&&thenodedistance(yourlist.get(j-1))> temp)
    {
        yourlist.add(j,yourlist.remove(j-1);
        j--;
    }
    yourlist.add(j,yourliste.remove(i));
}

this way you can sort your list (did not try the code....) 这样,您可以对列表进行排序(没有尝试代码...。)

What about having a Node class? 拥有Node类呢?

class Node{
   String str;
   int distance;
   public Node(String str){
       this.str = str;
       this.distance = theNodesDistance(str);
   }
}

Then you can override a Comparator. 然后,您可以覆盖比较器。 I suggest you to use a PriorityQueue instead of a LinkedList so your inserts to the ordered list can be more efficient (O(logn)). 我建议您使用PriorityQueue而不是LinkedList,以便对有序列表的插入可以更有效(O(logn))。 In this case you dont really need to call a sort or heapify function since the priority queue always keeps the nodes in order. 在这种情况下,由于优先级队列始终使节点保持顺序,因此您实际上不需要调用sort或heapify函数。

PriorityQueue que = new PriorityQueue(new Comparator<Node>(){
     public int compare(Node n1, Node n2){
          if(n1.distance < n2. distance) return -1;
          else if(n1.distance > n2.distance) return 1;
          return 0;
     }
});

You can add to the que as follows: 您可以按以下步骤添加到队列:

for(each str){
    que.add(new Node(str));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM