首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ArrayList中查找最常见的随机赋值字符串

在ArrayList中查找最常见的随机赋值字符串
EN

Stack Overflow用户
提问于 2019-08-30 21:43:34
回答 2查看 70关注 0票数 0

我正在开发一个模拟器,在模拟器中,Person对象(存储在ArrayList中)“复制”并生产婴儿,他们继承“基因”,表示为4个字母的字符串。在程序开始时,第一批人的基因库是随机生成的。

在计时器的每一个滴答中,我想计算出在所有的人对象中最常见的“基因”是什么。

这四封信是:

  1. G、Z、N、F
  2. A,T,C,G
  3. B、F、Q、N
  4. A、C、T、E

在这种情况下,有256种可能的组合,而且必须有比256条if-else语句更有效的检查。

Person类(减去get/set方法)

代码语言:javascript
复制
public class Person {
    static Random rand = new Random();
    private Person mother;
    private Person father;
    private String genes;
    private char sex;
    private int age, numKids;

    public Person() {
        mother = null;
        father = null;
        genes = createGenes();
        if (rand.nextDouble() <= 0.5)
            sex = 'm';
        else
            sex = 'f';
        age = 18;
        numKids = 0;
    }

    public Person(Person m, Person f) {
        mother = m;
        father = f;
        genes = inheritGenes(m, f);
        if (rand.nextDouble() <= 0.5)
            sex = 'm';
        else
            sex = 'f';
        age = 0;
    }
//create genes for original Persons
    private String createGenes() {
        String genetics = "";

        double first = rand.nextDouble();
        double second = rand.nextDouble();
        double third = rand.nextDouble();
        double fourth = rand.nextDouble();

        if (first <= 0.25)
            genetics += "G";
        else if (first <= 0.68)
            genetics += "Z";
        else if (first <= 0.9)
            genetics += "N";
        else
            genetics += "F";

        if (second <= 0.65)
            genetics += "A";
        else if (second <= 0.79)
            genetics += "T";
        else if (second <= 0.85)
            genetics += "C";
        else
            genetics += "G";

        if (third <= 0.64)
            genetics += "B";
        else if (third <= 0.95)
            genetics += "F";
        else if (third <= 0.98)
            genetics += "Q";
        else
            genetics += "N";

        if (fourth <= 0.37)
            genetics += "A";
        else if (fourth <= 0.58)
            genetics += "C";
        else if (fourth <= 0.63)
            genetics += "T";
        else
            genetics += "E";
        return genetics;

    }
//inherit genes from parents for new Persons
    public String inheritGenes(Person m, Person f) {
        String genetics = "";
        double first = rand.nextDouble();
        double second = rand.nextDouble();
        double third = rand.nextDouble();
        double fourth = rand.nextDouble();

        if (first < 0.5) {
            genetics += m.getGenes().charAt(0);
        } else
            genetics += f.getGenes().charAt(0);

        if (second < 0.5) {
            genetics += m.getGenes().charAt(1);
        } else
            genetics += f.getGenes().charAt(1);

        if (third < 0.5) {
            genetics += m.getGenes().charAt(2);
        } else
            genetics += f.getGenes().charAt(2);

        if (fourth < 0.5) {
            genetics += m.getGenes().charAt(3);
        } else
            genetics += f.getGenes().charAt(3);

        return genetics;
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-08-30 22:17:48

List<Person>中找到最常见基因的示例代码。我刚为genes String添加了一个吸气器

代码语言:javascript
复制
String getGenes() {
    return genes;
}

守则如下:

代码语言:javascript
复制
List<Person> people = new ArrayList<>();

for (int i = 0; i < 100; i++) {
    people.add(new Person()); // 100 random genes
}

String mostCommonGene = people.stream()
                .map(Person::getGenes)
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
                .entrySet()
                .stream()
                .max(Comparator.comparingLong(Map.Entry::getValue))
                .get()
                .getKey();

    System.out.println("Most common gene: " + mostCommonGene);

我们使用Java 8流:

  • 我们得到了stream() of people列表。
  • 我们将每个map() ( Person )转换为String --它们的genes
  • 我们collect()的基因流与groupingBy()喂食Function.identity()Collectors.counting()。此步骤生成一个Map<String, Long>,它表示genes及其频率的映射。有效地统计people列表中基因的出现情况。
  • 然后我们在地图上调用entrySet(),然后再调用stream() --现在我们有了一系列的地图条目(你可以把它们看作对),基因及其在一个物体中的频率。方便)。
  • 我们调用max()查找值最高的条目(解释为频率)。Comparator.comparingLong()告诉max()算法如何比较这些对,但它们不是long_s --这就是为什么我们必须告诉它如何将_entry转换为long --我们得到了该条目的值。
  • 然后我们调用get(),因为max()返回一个Optional<T>。我们只想要T (条目)。
  • 最后,我们在表示一对最频繁的基因及其频率的条目上调用getKey()。正如前面提到的,关键是基因,而值是它的频率。

如果您不熟悉这个答案中描述的大多数概念,我强烈建议您学习Java8Streams。一旦你习惯了,你就停不下来了。

票数 0
EN

Stack Overflow用户

发布于 2019-08-30 22:32:13

根据使用场景的不同,使用额外的Map<String,Long>作为每个基因的计数器(对于每个新的人基因增加计数器)可能更有效。

这种方法将使用更多的内存(包含256个元素的Map<String,Long>),而新的人员构造将稍微慢一些(地图的更新),但是如果有许多存活的Person对象,那么获取每个滴答上最常见的基因可能要快得多,因为这些对象已经在Map中进行了分组和计数,因此应该比较最多256个条目。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57733511

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档