当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - Can't find specific element in LinkedListNode

问题描述:

Let's start from the beginning. I have string:

LOAD B

STORE $2

LOAD A

MPY =5.01E+10

ADD $2

What looks in code this way:

string code = "LOAD B\r\nSTORE $2\r\nLOAD A\r\nMPY =5.01E+10\r\nADD $2\r\n";

And transform it into LinkedListNode this way:

IEnumerable<KeyValuePair<string, string>> pairs =

code.Split(new string[] { Environment.NewLine },

StringSplitOptions.RemoveEmptyEntries)

.Select(x => x.Split(new[] { ' ' },

StringSplitOptions.RemoveEmptyEntries))

.Select(x => new KeyValuePair<string, string>(x[0], x[1]));

var data = new LinkedList<KeyValuePair<string, string>>(pairs);

Element of this list is KeyValuePair containing left and right parts of every line of string. Now is main part. I have to find in this list sequence "LOAD a => STORE b" where a and b can be any string. After this i have to find in next part of my list all elements with key == b (in my example b = "$2") and replace b to a so here would be:

LOAD B

STORE B //changed

LOAD A

MPY =5.01E+10

ADD B //changed

So, here is my code to this:

string a;

string b;

for(LinkedListNode<KeyValuePair<string, string>> it = data.First; it != null; it = it.Next) {

if(it.Next != null) {

if ((it.Value.Key == "LOAD") &&

(it.Next.Value.Key == "STORE")) {

a = it.Value.Value;

b = it.Next.Value.Value;

for(LinkedListNode<KeyValuePair<string, string>>

current = it; current != null;

current = current.Next) {

//remove found element and replace it

if (current.Value.Value == b) {

data.AddAfter(current, new KeyValuePair<string, string> (current.Value.Key, a));

data.Remove(current);

}

}

}

}

}

After i run it i get this:

LOAD B

STORE B //changed

LOAD A

MPY =5.01E+10

ADD $2 //still the same

I tryed to debug it and figured out, that if (current.Value.Value == b) don't actually match ADD $2 in some reason. What can be wrong?

This is how you can see what is in list:

foreach (KeyValuePair<string, string> pair in data) {

Console.WriteLine("Key: {0} - Value: {1}", pair.Key, pair.Value);

}

网友答案:

I think the reason your code is broken, is that when you remove current from the linked list in your inner loop, the values for Next and Previous for the LinkedListNode<KeyValuePair<string, string>> get set to null. Hence your iteration in the inner loop terminates as soon as you make any replacement in the list. Check those values in your debugger immediately after data.Remove(current) to see what I mean.

I'd use slightly different patterns in trying to modify the data as you describe. When I had a quick go at hacking up a solution in LinqPad, I came up with this:

var newData = new LinkedList<KeyValuePair<string, string>>();
Nullable<KeyValuePair<string,string>> previousNode = null;
string valueToFind = "$2";
string valueToReplace = null;
foreach(var currentNode in data)
{
    if(previousNode != null)
    {
        if(previousNode.Value.Key == "LOAD" && currentNode.Key == "STORE")
        {
            valueToReplace = previousNode.Value.Value;
        }
    }

    if(valueToReplace != null && currentNode.Value == valueToFind)
    {
        var newValue = new KeyValuePair<string,string>(currentNode.Key, valueToReplace);
        newData.AddLast(newValue);
    }
    else
    {
        newData.AddLast(currentNode);
    }

    previousNode = currentNode;
}

Rather than modifying the existing list in place, I'm creating a copy. I find it easier to read code where it's not modifying the data structure that's being iterated over. Plus, I think this gets rid of your bug.

So I'm starting off with a null value for "what was the previous node in the list", and iterating through the entire list with a foreach(). If there is a previous node to look at, then the code checks to see if it was "LOAD" and the current node is "STORE". If so, it takes a copy of the parameter for the "LOAD" operation as the "value to replace".

Then, if we have a value to replace and the current node's Value is equal to the value we need to find ("$2" in your example) the code creates a new list node with the replacement made. Otherwise it just inserts the current node as-is into the new list.

That gives the following output for me:

Which I think is what you were after?

网友答案:

Finally found solution:

if (current.Value.Value == b) { 
    current.Value = new KeyValuePair<string, string> (current.Value.Key, a);
}

If you need to replace value of list element you just need:

LinkedListNode.Value = new value;
分享给朋友:
您可能感兴趣的文章:
随机阅读: