Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何根据祖先的共同程度对全名列表进行排序?_Algorithm - Fatal编程技术网

Algorithm 如何根据祖先的共同程度对全名列表进行排序?

Algorithm 如何根据祖先的共同程度对全名列表进行排序?,algorithm,Algorithm,如果下面的每个字母都代表一个名称。根据祖先的共同程度对它们进行分类的最佳方法是什么 A B C D E F G H I J K L M N C D O P C D Q R C D S T G H U V G H W J K L X J K L 结果应该是: I J K L # Three names is more important that two names W J K L X J K L A B C D # C D is repeated more than G H M N C D O

如果下面的每个字母都代表一个名称。根据祖先的共同程度对它们进行分类的最佳方法是什么

A B C D
E F G H
I J K L
M N C D
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L
结果应该是:

I J K L # Three names is more important that two names
W J K L
X J K L
A B C D # C D is repeated more than G H
M N C D
O P C D
Q R C D
E F G H
S T G H
U V G H
A B C D M
M N C D M
I J K L M
E F G H M
W J K L
X J K L
O P C D
Q R C D
S T G H
U V G H
编辑:

名称中可能包含空格()

考虑以下示例,其中每个字母代表一个单词:

A B C D M
E F G H M
I J K L M
M N C D M
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L
输出应为:

I J K L # Three names is more important that two names
W J K L
X J K L
A B C D # C D is repeated more than G H
M N C D
O P C D
Q R C D
E F G H
S T G H
U V G H
A B C D M
M N C D M
I J K L M
E F G H M
W J K L
X J K L
O P C D
Q R C D
S T G H
U V G H

首先计算每个链的出现次数。然后根据计数对每个名字进行排序。试试这个:

from collections import defaultdict

words = """A B C D
E F G H
I J K L
M N C D
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L"""

words = words.split('\n')

# Count ancestors
counters = defaultdict(lambda: defaultdict(lambda: 0))
for word in words:
    parts = word.split()
    while parts:
        counters[len(parts)][tuple(parts)] += 1
        parts.pop(0)

# Calculate tuple of ranks, used for sorting
ranks = {}
for word in words:
    rank = []
    parts = word.split()
    while parts:
        rank.append(counters[len(parts)][tuple(parts)])
        parts.pop(0)
    ranks[word] = tuple(rank)

# Sort by ancestor count, longest chain comes first
words.sort(key=lambda word: ranks[word], reverse=True)
print(words)

以下是如何在Java中实现这一点-基本上与@fafl的解决方案相同:

static List<Name> sortNames(String[] input)
{
  List<Name> names = new ArrayList<>();
  for (String name : input)
    names.add(new Name(name));

  Map<String, Integer> partCount = new HashMap<>();
  for (Name name : names)
    for (String part : name.parts)
      partCount.merge(part, 1, Integer::sum);

  for (Name name : names)
    for (String part : name.parts)
      name.counts.add(partCount.get(part));

  Collections.sort(names, new Comparator<Name>()
  {
    public int compare(Name n1, Name n2)
    {
      for (int c, i = 0; i < n1.parts.size(); i++)
        if ((c = Integer.compare(n2.counts.get(i), n1.counts.get(i))) != 0)
          return c;
      return 0;
    }
  });
  return names;
}

static class Name
{
  List<String> parts = new ArrayList<>();
  List<Integer> counts = new ArrayList<>();

  Name(String name)
  {
    List<String> s = Arrays.asList(name.split("\\s+"));
    for (int i = 0; i < s.size(); i++)
      parts.add(String.join(" ", s.subList(i, s.size())));
  }
}
输出:

I J K L
W J K L
X J K L
A B C D
M N C D
O P C D
Q R C D
E F G H
S T G H
U V G H

如果我们希望元素在元组计数相等时按字典顺序排列,该怎么办?目前,如果您对输入中的3个“jkl”元素重新排序,使它们不再按字典顺序排列,那么它们将按相同的顺序输出。我假设它们应该按名字排序,但我承认OP没有说明这一点。我更喜欢排序函数只在必要时更改元素顺序,在相同的秩上,输入顺序应该是相同的preserved@SirRaffleBuffle单个名称中可能有空格。不强制按字母顺序排序。感谢您的澄清@fafl你是对的。我已经更新了Java解决方案,以便在出现平局时保持输入顺序。