生成逻辑,以可能输出列表中所有字符串组合

时间:2019-02-19 08:03:33

标签: java

您好,如果列表中存在代码,我正在尝试将响应生成为true或false。因此,如果字符串包含“单个括号内”的值,例如:“ ABC(Q,E,1)EEE”,但是字符串包含多个括号,例如:“ B(A,1),则我能够生成响应)AA(E,Z)EE”,我无法从中生成输出。我是编码和构建逻辑的新手,如果有人可以提供帮助,那就太好了。

public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        System.out.println("Enter the code you want to check: ");
        String input = scan.next();

        List<String> codes = new ArrayList<>();
        codes.add("ABC(Q,E,1)EEE");
        codes.add("ABDCE(E,Z,X)E");
        codes.add("B(A,1)AAEEE");
        codes.add("R(1,2,3,4,5)RT(U,M,N,B,V,H)(Q,E,R,F,G,H)(R,Z)");
        codes.add("B(A,1)AA(E,Z)EE");

        for (Iterator<String> i = codes.iterator(); i.hasNext(); ) {
            String code = i.next();

            String prefix = code.substring(0, code.indexOf("("));
            String suffix = code.substring(code.indexOf(")") + 1);
            String middle = code.substring(code.indexOf("(") + 1, code.indexOf(")"));
            String[] var = middle.split(",");

            String[] result = new String[var.length];
            for (int j = 0; j < var.length; j++) {

                result[j] = prefix + var[j] + suffix;

                if (result[j].equals(input)) {
                    System.out.println("True: This code is present");
                }
               }
              }
              } 

输出(有效):

Enter the code you want to check: 
BAAAEEE                
True: The code is present

输出(无效):

Enter the code you want to check: 
BAAAZEE
<gives no output>

让我给您一个正在做的事的示例(“ ABC(Q,E,1)EEE”):它使该字符串的三个可能的输出分别是:“ ABCQEEE”,“ ABCEEEE”,“ ABC1EEE” ”。因此,如果我将输入指定为“ ABCQEEE”,它将在内部生成这些输出,并且如果代码在列表中的任何位置都将其输出为True。

2 个答案:

答案 0 :(得分:0)

尝试一下。 已编辑:添加了代码注释。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Main {

    public static void main(String args[]) {

        Scanner scan = new Scanner(System.in);
        System.out.println("Enter the code you want to check: ");
        String input = scan.next();
        scan.close();

        List<String> codes = new ArrayList<>();
        codes.add("ABC(Q,E,1)EEE");
        codes.add("ABDCE(E,Z,X)E");
        codes.add("B(A,1)AAEEE");
        codes.add("R(1,2,3,4,5)RT(U,M,N,B,V,H)(Q,E,R,F,G,H)(R,Z)");
        codes.add("B(A,1)AA(E,Z)EE");

        for (Iterator<String> i = codes.iterator(); i.hasNext();) {
            String code = i.next();
            List<String> codePossiblity = generatePossibilities(code);
            // check if the input is in the list of all the possibility
            for (String s : codePossiblity) {
                if (s.contains(input)) {
                    System.out.println("True: This code is present");
                }
            }
        }

    }

    /* This method removes the parenthesis and generates all the possibilities.
     * This method assumes that the parenthesis always comes in pair, thus
     * for every opening parenthesis ["("] there is a closing parenthesis [")"]
     * Example if the "code" is [A(WX)C(YZ)] then it will generate AWCY, AWCZ, AXCY and AXCZ 
     * 
     * @param code - The string which contains parenthesis.
     * @return a list of all the possibilities
     */
    public static List<String> generatePossibilities(String code) {
        // This will hold the left part of the possibleCodes (part before "(")
        List<String> possibleCodeList = new LinkedList<>();
        String s = code;
        boolean first = true;

        // Loop while an open parenthesis ["("] can be found
        while (s.contains("(")) {
            // Retrieve from the string the first substring where "(" starts and ends with ")"
            // In the example, in the first iteration will be "WX"
            // in the second iteration this will be "YZ"
            String inside = s.substring(s.indexOf("(") + 1, s.indexOf(")"));

            // Retrieve the list inside the "(" and ")"
            // In the example, in the first iteration the list will have "W", "X"
            // in the second iteration the list will have "Y", "Z"
            String[] listOfChoices = inside.split(",");

            // This will hold the right part of the possibleCodes (part after ")")
            List<String> listOfCombinations = new LinkedList<>();

            // Loop all the possible choices
            for (String choice : listOfChoices) {
                // If it is the first iteration then you need to include those characters before the "("
                if (first) {
                    // add the characters before the "(" and the remaining characters after ")"
                    // In the example, the first iteration of this list ("W", "X") will add "AWC(YZ)"
                    // the second iteration of this list ("W", "X") will add "AXC(YZ)"
                    listOfCombinations.add(s.substring(0, s.indexOf("(")) + choice + s.substring(s.indexOf(")") + 1));
                } 
                // Else just start with choice
                else {
                    // add the remaining characters after ")"
                    // In the example, the first iteration of this list ("Y", "Z") will add "Y"
                    // the second iteration of this list ("Y", "Z") will add "Z"
                    listOfCombinations.add(choice + s.substring(s.indexOf(")") + 1));
                }
            }
            // Remove the subtring before the ")", in the example this will be "C(YZ)"
            s = s.substring(s.indexOf(")") + 1);

            // If it is the first iteration then you just need to assign the listOfCombinations directly to possibleCodeList, 
            // since possibleCodeList is still empty
            if (first) {
                possibleCodeList = listOfCombinations;
                first = false;
            } 
            // Else combine the left and right part
            else {
                List<String> codePossiblity2 = new LinkedList<>();
                // Iterate though all the list of possible codes since we want all the elements in the list to be concatenated with the right half of the string
                // The list will have "AWC(YZ)" and "AXC(YZ)"
                for (String possibleCodes : possibleCodeList) {
                    // Iterate the possible combinations of the right half of the original string (the second pair of "()")
                    // The list will have "Y" and "Z"
                    for (String sTmp : listOfCombinations) {
                        // Replace the string which are inside the "()" in the left half of the original string.
                        // Replace it with the right half of the original string
                        // In the string of "AWC(YZ)" replace "(YZ)" with "Y"
                        // In the string of "AWC(YZ)" replace "(YZ)" with "Z"
                        // In the string of "AXC(YZ)" replace "(YZ)" with "Y"
                        // In the string of "AXC(YZ)" replace "(YZ)" with "Z"
                        String t = possibleCodes.replace("(" + inside + ")", sTmp);
                        // add the newly created string to codePossiblity2
                        codePossiblity2.add(t);
                    }

                    // At the end of the loop above codePossiblity2 will have these values
                    // AWCY, AWCZ, AXCY and AXCZ
                }

                // overwrite the possibleCodeList since we have now a new left part of the string
                possibleCodeList = codePossiblity2;
            }
        }

        return possibleCodeList;
    }

}

答案 1 :(得分:0)

如果您要做的只是根据用户输入正确或错误,则可以将代码字符串转换为正则表达式,并检查输入是否与正则表达式列表匹配。

步骤:

  • 将代码列表中的每个元素转换为正则表达式

    //将“ ABC(Q,E,1)EEE”转换为“ ABC [QE1] EEE”,以匹配每个以ABC开头,后跟[QE1]中的一个并以EEE结尾的字符串

    //“ R(1,2,3,4,5)RT(U,M,N,B,V,H)(Q,E,R,F,G,H)(R,Z) ”转换为“ R [12345] RT [UMNBVH] [QERFGH] [RZ]”

  • 检查输入是否与正则表达式之一匹配

示例:

public static void main(String[] args) {

    Scanner scan = new Scanner(System.in);
    System.out.println("Enter the code you want to check: ");
    String input = scan.next();

    List<String> codes = new ArrayList<>();
    codes.add("ABC(Q,E,1)EEE");
    codes.add("ABDCE(E,Z,X)E");
    codes.add("B(A,1)AAEEE");
    codes.add("R(1,2,3,4,5)RT(U,M,N,B,V,H)(Q,E,R,F,G,H)(R,Z)");
    codes.add("B(A,1)AA(E,Z)EE");

    //list to store the modified strings
    List<String> modifiedCodes = new ArrayList<>();
    //for each string in list find if there is a pattern like '('some chars')'
    Pattern p = Pattern.compile("\\(.*\\)");
    for (Iterator<String> i = codes.iterator(); i.hasNext();) {
        String code = i.next();
        StringBuffer  sb = new StringBuffer ();
        Matcher m = p.matcher(code);
         while (m.find()) { 
            String match = m.group();
            //if found a match replace '(' and ')' with '[' and ']' and remove commas
            m.appendReplacement(sb, match.replace('(', '[').replace(')', ']').replace(",", ""));
          }
          m.appendTail(sb);
          //add modified string to list
          modifiedCodes.add(sb.toString());
    }     

    boolean codeIsPresent = false;
    for(String code: modifiedCodes){
        //check if input matches one of the regex in the list 'modifiedCodes'
        if (input.matches(code)) {
            codeIsPresent = true;
            System.out.println("True: This code is present");
            break;
        }
    }
    if(!codeIsPresent){
        System.out.println("Code not found");
    }
}

编辑

  

我们如何从中打印字符串的所有组合的列表   它正在获得输出?说,我只有一根绳子   “ BA(1,2,3)QW(A-Z,0-9)”,我希望将其所有可能的组合

以上评论中的问题与原始帖子略有不同,如果发布新问题可能会更好。您可以使用某种树形结构创建自己的算法来解决该问题,但它可能会很杂乱无章。我建议尽可能使用generex之类的第三方天秤座。您可以下载jar from the maven repo here。使用generex,您可以拥有所有可能的组合:

public static void main(String args[]){
    //change your input to a regular expression
    //"BA(1,2,3)QW(A-Z,0-9)"  to  "BA[1-3]QW[A-Z][0-9]"
    Generex generex = new Generex("BA[1-3]QW[A-Z][0-9]");
    List<String> matchedStrs = generex.getAllMatchedStrings();
    matchedStrs.forEach(System.out::println);
}