0

I am looking for a data structure that allows duplicates and maintains insertion order so that if given file input of : a + a + b = c

So that once correctly split, I will get: {a,+,a,+,b,=,c}

This data structure also needs to allow for removal and insertion in the correct order, for example if I replace a with d, I should get {d,+,d,+,b,=,c}.

Finally the structure must also be able to recognize which items are before or after a certain item. E.g. the item directly before = is b and directly after is c.

I am aware that lists allow duplicates and some lists maintain insertion order, but I am unsure as to which will allow me to achieve my goals.

If you are aware of a structure the will achieve all of the above, please provide the syntax for creating such a structure.

Regards

Digitalwolf
  • 447
  • 2
  • 9
  • 20
  • Haven't tried it yet. Never knew such a thing existed. Will it be able to do everything I want? – Digitalwolf Jan 23 '13 at 11:04
  • I think you need a balanced tree data structure. – Subhrajyoti Majumder Jan 23 '13 at 11:11
  • I could definitely use the "branching factor" is there a link to an example that you can provide me, and what is syntax for creating such a structure? – Digitalwolf Jan 23 '13 at 11:14
  • 1
    There are some basic implementation is availabe - [link 1](http://www.codeproject.com/Articles/53366/Binary-Trees-in-Java) [link 2](http://stackoverflow.com/questions/8876406/binarytree-implementation-in-java), but you must extends what you need more. – Subhrajyoti Majumder Jan 23 '13 at 11:18

2 Answers2

3

Seems ArrayList with ListIterator would fulfill your requirements, for sample usage, see: http://www.java2s.com/Code/Java/Collections-Data-Structure/BidirectionalTraversalwithListIterator.htm

Peter Butkovic
  • 11,143
  • 10
  • 57
  • 81
  • My file input isn't always going to be the same, so the items I will have to remove won't always be in the same order so I am not sure if iterating through the data is the best option. Ideally I would like to say **if(list.contains("a"){ replace a with d}** to get the output I demonstrated in my question. – Digitalwolf Jan 23 '13 at 11:11
  • It sounds like your problem is coming up with a algorithm rather than finding a suitable data structure. A `List` implementation with a `ListIterator` should fulfill your stated requirements. If not, you should update the question. – Gustav Karlsson Jan 23 '13 at 11:16
  • Was just looking for a data structure that could store duplicates and maintained insertion order. I have used an arrayList before and because my file input is highly varied, all I was able to do is replace value, but those values kept getting put at the end of the list. Is it possible to do what I have explained in my question with a listIterator, if the input is highly varied? – Digitalwolf Jan 23 '13 at 11:25
  • 1
    Then `List` is your structure. You can use `Collections` to replace stuff: `Collections.replaceAll(myArray, 'a', 'd')`. – Gustav Karlsson Jan 23 '13 at 11:34
1

Assuming performance is enough of a concern, to not use one of the simple Java List implementation (because you want to avoid iterating over the whole list to search for items during replacement), then you would need a maintain two data structures, one to keep track of the order of tokens and one as an index of token positions for replacement.

So, something like (I haven't run this through a compiler, so expect typos):

class TokenList
{
  List<String> tokens;
  Map<String,List<Integer>> tokenIndexes= new HashMap<String,List<Integer>>();

  TokenList(Iterable<String> tokens)
  {
    this.tokens = new ArrayList<String>(tokens);
    for (int i = 0; i < this.tokens.size(); i++)
    {
      String token = this.tokens.get(i);
      List<Integer> indexes = tokenIndexes.get(token);
      if (indexes == null)
      {
        index = new List<Integer>();
        tokenIndexes.put(token, indexes);
      }
      indexes.add(index);
    }
  }

  void replace(String oldToken, String newToken)
  {
    List<Integer> indexes = tokenIndexes.remove(oldToken);
    if (indexes == null)
      throw new IllegalArgumentException("token doesn't exist: " + oldToken);
    for (int index : indexes)
      tokens.set(i, newToken);
    tokenIndexes.put(newToken, indexes);
  }
}

This structure makes the assumption that tokens will not change index once created (the tokenIndex map would need to be recreated, which is a relatively costly operation).

SimonC
  • 6,590
  • 1
  • 23
  • 40