예제 #1
0
// Score function
int calculate_score( const ID& a, const ID& b ) {
  int len_a = a.size();
  int len_b = b.size();
  int s = 0;
  int L = (len_a < len_b) ? len_a:len_b;
  int dL = abs(len_a - len_b);

  s = dL * (dL + 1) / 2;
  for (int i = L-1; i >= 0; --i) {
    s += ((a[i] == b[i]) ? 0:(L-i));
  }

  return s;
}
예제 #2
0
void AccountMap::Existing( const ID& id ) {
  vector<ID*> list_id(10);
  vector<int> list_score(10);
  int target_score = 1;
  int num_compare = id.size() - 1;
  int score_temp;
  int size = 0;
  SkipListNode* front;
  SkipListNode* back;

  // Set the iteratro go to front and back
  Find(id, front);
  back = Next(front);

  // Stop when get enough data, or two iterator are at the end
  while ((front->data_id.front() != '!' || back->data_id.front() != '{') && \
         (size != 10 || list_score[10] > target_score)
  ) {

    // First move front iteratro
    while (front->data_id.front() != '!' && \
          (num_compare == 0 || id.compare(0, num_compare, front->data_id, 0, num_compare) == 0)
    ) {
      score_temp = calculate_score(id, front->data_id);
      if (size < 10 || score_temp <= list_score.back()) {
        insert_id_to_vector(list_id, list_score, 0, front->data_id, score_temp, size);
      }
      front = Previous(front);
    }
    
    // If get enough data, stop
    if (size == 10 && list_score[10] <= target_score) break;
    
    // If data is not enough, move back iterator
    while (back->data_id.front() != '{' && \
          (num_compare == 0 || id.compare(0, num_compare, back->data_id, 0, num_compare) == 0)
          ) {
      score_temp = calculate_score(id, back->data_id);
      if (size < 10 || score_temp < list_score.back()) {
        insert_id_to_vector(list_id, list_score, 1, back->data_id, score_temp, size);
      }
      back = Next(back);
    }

    // Add the tolerent to score, adjust the number of string to compare
    target_score += 1;
    if (num_compare > 0) num_compare -= 1;
  }

  // Print the result
  bool comma = false;
  for (int i = 0; i < (int)list_score.size(); ++i) {
    if (comma) {
      cout << ',';
    }
    cout << *(list_id[i]);
    comma = true;
  }

}
예제 #3
0
// Return whether two char* is matching, a may have wildcard
bool match_recursion( const ID& a, const ID& b, int pa, int pb ) {
  if (pa == (int)a.size() && pb == (int)b.size()) {
    return true;
  }

  if (a[pa] == '?' || a[pa] == b[pb]) {
    return match_recursion(a, b, pa+1, pb+1);
  }

  if (a[pa] == '*' && pa+1 != (int)a.size() && pb == (int)b.size()) {
    return false;
  }

  if (a[pa] == '*') {
    return match_recursion(a, b, pa+1, pb) || match_recursion(a, b, pa, pb+1);
  }

  return false;
}
예제 #4
0
// Change text to the next one accrording to dictionary order
// The part that can be changed is between string[min_len] and string[max_len-1]
// Retrun true if succeed, false if the next one doesn't exist
bool next_string( ID& text, int min_len, int max_len ) {
  if ((int)text.size() < max_len) {
    text.append("0");
    return true;
  }

  while (text.back() == 'z') {
    text.pop_back();
    if ((int)text.size() == min_len) {
      return false;
    }
  }

  char c = text.back();
  if (c == '9') {
    text.back() = 'A';
  } else if (c == 'Z') {
    text.back() = 'a';
  } else {
    text.back() += 1;
  }
  return true;
}
예제 #5
0
void AccountMap::Unused( const ID& id ) {
  int target_score = 1;
  int len = id.size();
  int min_len = len - 1;
  int max_len = (len+1 < 100) ? (len+1):100;
  int output = 0;
  bool comma = false;
  SkipListNode* temp;
  
  string test;
  if (min_len == 0) {
    test = "0";
  } else {
    test = id.substr(0, min_len);
  }

  while (output < 10) {
    if (calculate_score(test, id) == target_score && !Find(test, temp)) {
      if (comma) {
        cout << ',';
      }
      cout << test;
      comma = true;
      output += 1;
    } 
    if (!next_string(test, min_len, max_len)) {
      target_score += 1;
      min_len = (min_len == 0) ? 0:(min_len-1);
      if (max_len != 100 &&
          (max_len+1-len+1)*(max_len+1-len)/2 <= target_score)
      {
        max_len += 1;
      }
      if (min_len == 0) {
        test = "0";
      } else {
        test = id.substr(0, min_len);
      }
      
    }
  }

}