Java 从多个列表中获取所有值的组合
我试图根据给定的字符串解析所有元素的组合 字符串如下所示:Java 从多个列表中获取所有值的组合,java,performance,algorithm,combinations,Java,Performance,Algorithm,Combinations,我试图根据给定的字符串解析所有元素的组合 字符串如下所示: String result="1,2,3,###4,5,###6,###7,8,"; 未确定###(以,分隔)之间的元素数量,也未确定“列表”(以##分隔的部分)的数量 注意:我在这个例子中使用数字,但它也可以是String 本例中的预期结果是一个字符串,其中包含: String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 35
String result="1,2,3,###4,5,###6,###7,8,";
未确定###
(以,
分隔)之间的元素数量,也未确定“列表”(以##
分隔的部分)的数量
注意:我在这个例子中使用数字,但它也可以是String
本例中的预期结果是一个字符串,其中包含:
String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 3568"
因此,正如您所看到的,结果中的元素必须以第一个列表的元素开始,然后第二个元素必须是第二个列表的元素,等等
从现在开始,我做了这个算法,但它很慢:
String [] parts = result.split("###");
if(parts.length>1){
result="";
String stack="";
int i;
String [] elmts2=null;
String [] elmts = parts[0].split(",");
for(String elmt : elmts){ //Browse root elements
if(elmt.trim().isEmpty())continue;
/**
* This array is used to store the next index to use for each row.
*/
int [] elmtIdxInPart= new int[parts.length];
//Loop until the root element index change.
while(elmtIdxInPart[0]==0){
stack=elmt;
//Add to the stack an element of each row, chosen by index (elmtIdxInPart)
for(i=1 ; i<parts.length;i++){
if(parts[i].trim().isEmpty() || parts[i].trim().equals(","))continue;
String part = parts[i];
elmts2 = part.split(",");
stack+=elmts2[elmtIdxInPart[i]];
}
//rollback i to previous used index
i--;
if(elmts2 == null){
elmtIdxInPart[0]=elmtIdxInPart[0]+1;
}
//Check if all elements in the row have been used.
else if(elmtIdxInPart[i]+1 >=elmts2.length || elmts2[elmtIdxInPart[i]+1].isEmpty()){
//Make evolve previous row that still have unused index
int j=1;
while(elmtIdxInPart[i-j]+1 >=parts[i-j].split(",").length ||
parts[i-j].split(",")[elmtIdxInPart[i-j]+1].isEmpty()){
if(j+1>i)break;
j++;
}
int next = elmtIdxInPart[i-j]+1;
//Init the next row to 0.
for(int k = (i-j)+1 ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i-j]=next;
}
else{
//Make evolve index in current row, init the next row to 0.
int next = elmtIdxInPart[i]+1;
for(int k = (i+1) ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i]=next;
}
//Store full stack
result+=stack+",";
}
}
}
else{
result=parts[0];
}
String[]parts=result.split(“####”);
如果(零件长度>1){
结果=”;
字符串堆栈=”;
int i;
字符串[]elmts2=null;
字符串[]elmts=parts[0]。拆分(“,”;
对于(字符串elmt:elmts){//浏览根元素
如果(elmt.trim().isEmpty())继续;
/**
*此数组用于存储每行要使用的下一个索引。
*/
int[]elmtIdxInPart=新int[parts.length];
//循环,直到根元素索引更改。
while(elmtIdxInPart[0]==0){
stack=elmt;
//向堆栈中添加每行的一个元素,按索引选择(elmtIdxInPart)
对于(i=1;i=elmts2.length | | elmts2[elmtIdxInPart[i]+1].isEmpty()){
//使上一行仍然有未使用的索引
int j=1;
while(elmtIdxInPart[i-j]+1>=零件[i-j]。拆分(“,”)。长度| |
部件[i-j]。拆分(“,”[i-j]+1]。isEmpty(){
如果(j+1>i)断裂;
j++;
}
int next=elmtIdxInPart[i-j]+1;
//将下一行初始化为0。
对于(int k=(i-j)+1;k这是我的解决方案。它在C#中,但您应该能够理解它(重要的部分是“计算下一个元素”部分):
static void Main(字符串[]args)
{
//解析输入,这可能可以更有效地完成
字符串输入=“1,2,3,####4,5,####6,###7,8,”;
string[]list=input.Replace(“###“,“#”)Split(“#”);
int N=列表长度;
int[]长度=新的int[N];
int[]索引=新的int[N];
对于(int i=0;i=0;ind--)
如果(索引[ind]<长度[ind]-1)中断;
如果(ind==-1)中断;
指数[ind]++;
对于(ind++;ind
似乎有点类似于您的解决方案。这真的有糟糕的性能吗?在我看来,这显然是最优的,因为复杂性与输出的大小成线性关系,而输出的大小总是最优的
编辑:我所说的“相似”是指你似乎也在用索引进行计数。你的代码太复杂了,我下班后无法进入其中。:D
我的索引调整工作非常简单:从右边开始,找到我们可以不溢出地增加的第一个索引,增加1,然后将所有的索引设置为右边(如果有的话)0。它基本上是在一个数字系统中计数,每个数字都在不同的基数中。一旦我们不能再增加第一个索引(这意味着我们不能增加任何,因为我们从右边开始检查),我们完成了。这里有一个稍微不同的方法:
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}
static void Main(字符串[]args)
{
字符串输入=“1,2,3,####4,5,####6,###7,8,”;
string[]list=input.Replace(“###“,“#”)Split(“#”);
int N=列表长度;
int[]长度=新的int[N];
字符串[][]元素=新字符串[N][];
int-outCount=1;
//获取每个位置的每个字符串
对于(int i=0;i
我也不是Java程序员,所以我采用了Svinja的c#answe
static void Main(string[] args)
{
// parse the input, this can probably be done more efficiently
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
int[] indices = new int[N];
for (int i = 0; i < N; i++)
length[i] = lists[i].Split(',').Length - 1;
string[][] element = new string[N][];
for (int i = 0; i < N; i++)
{
string[] list = lists[i].Split(',');
element[i] = new string[length[i]];
for (int j = 0; j < length[i]; j++)
element[i][j] = list[j];
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++) Console.Write(element[i][indices[i]]);
Console.WriteLine(" ");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
}
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}