早些时候我需要为我的工作写一个算法,我写了它,但对我来说相当困难,算法显然不是最好的实现,所以我会问专业人士它可以如何升级,我在哪里有问题,一些技巧.

Given

模式,它描述了字符串的变化:abc[de[f,g],hk],这给出了

abcdef
abcdeg
abchk

模式由"数组"组成,后跟字符串:abc[...]和字符串adj,kg,q

另一个可能更复杂的例子是:utvk[fvu,gn[u,k,r],nl,q[t[ij,lo[z,x]],bm]].

Conditions

  1. 字符串本身只能包含字母和数字.不可能有abc[h\,k,b]abc[h\[k,b]等于abch,kabch[k.
  2. "数组"始终不为空,并且至少有2个元素.
  3. 可以有任意顺序的"数组"或"唯一字符串"值,即:abc[a,b[c,d]]abc[a[b,c],d].从左到右的顺序是严格的,不能有来自图案abc[d,e]的组合eabcdabc.
  4. abc[d,e]既不是abcde,也不是abced,只有abcdabce.
  5. Pattern始终以字符串开头,数组:something[...].
  6. 可以有不带数组的字符串:abc[a,bc[d,f]],但不允许有不带字符串的数组:abc[a,[d,f]].
  7. 可以有一个空字符串,即:a[,b],表示aab

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]]')

推荐答案

我会使用正则表达式将输入分解为标记.在本例中,我 Select 了成对的(字母,分隔符),其中分隔符是"[""]"","中的一个.字母部分可能为空.

然后我会像你一样使用递归函数,但我 Select 了递归generator函数.

以下是建议的实施:

function* getStrings(pattern) {
    const tokens = pattern.matchAll(/([^[\],]*)([[\],])?/g);
    
    function* dfs(recur=false) {
        let expectToken = true;
        while (true) {
            const [, token, delim] = tokens.next().value;
            if (delim === "[") {
                for (const deep of dfs(true)) yield token + deep;
            } else {
                if (token || expectToken) yield token;
                if (delim === "]" && !recur) throw "Invalid pattern: too many `]`";
                if (!delim && recur) throw "Invalid pattern: missing `]`";
                if (delim !== ",") return;
            }
            expectToken = delim !== "["; // After [...] we don't expect a letter
        }
    }
    yield* dfs();
}


const input = 'IE5E[COR[R[,G[A,E,I]],S,T,U,V,W,X,Y,Z],EORRG[I,M]]';
for (const s of getStrings(input))
    console.log(s);

此实施应根据给定的限制与模式匹配,但它还将允许以下内容:

  • "数组"可以不带字母前缀.因此,[a,b]是允许的,并且将产生与a,b相同的输出.
  • "数组"后面可以紧跟字母或新的"数组",但这将被解释为它们之间用逗号隔开.所以x[a,b]c将被解释为x[a,b],c
  • "数组"可以为空.在这种情况下,该数组将被忽略.所以x[]等于x.

有一些基本的错误判断:当括号不平衡时将生成错误.

Javascript相关问答推荐

在类型脚本中使用浏览器特定属性的正确方法是什么?

在Phaser中查找哪个物体处于碰撞中

响应式JS DataTable中的Bootstrap 5弹出程序无法正常工作

如何在非独立组件中使用独立组件?

基于每个索引迭代嵌套对象

如何让\w token 在此RegEx中表现得不贪婪?

格式值未保存在redux持久切片中

防止用户在selectizeInput中取消 Select 选项

使用i18next在React中不重新加载翻译动态数据的问题

为什么这个JS模块在TypeScript中使用默认属性导入?""

如何添加绘图条形图图例单击角形事件

在执行异步导入之前判断模块是否已导入()

使用原型判断对象是否为类的实例

环境值在.js文件/Next.js中不起作用

在开发期间,Web浏览器如何运行&qot;.jsx&qot;文件?

JS Animate()方法未按预期工作

如何在和IF语句中使用||和&;&;?

将Auth0用户对象存储在nextjs类型脚本的Reaction上下文中

MongoDB通过数字或字符串过滤列表

AG-GRIDreact 显示布尔值而不是复选框