String Letter组合使用Java

时间:2015-11-27 21:54:03

标签: java math arraylist probability discrete-mathematics

所以我遇到了一个问题,我有一个ArrayList,其中List由一个字母字符串组成。在这种情况下(A,B,C,D,F,J,N),其中列表的大小为7.

现在我正在尝试编写代码,使得可以在顺序无关紧要的情况下进行所有字母组合,即(我知道它将涉及“n选择k”)最多5个字母。

因此对于7选择1将是A,B,C,D,F,J,N ... 7选择2 ...等 ... 7选择3 ...等 ......等等。

然后我想将这些字符串组合存储到另一个列表/ hashmap中(尚未确定)。

但我主要关注的是生成此类字符串的代码。如果有人可以提供帮助,那将非常感激。我也想让它模块化,以防万一我想最终形成6,7长度的其他组合。 (这就是为什么我不只是使用5个循环并为不同的索引递增)。

到目前为止我所拥有的......

public class ReadFile {

    public static void main(String[] args) throws IOException {

        String file_name = "C:/Users/Shane/Documents/College/Classes/PurchaseTable.txt";

        extract(file_name, 50);


    }

        private String path;

        public ReadFile(String file_path) {
            path= file_path;
        }

        public String[] OpenFile() throws IOException {
            FileReader fr = new FileReader(path);
            BufferedReader textReader = new BufferedReader(fr);

            int numberOfLines = readLines();
            String[] textData = new String[numberOfLines];

            int i;

            for(i=0; i < numberOfLines; i++) {
                textData[i] = textReader.readLine();
            }

            textReader.close();
            return textData;
        }

        int readLines() throws IOException {

            FileReader file_to_read = new FileReader(path);
            BufferedReader bf = new BufferedReader(file_to_read);

            String aLine;
            int numberOfLines = 0;

            while(( aLine = bf.readLine()) != null) {
                numberOfLines++;
            }
            bf.close();

            return numberOfLines;
        }

    public static void extract(String filename, int threshold) {

        String file_name = filename;
        ArrayList<String> temp = new ArrayList<String>();
        ArrayList<String> products = new ArrayList<String>();
        HashMap<Integer, String> productsPerDate = new HashMap<Integer, String>();
        //HashMap<Integer, String> allCombinations = new HashMap<Integer, String>();

        try {
            ReadFile file = new ReadFile(file_name);
            String[] aryLines = file.OpenFile();
            int i;
            for (i=1; i < aryLines.length; i++) { //excludes header section of any table as shown in assignment
                temp.add(aryLines[i]);              
            }
        }
        catch (IOException e) {
            System.out.println( e.getMessage() );
        }

        System.out.println(temp);
        System.out.println(temp.get(0));
        System.out.println(temp.size());

        int i; int j; int l;
        for (i=0; i<temp.size(); i++) {
            String str = temp.get(i);
            StringBuilder sb = new StringBuilder(str);
            int k =0;
            for (j=0; j<=sb.length(); j++) {
                if(sb.charAt(j) == '\"' && k==0) {
                    sb.delete(0, j+1);
                    k++;
                }
                if(sb.charAt(j) == '\"' && k!=0) {
                    sb.delete(j, sb.length());
                    String line = null;
                    System.out.println(sb);
                    for( l=0; l<sb.length(); l++) {
                         String string = Character.toString(sb.charAt(l));
                         if(string.equals(",")) {

                         }
                         else if (l ==0) {
                             products.add(string);
                             line = string;
                         }
                         else {
                             products.add(string);
                             line = line + string;
                         }
                    }
                    productsPerDate.put(i, line);
                    //System.out.println(products);
                    break;
                }
            }
        }

        System.out.println(products);
        System.out.println(productsPerDate.entrySet()); //Hashmap set to string of 1 letter characters for products per date

        Set<String> removeDup = new HashSet<>();
        removeDup.addAll(products);
        products.clear();
        products.addAll(removeDup);

        System.out.println(products);

        int maxLength = productsPerDate.get(0).length();
        for(int m = 0; m < productsPerDate.size(); m++) { //determine max length of string in hashmap
            if(maxLength < productsPerDate.get(m).length()) {
                maxLength = productsPerDate.get(m).length();
            }
        }

这可能不是最有效的方法,但请耐心等待,并以任何方式提供帮助。

输出如下所示:在上面的代码中创建的内容:

1,"A,B,C,N",1/3/2013
4
A,B,C,N
B,C,D,A,F
A,C,V,N,J
A,C,J,D
[A, B, C, N, B, C, D, A, F, A, C, V, N, J, A, C, J, D]
[0=ABCN, 1=BCDAF, 2=ACVNJ, 3=ACJD]
[A, B, C, D, F, V, J, N]

所以基本上我试图编写代码,使用最后一个输出中显示的数组列表中包含的字母字符串来制作长度为5的所有可能组合。

2 个答案:

答案 0 :(得分:2)

给定一个长度为n的输入字符串,这里有一个小方法返回长度为k的所有字母组合的列表(顺序并不重要):

public static ArrayList<String> combinations(String nChars, int k) {
    int n = nChars.length();
    ArrayList<String> combos = new ArrayList<String>();
    if (k == 0) {
        combos.add("");
        return combos;
    }
    if (n < k || n == 0)
        return combos;
    String last = nChars.substring(n-1);
    combos.addAll(combinations(nChars.substring(0, n-1), k));
    for (String subCombo : combinations(nChars.substring(0, n-1), k-1)) 
        combos.add(subCombo + last);

    return combos;
}

public static void main(String[] args) {
    String nChars = "ABCDE";
    System.out.println(combinations(nChars, 2));
}

output: [AB, AC, BC, AD, BD, CD, AE, BE, CE, DE]

我使用字符串作为输入和输出,因为它们是不可变的,并且在切片方面比列表表现得更好。但是如果你的List只包含1个字母的字符串,那么它应该很容易转换。

我不知道这个递归实现是否具有高效性,但它很好地反映了Pascal三角形的数学属性:(n choose k) = (n-1 choose k-1) + (n-1 choose k)

答案 1 :(得分:0)

蛮力,没有递归,带有泛型,没有优化,说教。

如果你想要安排而不是组合,只需注释一行。

// COMBINAISONS
/**
 * Return combinaisons of input
 * @param _input 
 * @param _n how many to pick
 * @return
 */
public static <T> Vector<Vector<T>> combinaisons (Vector<T> _input, int _n)
{
Vector<Vector<T>> output=new Vector<Vector<T>> ();

int size=_input.size();

// Current result
Object current[]=new Object[_n];
Arrays.fill(current,"");

// which element we take at each box  (between 0 and size-1)
int current_indices[]=new int[_n];
Arrays.fill(current_indices,-1);

// inputs used
boolean used[]=new boolean [size];
Arrays.fill(used, false);

// Which box are we processing
int current_box=0;

// Next value for next position
int next_pos_value=0;

// ALGORITHM

while (true)
{
// Finished ?
if (current_box<0)
    break;

// Last element ? 
if (current_box>=_n)
    {
    // => save group
    output.add(new Vector<T>((List<T>) Arrays.asList(current)));

    current_box--;
    continue;
    }

// filling Current box > 0 && < _n

// next value available
int last_value=current_indices[current_box];
int next_value=-1;

// Where do we begin
int begin_test=0;
if (last_value>=0)
    begin_test=last_value+1;

// bigger
// comment this for arrangement rather than combinaisons
if (begin_test<next_pos_value) begin_test=next_pos_value;

for (int test_value=begin_test; test_value < size; test_value++)
        if (!used[test_value])
            {
            next_value=test_value;
            break;
            }

// VALUE AVAILABLE
if (next_value!=-1)
    // valid value ?
    {
    // release
    if (last_value!=-1)
        used[last_value]=false;

        used[next_value]=true;
        current_indices[current_box]=next_value;
        current[current_box]=_input.get(next_value);

        // next position
        current_box++;

        // like arrangements, but next value always more
        next_pos_value=next_value+1;

        continue;
    }       

else
    // invalid value (too big) ?
    {
    // release
    if (last_value!=-1)
    used[last_value]=false;
    current_indices[current_box]=-1;

    // back position
    current_box--;

    // like arrangements, but reset this
    next_pos_value=-1;

    continue;
    }       
}

return output;
}
//  public static Vector<Vector<T>> combinaisons (Vector<T> _input)