I wrote an algorithm that is inadequate, namely because it does not handle [,abc]
cases (see the string variations and conditions below), and would like to know how it can be improved so it covers those cases:
Given
Pattern, that describes strings variations: abc[de[f,g],hk]
, which gives
abcdef
abcdeg
abchk
Pattern consists of "arrays", that followed by strings: abc[...]
, and strings adj,kg,q
Another possible more complex example: utvk[fvu,gn[u,k,r],nl,q[t[ij,lo[z,x]],bm]]
.
Conditions
- Strings itself can contain only letters and numbers. There couldn't be
abc[h\,k,b]
orabc[h\[k,b]
that givesabch,k
orabch[k
. - "Arrays" always not empty, and has at least 2 elements.
- There can be any order of "array", or "only string" value, i.e.:
abc[a,b[c,d]]
orabc[a[b,c],d]
. The order is strict from left to right, there can not be from patternabc[d,e]
combinationseabc
ordabc
. abc[d,e]
doesn't givesabcde
norabced
string, onlyabcd
andabce
.- Pattern always starts with string with array:
something[...]
. - There can be string without array:
abc[a,bc[d,f]]
, but array without string is not allowed:abc[a,[d,f]]
. - There can be an empty string, i.e.:
a[,b]
, that givesa
andab
My solution
function getStrings(pat) {
if(pat.indexOf('[') == -1)
return pat;
String.prototype.insert = function(index, string) {
if (index > 0) {
return this.substring(0, index) + string + this.substr(index);
}
return string + this;
};
function getArray(str, start, isSource = false) {
if (start < 0) return null;
var n = 0;
var ret = "";
var i = start;
for (; i < str.length; i++) {
if (str[i] == "[") n++;
else if (str[i] == "]") n--;
if (n == 0) break;
}
var ret = {
str: "",
arr: "",
end: 0,
};
ret.arr = str.slice(start, i) + "]";
ret.end = i;
start--;
var end = start;
for (
;
start > 0 &&
str[start] != "," &&
str[start] != "]" &&
str[start] != "[";
start--
) {}
if(!isSource)
start++;
end++;
ret.str = str.slice(start, end);
return ret;
}
function getElement(source, start) {
var ret = [];
start++;
for (
;
start < source.length && source[start] != "," && source[start] != "]";
start++
)
ret[ret.length] = source[start];
return ret;
}
var source = getArray(pat, pat.indexOf("["), true); // parsing
var ar = source.arr;
source.arrs = getArrays(source); // parsing
source.source = true;
var fi = "";
var temp_out = [];
var tol = 0;
return getVariations(source); // getting variations of parsed
function getVariations(source) {
if (source.arrs == undefined) {
} else
for (var i = 0; i < source.arrs.length; i++) {
if (source.source) fi = source.str;
if (!source.arrs[i].arrs) {
temp_out[tol] = fi + source.arrs[i].str;
tol++;
} else {
var lafi = fi;
fi += source.arrs[i].str;
getVariations(source.arrs[i]);
if(i != source.arrs.length - 1)
fi = lafi;
}
if (source.source && i == source.arrs.length - 1) {
var temp = temp_out;
temp_out = [];
tol = 0;
return temp;
}
}
}
function getArrays(source) {
var la = 1;
var start = 0;
var arrs = [];
if (!source.arr) return;
while (start != -1) {
start = source.arr.indexOf("[", la);
var qstart = source.arr.indexOf(",", la);
if(source.arr[la] == ',')
qstart = source.arr.indexOf(",", la+1);
var pu = false;
if(qstart != la && qstart != -1 && qstart < start && start != -1)
{
pu = true;
var str = source.arr;
var buf = [];
qstart--;
var i = -1;
for(i = qstart; i > 0 && str[i] != '[' && str[i] != ','; i--)
{}
i++;
for(; i < str.length && str[i]!= ','; i++)
{
buf[buf.length] = str[i];
}
if(buf.length == 0)
{
la = start;
alert("1!")
}
else
{
buf = buf.join('');
arrs[arrs.length] = {str:buf};
la += buf.length+1;
}
}
else
if (start != -1) {
arrs[arrs.length] = getArray(source.arr, start);
la = arrs[arrs.length - 1].end + 1;
} else {
start = source.arr.indexOf(",", la);
if (start != -1) {
var ret = getElement(source.arr, start);
arrs[arrs.length] = ret;
la += ret.length;
}
}
}
for (var i = 0; i < arrs.length; i++)
if (typeof arrs[i] != "string" && arrs[i].arr) {
arrs[i].arrs = getArrays(arrs[i]);
var st = arrs[i].arr;
if (occ(arrs[i].arr, "[") == 1 && occ(arrs[i].arr, "]") == 1) {
st = st.replaceAll("[", '["');
st = st.replaceAll("]", '"]');
st = st.replaceAll(",", '","');
st = JSON.parse(st);
for (var j = 0; j < st.length; j++) st[j] = { str: st[j] };
arrs[i].arrs = st;
}
} else if (typeof arrs[i] == "string") {
arrs[i] = { str: arrs[i] };
}
RecursArrs(arrs);
return arrs;
}
function RecursArrs(arrs) {
for (var i = 0; i < arrs.length; i++) {
if (!arrs[i].source)
if (arrs[i].arr) {
delete arrs[i].arr;
delete arrs[i].end;
}
if (!arrs[i].str) {
try{
arrs[i] = { str: arrs[i].join("") };
}catch(er)
{
arrs[i] = {str:''};
}
if (i && arrs[i - 1].str == arrs[i].str) {
arrs.splice(i, 1);
i--;
}
} else if (arrs[i].arrs) RecursArrs(arrs[i].arrs);
}
}
function occ(string, word) {
return string.split(word).length - 1;
}
}
// getStrings('IE5E[COR[R[,G[A,E,I]],S,T,U,V,W,X,Y,Z],EORRG[I,M]]')
]
is followed by a letter or by a[
? – Equalizera[b,c]d
ora[b,c][d,e]
– Equalizera[b,c],d
,a[b,c],[d,e]
. But there are two important things I didn't mentioned in the post, wait a minute – TaurineR[,G[A,E,I]]
. Does the immediate comma mean thatR
is a possible outcome? Does that mean that also,,
would be allowed or,]
-- with the same purpose? – Equalizer[,...
stuff. Probably justpat = pat.replaceAll('[,','[').replaceAll(',]',']').replaceAll(',,',',')
at the beginning – Taurinea[,b]
would allowa
andab
as outputs, whilea[b]
would only allowab
as output. Can you confirm what you want? – Equalizer[,abc]
cases, which I just have not been noticing before trincot pointed that – Taurine