当输入相同时,输出顺序会改变,为什么?

时间:2021-04-21 03:12:29

I'm trying to solve this problem: https://kth.kattis.com/problems/genealogical and the only testcase there for me works perfect. But if I instead write the third birth line on the first line and the first birth line on the third line, it prints this: http://puu.sh/kJdBU/dcd693e466.png which is in the wrong order. Do anyone know why and how I can fix this if this is my code?

我正在尝试解决这个问题:https://kth.kattis.com/problems/genealogical,对我来说唯一的测试用例非常完美。但是,如果我改为在第一行写第三个生育线,在第三行写第一个生育线,则打印出来:http://puu.sh/kJdBU/dcd693e466.png,顺序错误。如果这是我的代码,有谁知道我为什么以及如何解决这个问题?

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Genealogical {

private static List<Person> persons = new ArrayList<Person>();

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    while (true) {
        String firstLine = input.nextLine();
        String[] splitted = firstLine.split(" : ");
        if (splitted.length == 0) {
            System.exit(0);
        }

        if (firstLine.contains("BIRTH") && splitted.length >= 2) {
            String childName = splitted[0].substring(6);
            if (splitted.length == 4) {
                birth(childName, splitted[1], splitted[2], splitted[3]);
            }

        }

        else if (firstLine.contains("DEATH")) {
            if (!firstLine.contains(" : ")) {
                if (persons.size() > 0)
                    persons.get(persons.size() - 1).kill(
                            firstLine.substring(6));
            } else {
                String name = splitted[0].substring(6);
                getPerson(name).kill(splitted[1]);
            }
        }

        else if (firstLine.contains("ANCESTORS")) {
            String name = splitted[0].substring(10);

            Person ancestor = getPerson(name);
            for (Person p : persons) {
                if (p.getName().equals(name) || p.used) {
                    continue;
                }

                else {
                    p.used = true;
                    ancestor.addAncestors(p);
                }
            }
        }

        else if (firstLine.contains("DESCENDANTS")) {

            String name = splitted[0].substring(12);

            Person descendant = getPerson(name);
            for (Person p : persons) {
                if (p.getName().equals(name) || p.used) {
                    continue;
                }

                else {
                    p.used = true;
                    descendant.addDescendants(p);
                }
            }
        }

        else if (firstLine.contains("QUIT")) {
            if (persons.size() > 0) {
                for (int i = persons.size() - 1; i >= 0; i--) {
                    Person p = persons.get(i);

                    if (p.getAncestors().size() > 0) {
                        printAncestor(p);

                    }

                    if (p.getDescendants().size() > 0) {
                        printDescendant(p);
                    }

                }
            }

            System.exit(0);

        }
    }

}

public static void printAncestor(Person p) {
    System.out.println("ANCESTORS of " + p.getName());
    for (Person ancestor : p.getAncestors()) {
        System.out.println("  " + ancestor.getName() + " "
                + ancestor.getDate() + " -" + ancestor.getDeathdate());
        System.out.println("    " + ancestor.getDad().getName());
        System.out.println("    " + ancestor.getMom().getName());
    }

    System.out.println();
}

public static void printDescendant(Person p) {
    System.out.println("DESCENDANTS of " + p.getName());
    for (Person descendant : p.getDescendants()) {
        System.out.println("  " + descendant.getName() + " "
                + descendant.getDate() + " -" + descendant.getDeathdate());

    }

}

private static void birth(String child, String date, String mother,
        String father) {

    Person mom = getPerson(mother);
    if (mom == null) {
        mom = new Person(null, null);
        mom.setName(mother);
    }
    Person dad = getPerson(father);
    if (dad == null) {
        dad = new Person(null, null);
        dad.setName(father);
    }

    Person childd = new Person(mom, dad);
    childd.setName(child);
    childd.setDate(date);

    persons.add(childd);

}

private static Person getPerson(String person) {
    for (Person p : persons) {
        if (p.getName().equals(person)) {
            return p;
        }

    }

    return null;
}

}

And this is my person class:

这是我的人类:

import java.util.ArrayList;
import java.util.List;


public class Person {

private String name;
private String date;
private List<Person> children = new ArrayList<Person>();
private Person mom;
public boolean used = false;

private String deathDate = null;
private List<Person> ancestors = new ArrayList<Person>();
private List<Person> descendants = new ArrayList<Person>();


public Person getMom() {
    return mom;
}

private Person dad;
public Person getDad() {
    return dad;
}


public List<Person> getDescendants() {
    return descendants;
}

public List<Person> getAncestors() {
    return ancestors;
}

public Person(Person mom, Person dad)
{
    this.mom = mom;
    this.dad = dad;
}

public Person(String peo)
{
    name = peo;
}

public void setName(String name)
{
    this.name = name;
}

public String getName()
{
    return this.name;
}

public void setDate(String date)
{
    this.date = date;
}

public String getDate()
{
    return this.date;
}

public void addChild(Person child)
{
    children.add(child);
}

public void kill(String date)
{
    this.deathDate = date;
}

public void addAncestors(Person p)
{
    ancestors.add(p);
}

public void addDescendants(Person p)
{
    descendants.add(p);
}

public String getDeathdate()
{
    if(this.deathDate == null)
        return "";
    else
        return " " + this.deathDate;
}


}

1 个解决方案

#1


0  

To keep the order of the commands you need to save them somewhere.

要保持命令的顺序,需要将它们保存在某处。

For example you could create a class, since you already parse it:

例如,您可以创建一个类,因为您已经解析了它:

public class OutputQuery
{
    public final String command;
    public final String name;

    // Add other fields..

    public OutputQuery(String command, String name)
    {
        this.command = command;
        this.name = name;
    }
}

And in your main class you add a List and add them to it:

在您的主类中,您添加一个List并将其添加到它:

private static List<OutputQuery>    queries = new LinkedList<>();

// ...

else if (firstLine.contains("ANCESTORS"))
{
    String name = splitted[0].substring(10);

    queries.add(new OutputQuery("ANCESTORS", name));

    //...

else if (firstLine.contains("DESCENDANTS"))
{
    String name = splitted[0].substring(12);

    queries.add(new OutputQuery("DESCENDANTS", name));

    //...

else if (firstLine.contains("QUIT"))
{
    for (OutputQuery query : queries)
    {
        if (query.command == "ANCESTORS")
        {
            // Print output
        } else if (query.command == "DESCENDANTS")
        {
            // Print output
        }
    }

//...

You don't need to iterate over all persons, just the queries, as you can see in the code above, the loop over the queries is NOT in another loop, here the complete else if block:

您不需要遍历所有人,只需查询,正如您在上面的代码中看到的那样,查询循环不在另一个循环中,这里是完整的if if块:

else if (firstLine.contains("QUIT"))
{
    for (OutputQuery query : queries)
    {
        Person p = getPerson(query.name);

        if (query.command == "ANCESTORS")
        {
            printAncestor(p);
        } else if (query.command == "DESCENDANTS")
        {
            printDescendant(p);
        }
    }

    System.exit(0);
}

#1


0  

To keep the order of the commands you need to save them somewhere.

要保持命令的顺序,需要将它们保存在某处。

For example you could create a class, since you already parse it:

例如,您可以创建一个类,因为您已经解析了它:

public class OutputQuery
{
    public final String command;
    public final String name;

    // Add other fields..

    public OutputQuery(String command, String name)
    {
        this.command = command;
        this.name = name;
    }
}

And in your main class you add a List and add them to it:

在您的主类中,您添加一个List并将其添加到它:

private static List<OutputQuery>    queries = new LinkedList<>();

// ...

else if (firstLine.contains("ANCESTORS"))
{
    String name = splitted[0].substring(10);

    queries.add(new OutputQuery("ANCESTORS", name));

    //...

else if (firstLine.contains("DESCENDANTS"))
{
    String name = splitted[0].substring(12);

    queries.add(new OutputQuery("DESCENDANTS", name));

    //...

else if (firstLine.contains("QUIT"))
{
    for (OutputQuery query : queries)
    {
        if (query.command == "ANCESTORS")
        {
            // Print output
        } else if (query.command == "DESCENDANTS")
        {
            // Print output
        }
    }

//...

You don't need to iterate over all persons, just the queries, as you can see in the code above, the loop over the queries is NOT in another loop, here the complete else if block:

您不需要遍历所有人,只需查询,正如您在上面的代码中看到的那样,查询循环不在另一个循环中,这里是完整的if if块:

else if (firstLine.contains("QUIT"))
{
    for (OutputQuery query : queries)
    {
        Person p = getPerson(query.name);

        if (query.command == "ANCESTORS")
        {
            printAncestor(p);
        } else if (query.command == "DESCENDANTS")
        {
            printDescendant(p);
        }
    }

    System.exit(0);
}