需要一种算法来根据人名对一个人的几个参数进行分组

时间:2010-05-09 05:50:42

标签: algorithm language-agnostic

我有一堆按字母顺序排列的名字,同名的多个实例都按字母顺序排列,这样名字就全部组合在一起了。在每个名字旁边,在昏迷之后,我有一个已分配给他们的角色,每行一个名称 - 角色对,如下所示:

NAME1,基于role1
NAME1,role2所
NAME1,role3
NAME1,role8
NAME2,role8
NAME2,role2所
NAME2,role4
NAME3,role1上
NAME4,role5
NAME4,role1上
...
..
点。

我正在寻找一种算法,将上述.csv文件作为输入,以下列格式创建输出.csv文件

NAME1,基于role1,基于role2,role3,role8
NAME2,role8,基于role2,role4
NAME3,role1上
NAME4,role5,role1上
...
..
点。

所以基本上我希望每个名称只出现一次,然后在输入文件中所有名称和角色的名称旁边以csv格式打印角色。

算法应该与语言无关。如果它不使用OOP原则,我将不胜感激:-)我是新手。

5 个答案:

答案 0 :(得分:4)

显然有一些格式错误,但这会让你开始。

var lastName = "";

do{
  var name = readName();
  var role = readRole();
  if(lastName!=name){
    print("\n"+name+",");
    lastName = name;
  }
  print(role+",");
}while(reader.isReady());

答案 1 :(得分:0)

如果您的语言具有关联数组,则很容易做到这一点:可以通过任何东西(例如字符串)而不仅仅是数字索引的数组。有些语言称它们为“哈希”,“地图”或“字典”。

另一方面,如果您可以保证名称在样本数据中组合在一起,那么Stefan的解决方案效果非常好。

答案 2 :(得分:0)

很可惜,你说它必须与语言无关,因为Python非常合格:

import itertools
def split(s):
  return s.strip().split(',', 1)
with open(filename, 'r') as f:
  for name, lines in itertools.groupby(f, lambda s: split(s)[0])
    print name + ',' + ','.join(split(s)[1] for s in lines)

基本上groupby调用会使所有连续的行具有相同的名称并将它们组合在一起。

现在我想起来了,Stefan的答案可能更有效率。

答案 3 :(得分:0)

以下是Java中的解决方案:

Scanner sc = new Scanner (new File(fileName));
Map<String, List<String>> nameRoles = new HashMap<String, List<String>> ();
while (sc.hasNextLine()) {
  String line = sc.nextLine();
  String args[] = line.split (",");
  if (nameRoles.containsKey(args[0]) {
    nameRoles.get(args[0]).add(args[1]);
  } else {
    List<String> roles = new ArrayList<String>();
    roles.add(args[1]);
    nameRoles.put(args[0], roles);
  }
}

// then print it out
for (String name : nameRoles.keySet()) {
   List<String> roles = nameRoles.get(name);
   System.out.print(name + ",");
   for (String role : roles) {
     System.out.print(role + ",");
   }
   System.out.println();
}

使用这种方法,您可以使用以下随机输入:

NAME1,基于role1

NAME3,基于role1

NAME2,role8

NAME1,role2所

NAME2,role2所

NAME4,role5

NAME4,基于role1

答案 4 :(得分:0)

这里是C#中没有任何花哨的东西。它应该是不言自明的:

static void Main(string[] args) 
{
    using (StreamReader file = new StreamReader("input.txt"))
    {
        string prevName = "";
        while (!file.EndOfStream)
        {
            string line = file.ReadLine(); // read a line

            string[] tokens = line.Split(','); // split the name and the parameter

            string name = tokens[0]; // this is the name
            string param = tokens[1]; // this is the parameter

            if (name == prevName) // if the name is the same as the previous name we read, we add the current param to that name. This works right because the names are sorted.
            {
                Console.Write(param + " ");
            }
            else // otherwise, we are definitely done with the previous name, and have printed all of its parameters (due to the sorting).
            {
                if (prevName != "") // make sure we don't print an extra newline the first time around
                {
                    Console.WriteLine();
                }
                Console.Write(name + ": " + param + " "); // write the name followed by the first parameter. The output format can easily be tweaked to print commas.
                prevName = name; // store the new name as the previous name.
            }
        }
    }
}