【问题标题】:Dynamic naming of variable (E1, E2, E3 ...)变量的动态命名(E1、E2、E3 ...)
【发布时间】:2021-12-27 05:11:09
【问题描述】:

我想知道是否有一种方法或库可以用来执行以下操作:

我有一个对象数组列表,其中每个 obj 都有一个名称。

列表必须始终是唯一的,最多包含 5 个元素,例如 [E1,E2,E3]

例如,如果列表具有初始形式 [E3,E5] 并且我添加了一个对象,它的名称应该是 E1 并且列表将是 [E1,E3,E5][E3,E5,E1] 没关系,只要名称是唯一的并且该项目从 1 到 5 添加到列表中。

如果添加另一个项目,它应该是[E3,E5,E1,E2],始终是唯一的名称,并且介于 1 和 5 之间

这些都是我失败的尝试,

StartNode node = new StartNode();
node.setName("E1");

for (int i = 0; i < circuit.getNbStartNodes(); i++) {
    for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
        String test = ((StartNode) circuit.getStartNode(j)).getName();
        if (("E"+j).equalsIgnoreCase(test) && ("E"+j).equalsIgnoreCase(node.getName()) ) {
            break;
        }
        else
            node.setName("E" + j);
    }
}

/*while (t <= circuit.getNbStartNodes()) {
      for (int j = 0; j < circuit.getNbStartNodes(); j++) {
          String test = ((StartNode) circuit.getStartNode(j)).getName();
          if (("E" + t).equalsIgnoreCase(test) || ("E" + t).equalsIgnoreCase(node.getName()))
              break;
          else {
              node.setName("E" + t);
          }
      }
      t++;
  }
*/

/*  for (int i = 1; i <= circuit.getNbStartNodes(); i++) {
        for (int j = 0; j < circuit.getNbStartNodes(); j++) {
            String test = ((StartNode) circuit.getStartNode(j)).getName();
            if (!("E" + i).equalsIgnoreCase(test)) {
                node.setName("E" + i);
                t=0;
                break;
            }
        }
        if (t==0)
            break;
        else
            continue;
*/
//String test = ((StartNode) circuit.getStartNode(i)).getName();
//for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
//    if (!("E" + j).equalsIgnoreCase(test))
//       node.setName("E" + j);
//}

我的代码做错了什么?

【问题讨论】:

  • 我想知道,如果您的初始列表包含E3E5,那么添加哪个 元素是否重要?它必须是E1,还是E1E2E4 中的任何一个都可以?

标签: java oop arraylist


【解决方案1】:
  • 创建一个小的布尔数组来跟踪哪些名称已被使用并相应地填充它
  • 找到第一个未使用的元素并将其用作 id。
boolean[] used = new boolean[circuit.getNbStartNodes()];

for (int i = 0; i < used.length; i++) {
    int index = Integer.parseInt(((StartNode) circuit.getStartNode(j)).getName().substring(1)) - 1; // should be   in range 0..4
    used[index] = true;
}

String name = "E";
for (int i = 0; i < used.length; i++) {
    if (!used[i]) {
        name += String.valueOf(i + 1); // starting from 1
        break;
    }
}
System.out.println("free name: " + name);
StartNode node = new StartNode();
node.setName(name);

// add new node to circuit, etc.

【讨论】:

  • 如果例如 all used 全部为真,第二个循环不会被执行,你认为我可以启动一个布尔数组,其中包含我已经存在的节点,这些节点将变为真,其余的将被保留为假,这样第二个循环就会被执行?我也认为第一个循环缺少for (int j = 0; j &lt; circuit.getNbStartNodes(); j++) {
  • used 的思想是跟踪使用了哪些节点,默认情况下这个数组的所有元素都是false。如果在第一个循环之后没有剩余空间,那么第二个循环仍然会运行。 used 的大小与circuit.getNbStartNodes() 相同,所以在第一个循环中应该使用哪个值并不重要(如果有相等的used.length,则无需调用方法)。
【解决方案2】:

对于较小的值,Alex 的解决方案可以正常工作。

但是,如果您遇到元素数量可能很大的用例,那么您可以使用TreeSet 来跟踪未使用的数字。此外,nextCeilValue 是在没有删除号码时要选择的下一个号码。

在下面的代码中,我创建了一个UniqueNumber 类,它能够get 下一个数字,或remove 给定数字。请注意,此代码提供从 0 开始的整数。当然,您可以使用函数 i -&gt; "E" + (i + 1) 轻松将其转换为 E 编号。

public class UniqueNumber {

    private int nextCeilValue;

    private final TreeSet<Integer> removedNumbers = new TreeSet<>(Integer::compare);

    public int get() {
        if (removedNumbers.isEmpty()) {
            return nextCeilValue++;
        }
        else {
            int number = removedNumbers.first();
            removedNumbers.remove(number);
            return number;
        }
    }

    public boolean remove(int number) {
        if (number < 0 || number > nextCeilValue) {
            return false;
        }

        if (number == nextCeilValue) {
            nextCeilValue--;
        }
        else {
            removedNumbers.add(number);
        }
        return true;
    }

    public int size() {
        return nextCeilValue - removedNumbers.size();
    }
}

为了对此进行测试,我们首先需要模拟您的初始情况。在我们从零开始的整数世界中,我们需要数字 2 和 4(代表 E3 和 E5)。在下面的代码中,我们需要调用 get 5 次,然后删除元素 0、1 和 3。当然,我们可以创建一个 UniqueNumber(int... initialValues) 构造函数来执行此操作。

UniqueNumber un = new UniqueNumber();
for (int i = 0; i < 5; i++) {
    un.get();
}
un.remove(0); // Remove E1
un.remove(1); // Remove E2
un.remove(3); // Remove E4

为了得到下一个值,只需使用这个:

StartNode node = new StartNode();
node.setName("E" + (un.get() + 1));

【讨论】:

  • 谢谢先生,我会用这个做我的门,因为我最多有 50 个门。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 2012-12-22
  • 2020-01-03
  • 2021-05-26
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多