我有一堆按字母顺序排列的名字,同名的多个实例都按字母顺序排列,这样名字就全部组合在一起了。在每个名字旁边,在昏迷之后,我有一个已分配给他们的角色,每行一个名称 - 角色对,如下所示:
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原则,我将不胜感激:-)我是新手。
答案 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)
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.
}
}
}
}