0

I have a very basic java code . There are 2 hash tables :

Hashtable<String, ArrayList<tuple> > htDOC1 = new Hashtable<String, ArrayList<tuple> >();
    Hashtable<String, ArrayList<tuple> > htDOC2 = new Hashtable<String, ArrayList<tuple> >();

Each key represents a word as you can see String.Then i have a method which takes 2 hash tables as a parameters :

 public static void CheckCheaters(Hashtable<String, ArrayList<tuple> > doc1 ,Hashtable<String, ArrayList<tuple> > doc2 ){

    Set <String> keysDoc1 =  doc1.keySet();
    Set <String> keysDoc2 =  doc2.keySet();

}

in the KeysDoc1 I've stored the keys of the first hash table , in the keysDoc2 I've stored the keys of the second hash table.

I want to loop over the two sets and check if the first 5 elements of the keysDoc1 are equal to the first 5 elements of keysDoc2 , then check the next 5 ..etc

could you please guide me ? i hope i was clear , i tried my best.

EDIT

 public static boolean CheckCheaters(SortedMap<String, ArrayList<tuple> > doc1 ,SortedMap<String, ArrayList<tuple> > doc2 ){

     boolean checking=true;
      Set<String> keysDoc1 =  doc1.keySet();
      Set<String> keysDoc2 =  doc2.keySet();

      int count = 0;
      for(String s : keysDoc1)
      {
          if(keysDoc2.contains(s))
              count++;
      }
      if(count>5) {
          checking=true;
      }
      else {
          checking=false;
      }
      return checking;

     }
 }
  • 2
    Hashtables are unordered. – SLaks Dec 18 '17 at 22:21
  • @SLaks Really ! omg what data structure should i use ? – yousef aqra Dec 18 '17 at 22:24
  • Take a look at: https://stackoverflow.com/a/663396/3179169 – clinomaniac Dec 18 '17 at 22:27
  • You can use a LinkedHashMap to have insert order preserved or a TreeMap to keep ascending order as defined by the comparator. – clinomaniac Dec 18 '17 at 22:30
  • well , I've used the TreeMap how can i check the elements of the both sets ? @clinomaniac please could you show me with code sample..? – yousef aqra Dec 18 '17 at 22:37
  • Post the code of what you have tried so far. – clinomaniac Dec 18 '17 at 22:38
  • @clinomaniac , I edited the post , u can see what I've tried. – yousef aqra Dec 18 '17 at 22:47
  • In your code, you are checking if the elements from the first set exist in the second set. Is that what you want to check for? What needs to happen after the first 5 elements have been checked and found? Or not found? What should it return and till when should it keep checking? – clinomaniac Dec 18 '17 at 22:52
  • this what I've done , but i want is to check 5 elements as i mentioned in the post , if the 5 elements are equals i would like to increment the value of the counter by 1 ... etc @clinomaniac – yousef aqra Dec 18 '17 at 22:58
  • What should it do if they are not equal? Also, the method returns a boolean so what do you need to do with the count after all comparisons are done? – clinomaniac Dec 18 '17 at 22:59
  • @clinomaniac if the value of the counter was more than specific number , that means there is a big similarity between the tow documents . each documents words inside one of the hashtables – yousef aqra Dec 18 '17 at 23:14
  • @yousefaqra Hello, just dropping by to advice you to use clino's answer. It checks all elements instead of the first five. I hope we've managed to help.. have a good day! – oBit91 Dec 18 '17 at 23:19
  • I have posted a solution that might help. To check how similar the sets are, I would recommend using a different approach. Checking a few elements at a time when only one might be different can lead to things showing as different even thought they might be off by 1. Take a look at Collections.retainAll and such methods to see how you can use those to better find out if the sets are similar or not. – clinomaniac Dec 18 '17 at 23:24
  • thank u dude u helped me a lot , i'm just trying to learn .. 3> @clinomaniac – yousef aqra Dec 19 '17 at 01:26

2 Answers2

0

You can use a LinkedHashMap, which means that the HashMap elements are linked through a double sided LinkedList. For that reason, the elements are sorted by their order of input.

For example:

public static void foo() {
    HashMap<String, ArrayList<tuple>> htDOC1 = new LinkedHashMap<String, 
                  ArrayList<tuple>>();
    HashMap<String, ArrayList<tuple>> htDOC2 = new LinkedHashMap<String, 
                  ArrayList<tuple>>();
    System.out.println(CheckCheaters(htDOC1, htDOC2));
}

public static int CheckCheaters(HashMap<String, ArrayList<tuple>> doc1, 
                                    HashMap<String, ArrayList<tuple>> doc2){
    if (doc1.size() < 5 || doc2.size() < 5) {
        System.out.println("Not enough elements");
        return 0;
    }
    Iterator<String> doc1Keys = doc1.keySet().iterator();
    Iterator<String> doc2Keys = doc2.keySet().iterator();
    int i = 0;
    int counter = 0;
    int numOfEquals = 0;
    int limit = min(doc1.size(), doc2.size());
    while (doc1Keys.hasNext() != null && doc2Keys.hasNext() != null
                                      && i < limit ){
        if (Objects.equals(doc1Keys.next(), doc2Keys.next())
            counter++;

        if (i % 5 == 0) {
            if (counter == 5)
                numOfEquals++;
            counter = 0;
        }
        i++;
    }
    return numOfEquals;
}

edit - I've reworked the code to compare every sequence of 5 elements (excluding congruence elements).

Objects.equals(a,b) vs a.equals(b)

notice that I've used Objects.equals(a, b) instead of a.equals(b). The difference is that the latter fails in case one of the arguments is null. Keep that in mind when working with strings (whether you want to treat null pointers differently).

More details on LinkedHashMap here.

oBit91
  • 398
  • 1
  • 12
  • 1
    _"the HashMap is implemented as a LinkedList"_ -- this is incorrect. It is still a `HashMap` but the nodes are _also_ in a `LinkedList` in insertion order. – Jim Garrison Dec 18 '17 at 22:58
0

This is based on the comments. Let me know if it is not what you need and I'll try to see what I can help with.

    Set<String> keysDoc1 = doc1.keySet();
    Set<String> keysDoc2 = doc2.keySet();
    if (keysDoc1.size() != keysDoc2.size()) {
        // Different number of elements in both sets.
        return false;
    }
    int checkCount = 0, count5 = 0;
    for (int i = 0; i < keysDoc1.size(); i++) {
        if (!Objects.equals(keysDoc1.toArray()[i], keysDoc2.toArray()[i]))
            checkCount++;
        if (i % 5 == 0) {
            if (checkCount == 5) {
                count5++;
            }
            checkCount = 0;
        }

    }
    System.out.println(count5);
    return true;

Not really sure what the point of count will be unless you need to use it for something later in the code.

The checkCount will see if 5 elements are correct in each 5 it checks. If 5 are matching, then it will increment the count5 variable.

clinomaniac
  • 2,200
  • 2
  • 17
  • 22