Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 非结构化字符串连接策略_C#_Algorithm - Fatal编程技术网

C# 非结构化字符串连接策略

C# 非结构化字符串连接策略,c#,algorithm,C#,Algorithm,我有一些非结构化字符串数组(长度不同),我希望将它们连接到一个字符串表达式中,以便进行解析。例如: a +b => a+b a+ b => a+b a +b c +d => a+b, c+d a+ b c+ d => a+b, c+d a+ b +c d => a+b+c, d a +b +c d => a+b+c, d a+ b+

我有一些非结构化字符串数组(长度不同),我希望将它们连接到一个字符串表达式中,以便进行解析。例如:

a  +b              => a+b
a+  b              => a+b
a  +b   c  +d      => a+b, c+d
a+  b   c+  d      => a+b, c+d
a+  b  +c   d      => a+b+c, d
a  +b  +c   d      => a+b+c, d
a+  b+  c  +d      => a+b+c+d
a  +b  +c  +d      => a+b+c+d
a  +b+  c+  d      => a+b+c+d
a  +b   c   d      => a+b, c, d
NB:a、b、c和d用于简洁。它们实际上可以是任意长度的字符串。此外,也可能有任意数量的人。。。不仅仅是4个。

请注意,元素可以具有前导或尾随运算符,这些运算符将确定它是否应连接到数组中的上一个或后续项,以确定它是独立的还是作为下一个表达式的一部分。(一元运算符和确定

a -b => a-b or a, -b
我确实有语法(反语)我当前使用它来确定正在构建的表达式是否格式正确。因此,我连接每个元素,一次一个,解析连接的结果以查看其格式是否正确。如果格式正确,我仍然需要继续使用元素,以防下一个元素有前导运算符。一旦我从解析器(或者数组没有更多的元素),我断定表达式(除了最后2个串联)是有效的,存储它,然后重新开始。(我需要这样做,因为我需要知道有效表达式是数组中特定元素的串联,因为这些元素映射回具有其他信息的对象。)

但这一切都让人觉得有点笨拙

a +b +c +d 

a          => valid
a +b       => valid
a +b +c    => valid
a +b +c +d => valid
我会得到4个有效的“信号”,但对于底层表达式,只有最后一个是“真正的”有效“信号”

我想知道是否还有其他更优雅的策略来决定是否应该连接。例如,可能我没有充分使用解析器,或者可能有一些我不熟悉的模式匹配策略

那么我应该如何处理这个问题呢

提前Thx


PS我正在使用C,但我不认为这与此场景相关。

似乎如果删除所有空白,所有有效字符串都是奇数。接下来需要检查所有奇数位置是否都是leter(a、b等),偶数位置是否都是有效字符(+、-、等).

似乎如果删除所有空白,所有有效字符串都是奇数。接下来需要检查所有奇数位置是否都是LETER(a、b等),偶数位置是否都是有效字符(+、-、等)。

这应该起作用,请注意此代码如何处理一元运算符

static List<string> GetExpressions(string[] stringArray)
    {
        const string operators = "+-*/=";
        const string unaryOps = "+-";
        var q = new Queue<string>(stringArray.Length*2);

        foreach (string s in stringArray)
        {
            var work = s;
            if (operators.Contains(work[0]))
            {
                q.Enqueue(work[0].ToString());
                work = work.Substring(1);
            }
            if (operators.Contains(work[work.Length-1]))
            {
                q.Enqueue(work.Substring(0, work.Length - 1));
                q.Enqueue(work[work.Length - 1].ToString());
                continue;
            }
            q.Enqueue(work);
        }

        var res = new List<string>();
        var tmpString = new StringBuilder();
        var lastState = "Op";

        while (q.Count > 0)
        {
            var currElem = q.Dequeue();
            var currState = "St";
            if (unaryOps.Contains(currElem))
                currState = "Un";
            else if (operators.Contains(currElem))
                currState = "Op";

            switch (lastState + currState)
            {
                case "OpUn":
                case "OpSt":
                case "UnUn": // only with + & - unary ops: refinement necessary
                case "UnSt":
                case "StUn": // only with + & - unary ops: refinement necessary
                case "StOp":
                    tmpString.Append(currElem);
                    break;
                case "StSt":
                    res.Add(tmpString.ToString());
                    tmpString.Length=0;
                    tmpString.Append(currElem);
                    break;
                case "OpOp":
                case "UnOp":
                    throw new Exception();
            }
            lastState = currState;
        }

        res.Add(tmpString.ToString());

        return res;
    }
static List GetExpressions(string[]stringArray)
{
常量字符串运算符=“+-*/=”;
常量字符串unaryOps=“+-”;
var q=新队列(stringArray.Length*2);
foreach(stringArray中的字符串s)
{
var功=s;
if(运算符.Contains(工作[0]))
{
q、 排队(工作[0]。ToString());
功=功。子串(1);
}
if(运算符.Contains(工时[work.Length-1]))
{
q、 排队(work.Substring(0,work.Length-1));
q、 排队(工时[work.Length-1].ToString());
持续
}
q、 排队(工作);
}
var res=新列表();
var tmpString=新的StringBuilder();
var lastState=“Op”;
而(q.Count>0)
{
var currElem=q.Dequeue();
var currState=“St”;
if(不包含(currElem))
currState=“Un”;
else if(运算符包含(currElem))
currState=“Op”;
开关(最后状态+当前状态)
{
“OpUn”案:
案例“OpSt”:
案例“UnUn”://仅带+&-一元运算:需要细化
案例“UnSt”:
案例“晕眩”://仅使用+&-一元运算:需要细化
案例“停止”:
tmpString.Append(currElem);
打破
案例“StSt”:
res.Add(tmpString.ToString());
tmpString.Length=0;
tmpString.Append(currElem);
打破
“OpOp”案:
案件“UnOp”:
抛出新异常();
}
lastState=当前状态;
}
res.Add(tmpString.ToString());
返回res;
}

这应该行得通,注意这段代码如何处理一元运算符

static List<string> GetExpressions(string[] stringArray)
    {
        const string operators = "+-*/=";
        const string unaryOps = "+-";
        var q = new Queue<string>(stringArray.Length*2);

        foreach (string s in stringArray)
        {
            var work = s;
            if (operators.Contains(work[0]))
            {
                q.Enqueue(work[0].ToString());
                work = work.Substring(1);
            }
            if (operators.Contains(work[work.Length-1]))
            {
                q.Enqueue(work.Substring(0, work.Length - 1));
                q.Enqueue(work[work.Length - 1].ToString());
                continue;
            }
            q.Enqueue(work);
        }

        var res = new List<string>();
        var tmpString = new StringBuilder();
        var lastState = "Op";

        while (q.Count > 0)
        {
            var currElem = q.Dequeue();
            var currState = "St";
            if (unaryOps.Contains(currElem))
                currState = "Un";
            else if (operators.Contains(currElem))
                currState = "Op";

            switch (lastState + currState)
            {
                case "OpUn":
                case "OpSt":
                case "UnUn": // only with + & - unary ops: refinement necessary
                case "UnSt":
                case "StUn": // only with + & - unary ops: refinement necessary
                case "StOp":
                    tmpString.Append(currElem);
                    break;
                case "StSt":
                    res.Add(tmpString.ToString());
                    tmpString.Length=0;
                    tmpString.Append(currElem);
                    break;
                case "OpOp":
                case "UnOp":
                    throw new Exception();
            }
            lastState = currState;
        }

        res.Add(tmpString.ToString());

        return res;
    }
static List GetExpressions(string[]stringArray)
{
常量字符串运算符=“+-*/=”;
常量字符串unaryOps=“+-”;
var q=新队列(stringArray.Length*2);
foreach(stringArray中的字符串s)
{
var功=s;
if(运算符.Contains(工作[0]))
{
q、 排队(工作[0]。ToString());
功=功。子串(1);
}
if(运算符.Contains(工时[work.Length-1]))
{
q、 排队(work.Substring(0,work.Length-1));
q、 排队(工时[work.Length-1].ToString());
持续
}
q、 排队(工作);
}
var res=新列表();
var tmpString=新的StringBuilder();
var lastState=“Op”;
而(q.Count>0)
{
var currElem=q.Dequeue();
var currState=“St”;
if(不包含(currElem))
currState=“Un”;
else if(运算符包含(currElem))
currState=“Op”;
开关(最后状态+当前状态)
{
“OpUn”案:
案例“OpSt”:
案例“UnUn”://仅带+&-一元运算:需要细化
案例“UnSt”:
案例“晕眩”://仅使用+&-一元运算:需要细化
案例“停止”:
tmpString.Append(currElem);
打破
案例“StS”
public class WaitingForAnyTokenState : State
{
    public override State Process(string token)
    {
        return PushTokenToTokenList(token);
    }

    protected State PushTokenToTokenList(string token)
    {
        Tokens.Add(token);
        if (operators.Any(op => token.EndsWith(op)))
        {
            return new WaitingForAnyTokenState() { Expressions = Expressions, Tokens = Tokens };
        }
        return new WaitingForOperationState() { Expressions = Expressions, Tokens = Tokens };
    }
}
public class WaitingForOperationState : State
{
    public override State Process(string token)
    {
        CloseCurrentExpression(token);
        return PushTokenToTokenList(token); // let's imagine the same method as above is accessible here
    }

    private void CloseCurrentExpression(string token)
    {
        if (!operators.Any(op => token.StartsWith(op)))
        {
            CombineTokensIntoExpression();
            Tokens = new List<string>();
        }
    }
}
private static void Main(string[] args)
{
    var ttea = new TokenToExpressionAggregator();
    foreach (var l in new string[] { "a+", "+1", "+c-", "d", "e", "+d", "z+", "a+" }) {
        ttea.Add(l);
    }
    ttea.EndAggregation();
    foreach (var expression in ttea.CurrentState.Expressions) {
        Console.WriteLine(expression);
    }
}

public class TokenToExpressionAggregator
{
    public State CurrentState { get; set; }
    public TokenToExpressionAggregator()
    {
        CurrentState = new InitialState();
    }
    public void Add(string token)
    {
        CurrentState = CurrentState.Process(token);
    }
    public void EndAggregation()
    {
        CurrentState = new FinalState(CurrentState);
    }
}

public abstract class State
{
    public static string[] operators = new string[] { "+", "-", "*", "/" };
    public List<string> Expressions { get; set; }
    public List<string> Tokens { get; set; }
    public abstract State Process(string token);

    protected State PushTokenToTokenList(string token)
    {
        Tokens.Add(token);
        if (operators.Any(op => token.EndsWith(op)))
        {
            return new WaitingForAnyTokenState() { Expressions = Expressions, Tokens = Tokens };
        }
        return new WaitingForOperationState() { Expressions = Expressions, Tokens = Tokens };
    }

    protected void CombineTokensIntoExpression()
    {
        Expressions.Add(string.Join(" ", Tokens.ToArray()));
    }
}

public class InitialState : WaitingForAnyTokenState
{
    public InitialState()
    {
        Expressions = new List<string>();
        Tokens = new List<string>();
    }
}

public class WaitingForAnyTokenState : State
{
    public override State Process(string token)
    {
        return PushTokenToTokenList(token);
    }
}

public class WaitingForOperationState : State
{
    public override State Process(string token)
    {
        CloseCurrentExpression(token);
        return PushTokenToTokenList(token);
    }

    private void CloseCurrentExpression(string token)
    {
        if (!operators.Any(op => token.StartsWith(op)))
        {
            CombineTokensIntoExpression();
            Tokens = new List<string>();
        }
    }
}

public class FinalState : State
{
    public FinalState(State state)
    {
        Expressions = state.Expressions;
        Tokens = state.Tokens;
        CombineTokensIntoExpression();
        Tokens = null;
    }

    public override State Process(string token)
    {
        return this;
    }
}