生成名称排列并进入数据库

时间:2016-02-10 20:03:02

标签: java mysql algorithm

使用" Generating all permutations of a given string"作为参考,我试图让我的程序(在检测到名称字段时)向数据库写入名称的所有组合(queryID也称为qid不是主键。我打算将它全部重复)。

示例:John Michael Doe

  1. John Michael Doe
  2. John Doe Michael
  3. Michael John Doe
  4. Michael Doe John
  5. Doe John Michael
  6. Doe Michael John
  7. 为了让您更好地了解该场景,当有人使用我的程序进行搜索时,他们可以添加"约束"。

    Initial

    因此,当他们添加约束时,他们有一个下拉菜单,他们可以选择多个类别,其中一个是名称。

    After adding constraint

    所以,如果他们输入:
    Name CONTAINS foo bar为第一个约束。
    Id CONTAINS 1234表示第二个约束。
    Name CONTAINS john doe表示最后一个约束。

    它将创建SQL语句:
    insert into qal.query_input values('df084b1f-1337','1234','','','foo bar john doe','','');
    (空格是未搜索的类别)

    现在我的问题是我希望这个输出(使用相同的搜索):

    insert into qal.query_input values('df084b1f-1337','1234','','','foo bar','','');
    insert into qal.query_input values('df084b1f-1337','1234','','','bar foo','','');
    insert into qal.query_input values('df084b1f-1337','1234','','','john doe','','');
    insert into qal.query_input values('df084b1f-1337','1234','','','doe john','','');

    目前这是我的代码:

    ArrayList<String> fields = constraintToInputLogFieldMap.get(key);
    ArrayList<String> names;
    for (String field : fields) {
        ArrayList<String> values = inputLogFieldValues.get(field);
    
        if (values == null) {
            values = new ArrayList<>();
            inputLogFieldValues.put(field, values);
        }
    
        // only retrieve singletonRange and listRange          
        if (singletonRange != null) {
            values.add((String) singletonRange.getValue());
        }
        if (listRange != null) {
            for (Object v : listRange.getValues()) {
                values.add((String) v);
            }
        }
    }
    // This creates an arrayList for each name
    // ie. [foo bar, john doe]
    names = inputLogFieldValues.get("Name");
    
    for (String field : inputLogFields) {
        ArrayList<String> values = inputLogFieldValues.get(field);
        if (values == null)
            inputEntry += ",''";
        else {
            String valueStr = "";
            for (String value : values)
                valueStr += " " + value;
            inputEntry += ",'" + valueStr.substring(1) + "'";
        }
    }
    inputEntry = "insert into qal.query_input values('" + qid + "'" + inputEntry + ");";
    logger.info("Stackoverflow SQL output: " + inputEntry);
    dbUpdate(inputEntry);
    

    现在我的问题是当arraylist的输入未知时如何执行此操作的算法? (约束的数量和名称的长度,即。firstname middlename lastname secondlastname)

    如果需要澄清或者我需要输入更多代码,请告诉我。

    更新2/10/2016 17:36

    我修改了代码的底部,现在它将每个名称分开(而不是合并为一个),同时仍然保留其他字段。

    之前输出:
    insert into qal.query_input values('df084b1f-1337','1234','','','foo bar john doe','','');
    更新输出:
    insert into qal.query_input values('df084b1f-1337','1234','','','foo bar','','');
    insert into qal.query_input values('df084b1f-1337','1234','','','john doe','','');

    更新代码(这么简单的改动):

    ArrayList<String> inputEntries = new ArrayList<>();
    for (String name : names) {
        inputEntry = "";
        for (String field : inputLogFields) {
            ArrayList<String> values = inputLogFieldValues.get(field);
            if (values == null)
                inputEntry += ",''";
            else {
                if (field.equals("Name")) {
                    inputEntry += ",'" + name + "'";
                } else {
                    String valueStr = "";
                    for (String value : values)
                        valueStr += " " + value;
                    inputEntry += ",'" + valueStr.substring(1) + "'";
                }
            }
        }
        inputEntry = "insert into qal.query_input values('" + qid + "'" + inputEntry + ");";
        inputEntries.add(inputEntry);
    }
    for (String sqlEntry : inputEntries) {
        dbUpdate(sqlEntry);
    }
    

    现在我唯一要解决的问题是生成名称排列的方法。

1 个答案:

答案 0 :(得分:0)

使用“Generating all possible permutations of a list recursively”作为参考,我添加/更改了这一小部分。

ArrayList<String> inputEntries = new ArrayList<>();
ArrayList<String> permutedNames = names; // <----
for (String name : permutedNames) { // <--- Now permutedNames
    inputEntry = "";
    for (String field : inputLogFields) { ...

并添加了以下功能:

private ArrayList<String> splitNames(ArrayList<String> listOfNames) {
    String temp = "";
    List<String> splitName;
    List<List<String>> listSplitName = new ArrayList<List<String>>();
    ArrayList<String> toReturn = new ArrayList<String>();

    if (listOfNames.size() == 1) {
        temp = listOfNames.get(0);
        splitName =  new ArrayList<String>(Arrays.asList(temp.split(" ")));
        listSplitName = generatePerm(splitName);
        for (int i = 0; i < listSplitName.size(); i++) {
            toReturn.add(listSplitName.get(i).toString());
        }
        return toReturn;
    }
    else {
        for (int i = 0; i < listOfNames.size(); i++) {
            temp = listOfNames.get(i);
            splitName = new ArrayList<String>(Arrays.asList(temp.split(" ")));
            listSplitName = generatePerm(splitName);
            for (int j = 0; j < listSplitName.size(); j++) {
                toReturn.add(listSplitName.get(j).toString());
            }
        }
        return toReturn;
    }
}

private List<List<String>> generatePerm(List<String> original) {
    if (original.size() == 0) {
        List<List<String>> result = new ArrayList<List<String>>();
        result.add(new ArrayList<String>());
        return result;
    }
    String firstElement = original.remove(0);
    List<List<String>> returnValue = new ArrayList<List<String>>();
    List<List<String>> permutations = generatePerm(original);
    for (List<String> smallerPermutated : permutations) {
        for (int index=0; index <= smallerPermutated.size(); index++) {
            List<String> temp = new ArrayList<String>(smallerPermutated);
            temp.add(index, firstElement);
            returnValue.add(temp);
        }
    }
    return returnValue;
}

splitNames函数获取一个名称列表,并将每个名称分成一个只包含名称的单独数组。

例如:
输入 - [John Doe, Foo Bar Bat] 输出 - [John, Doe]发送至generatePerm[Foo, Bar, Bat]发送至generatePerm

然后generatePerm会置换每一个并发回一个组合列表。

然后将其发送回splitNames,它会将排列编译成ArrayList并将其返回。