繁体   English   中英

如何找到序列中缺少的元素?

[英]How to find the missing elements in a sequence?

我下面有一个字符串arraylist,我需要传递[[“ AA00001”,“ AA00005”,“ AA00003” -----“ ZZ00678”]中的22184个元素,并且我需要生成列表中不存在的序列元素。 我已经为此编写了代码,并且用更少的输入即可生成所需的输出。 但是当我添加22184个元素并想生成200个唯一ID不在arraylist中时,我得到了如下错误

方法main(String [])的代码超出了65535个字节的限制

有人可以帮忙吗?

    import java.util.ArrayList;

public class GenerateIds
{
    private static ArrayList<String> ids = new ArrayList<>();
    static int n=50;  //no of Ids u want to generate
    static int completed =0;
    static char ID[] = new char[7];
    public static void main(String[] args)
    {
        ids.add("AA00001");
        ids.add("AA00004");
        ids.add("AA00007");
        generateIds(0);
        for(String id : ids)
        {
            System.out.println(id);
        }
    }


    private static void generateIds(int i)
    {
        if(n!=completed)
        {
            if(i<2)
            {
                for(char c ='A';c<'Z';c++)
                {
                    ID[i]=c;
                    generateIds(i+1);
                }
            }
            else if(i>=2 && i<7)
            {
                for(char c ='0';c<='9';c++)
                {
                    ID[i]=c;
                    generateIds(i+1);
                }
            }else if(i==7)
            {
                String id = String.valueOf(ID);
                if(!ids.contains(id))
                {
                    ids.add(id);
                    completed++;
                }
            }
        }
    }
}

您可以将ID放在文本文件中。 然后使用类似的东西。

List<String> ids = Files.readAllLines(Paths.get("ids.txt"));

在Java中,方法的长度不能超过65535个字节。

主要方法变得太大,因为您正在执行所有内联添加:

ids.add("AA00001");
ids.add("AA00004");
ids.add("AA00007");
...

这将使主要方法过长。 解决此问题(并找到丢失的元素)的方法是将所有String值放入列表中,并在其上循环查找丢失的元素:

public void findMissingElements() {

    List<String> missingIds = allPossibleIds.stream()
                                            .filter(isMissingIn(existingIds))
                                            .collect(toList());

    //do something with the missingIds...

}

正如其他读者(例如matt)所建议的那样,您可以例如将所有Strings放在文件中并读取该文件。

我写了一个小例子来说明它们如何一起工作。 我用jOOλ重写了generateIds方法以生成所有可能的id,并将其重命名为allPossibleIds (但是您的递归方法也可以工作)。 我将ID限制为3位数字,以限制搜索时间为例。

  public class FindMissingIdsTest {

  private List<String> allPossibleIds;
  private List<String> existingIds;

  @Before
  public void setup() throws IOException {
    allPossibleIds = allPossibleIds();
    existingIds    = retrieveIdsFromSubSystem();
  }

  @Test
  public void findMissingElements() {

    List<String> missingIds = allPossibleIds.stream()
                                            .filter(isMissingIn(existingIds))
                                            .collect(toList());

  }

  private Predicate<String> isMissingIn(List<String> existingIds) {
    return possibleId -> !existingIds.contains(possibleId);
  }

  public List<String> allPossibleIds(){
    List<String> alphabet = Seq.rangeClosed('A', 'Z').map(Object::toString).toList();
    List<String> letterCombinations = Seq.seq(alphabet).crossJoin(Seq.seq(alphabet)).map(t -> t.v1 + t.v2).toList();
    List<String> numbericParts = IntStream.range(0, 1000)
                                          .mapToObj(i -> String.format("%03d", i))
                                          .collect(toList());

    return Seq.seq(letterCombinations).crossJoin(Seq.seq(numbericParts)).map(t -> t.v1 + t.v2).toList();
  }

  public List<String> retrieveIdsFromSubSystem() throws IOException {
    return Files.readAllLines(Paths.get("ids.txt"));
  }

}

要再次更改为5位,您可以将1000更改为100000,将%03d更改为%05d。

如果可以订购列表,则可能会找到更快更好的算法。 一切都取决于情况。 例如,如果您有一个有序列表,则可以构建所有id的流,对其进行迭代,然后使用指针跟随现有列表,而不是始终执行消耗资源的contains()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM