File: aststring.cpp

package info (click to toggle)
minizinc 2.9.3%2Bdfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,620 kB
  • sloc: cpp: 74,682; ansic: 8,541; python: 3,322; sh: 79; makefile: 13
file content (82 lines) | stat: -rw-r--r-- 2,141 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */

/*
 *  Main authors:
 *     Guido Tack <guido.tack@monash.edu>
 */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <minizinc/aststring.hh>

#include <iostream>
#include <vector>

#ifndef HAS_MEMCPY_S
namespace {
void memcpy_s(char* dest, size_t /*size*/, const char* src, size_t count) {
  memcpy(dest, src, count);
}
}  // namespace
#endif

namespace MiniZinc {

int ASTString::levenshteinDistance(const ASTString& other) const {
  size_t m = size();
  size_t n = other.size();
  const char* s = c_str();
  const char* t = other.c_str();
  assert(m > 0);
  assert(n > 0);

  // dynamic programming matrix
  std::vector<int> dp0(n + 1);
  std::vector<int> dp1(n + 1, 0);
  // initialise matrix
  for (int i = 0; i <= n; i++) {
    dp0[i] = i;
  }

  for (int i = 1; i <= m; i++) {
    dp1[0] = i;
    for (int j = 1; j <= n; j++) {
      int del = dp0[j] + 1;
      int ins = dp1[j - 1] + 1;
      int sub = dp0[j - 1] + static_cast<int>(s[i - 1] != t[j - 1]);
      dp1[j] = std::min(del, std::min(ins, sub));
    }
    std::swap(dp0, dp1);
  }
  return dp0[n];
}

ASTStringData::Interner& ASTStringData::interner() {
  static Interner _interner;
  return _interner;
}

ASTStringData::ASTStringData(const std::string& s)
    : ASTChunk(s.size() + sizeof(size_t) + 1, ASTNode::NID_STR) {
  memcpy_s(_data + sizeof(size_t), s.size() + 1, s.c_str(), s.size());
  *(_data + sizeof(size_t) + s.size()) = 0;
  std::hash<std::string> h;
  reinterpret_cast<size_t*>(_data)[0] = h(s);
}

ASTStringData* ASTStringData::a(const std::string& s) {
  if (s.empty()) {
    return nullptr;
  }
  auto it = interner().find({s.c_str(), s.size()});
  if (it != interner().end()) {
    return it->second;
  }
  auto* as = static_cast<ASTStringData*>(alloc(1 + sizeof(size_t) + s.size()));
  new (as) ASTStringData(s);
  interner().emplace(std::make_pair(as->c_str(), as->size()), as);
  return as;
}
}  // namespace MiniZinc