【问题标题】:Iterating over a subset of a set迭代集合的子集
【发布时间】:2013-06-18 22:56:06
【问题描述】:

我有一个集合 oneHundredInactiveSynapses,我想操纵该集合中 100 个非活动突触中的随机 21 个,然后停止。我觉得应该有一个简单的方法来做到这一点,但我现在想不出任何东西。

for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
    // I want to call a method on the inactiveSynapse like
        inactiveSynapse.setActiveState(true);
        // but I only want to do this to 21 of the synapses. How can I do this?
}

其他要点:

  1. 不能将 oneHundredInactiveSynapses 放入数组中
  2. 我不在乎哪个 21 活跃

【问题讨论】:

  • 你的意思是随机的,还是说你不在乎哪 21 个?
  • 我不在乎哪个 21。
  • @LouisWasserman 两个截然不同的东西......
  • 只抓取前 21 个元素。使用您的 for 循环和一个最多计数为 21 的计数器。
  • 出于兴趣,为什么不能为您的集合创建一个浅数组/列表副本?它不会占用太多内存。

标签: java for-loop iteration


【解决方案1】:

您可以复制Set,随机播放并获取前21个元素的子列表-

List<Synapse> copy = new ArrayList<Synapse>(original);
Collections.shuffle(copy);
List<Synapse> sub = copy.subList(0, 21);
for(Synapse s : sub) { ... }

【讨论】:

  • 恕我直言,一百个不算大。我曾考虑过,但 OP 明确提到了 100 和 21 中的 100。
【解决方案2】:

为了让它有点随机,你可以随机选择要开火的火,直到你达到 21最后是突触。

    int chosen = 0;
    int left = oneHundredInactiveSynapses.size();
    java.util.Random rand = new java.util.Random();
    for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
        if(left-chosen>21) inactiveSynapse.setActiveState(true);
        else{
          if(rand.nextBoolean()){
            inactiveSynapse.setActiveState(true);
            chosen++;
            if(chosen==21) break;
          }
        }
        left--;
   }

但是,如果您真的不关心随机性,那么只需使用计数选择前 21 个,即

   int count = 0;
   for(Synapse inactiveSynapse : oneHundredInactiveSynapses){
     if(count==21) break;
     inactiveSynapse.setActiveState(true);
     count++;

   }

【讨论】:

    【解决方案3】:

    Set 转换为数组,然后访问数组的21 个随机元素。你的问题是这个集合只有 100 个元素,所以应该不会太贵。如果您无法选择具体的 Set 实现或更改填充集合的代码,那么沿着这些思路的东西是唯一的选择。

    如果您可以更改填充集合的代码,您当然可以在添加 21 个元素后让它停止。如果您可以注入自己的 Set 实现,您可以拥有一个提供随机排序的实现,并且只迭代前 21 个元素。

    【讨论】:

    • 这在处理大量数据时会产生不利影响; Set 可以而且通常效率更高。也就是说,作为概念验证,这是一个足够好的解决方案。
    • 另外,将其制成数组不是一种选择。
    • @628496 也许你应该把它编辑到你的 Q 中;这是一个很好的备用练习。
    【解决方案4】:

    如果你对前 21 个没问题,你可以这样做:

    int count = 0
    for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
        if(count < 21){
            inactiveSynapse.setActiveState(true);  
            count++;        
        }else{
             break; 
        }
    
    }
    

    如果你想要随机,你可以这样做:

    java.util.Random rand = new java.util.Random();
        int count = 0
        for (Synapse inactiveSynapse : oneHundredInactiveSynapses) {
            if(rand.nextInt(100) % 2){
                next;
            }
            if(count < 21){
                inactiveSynapse.setActiveState(true); 
                 count++;         
            }else{
               break; 
            }
    

    如果随机数是偶数,这将转到下一个元素,直到您到达 21,这将中断。 }

    【讨论】:

    • 你应该只使用 rand.nextBoolean 而不是创建一个 int 并检查它是否是偶数。
    • 我想这是另一种方式。无论如何,它将具有相同的运行时间。
    • 如果随机生成器生成 100 个奇数,它不会激活任何突触!有更好的方法来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2017-03-10
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多