Collection_extensions.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* Collection_extensions.cpp
  2. *
  3. * Copyright (C) 1994-2011,2015-2017 David Weenink, 2018 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. djmw 20020812 GPL header
  20. djmw 20040420 Fraction in OrderedOfString_difference should be double.
  21. djmw 20050511 Skip printing unique labels in OrderedOfString
  22. djmw 20061214
  23. djmw 20061214 Changed info to Melder_writeLine<x> format.
  24. djmw 20110304 Thing_new
  25. */
  26. #include "Collection_extensions.h"
  27. #include "NUM2.h"
  28. autoCollection Collection_Permutation_permuteItems (Collection me, Permutation him) {
  29. try {
  30. if (my size != his numberOfElements) {
  31. Melder_throw (me, U"The number of elements are not equal.");
  32. }
  33. autoNUMvector<integer> pos (1, my size);
  34. autoCollection thee = Data_copy (me);
  35. for (integer i = 1; i <= my size; i ++) {
  36. pos [i] = i;
  37. }
  38. /* Dual meaning of array pos: */
  39. /* k < i : position of item 'k' */
  40. /* k >= i : the item at position 'k' */
  41. for (integer i = 1; i <= my size; i++) {
  42. integer ti = pos [i], which = Permutation_getValueAtIndex (him, i);
  43. integer where = pos [which]; // where >= i
  44. Daata tmp = static_cast<Daata> (thy at [i]);
  45. if (i == where) {
  46. continue;
  47. }
  48. thy at [i] = thy at [where];
  49. thy at [where] = tmp;
  50. /* order is important !! */
  51. pos [ti] = where;
  52. pos [where] = ti;
  53. pos [which] = ( which <= i ? i : ti );
  54. }
  55. return thee;
  56. } catch (MelderError) {
  57. Melder_throw (me, U": not permuted.");
  58. }
  59. }
  60. autoCollection Collection_permuteItems (Collection me) {
  61. try {
  62. autoPermutation p = Permutation_create (my size);
  63. Permutation_permuteRandomly_inplace (p.get(), 0, 0);
  64. autoCollection thee = Collection_Permutation_permuteItems (me, p.get());
  65. return thee;
  66. } catch (MelderError) {
  67. Melder_throw (me, U": items not permuted.");
  68. }
  69. }
  70. /****************** class OrderedOfString ******************/
  71. int OrderedOfString_append (StringList me, conststring32 append) {
  72. try {
  73. if (! append) {
  74. return 1; // BUG: lege string appenden??
  75. }
  76. autoSimpleString item = SimpleString_create (append);
  77. my addItem_move (item.move());
  78. return 1;
  79. } catch (MelderError) {
  80. Melder_throw (me, U": text not appended.");
  81. }
  82. }
  83. autoStringList OrderedOfString_joinItems (StringList me, StringList thee) {
  84. try {
  85. if (my size != thy size) {
  86. Melder_throw (U"sizes should be equal.");
  87. }
  88. autoStringList him = Data_copy (me); // FIXME: this copies *all* the data from me, and only the strings from thee
  89. for (integer i = 1; i <= my size; i ++) {
  90. SimpleString hisCategory = his at [i], thyCategory = thy at [i];
  91. integer hisLength = str32len (hisCategory -> string.get()), thyLength = str32len (thyCategory -> string.get());
  92. hisCategory -> string. resize (hisLength + thyLength);
  93. str32cpy (& hisCategory -> string [hisLength], thyCategory -> string.get());
  94. }
  95. return him;
  96. } catch (MelderError) {
  97. Melder_throw (U"Items not joined.");
  98. }
  99. }
  100. autoStringSet StringList_to_StringSet (StringList me) {
  101. try {
  102. autoStringSet you = StringSet_create ();
  103. for (integer i = 1; i <= my size; i ++) {
  104. autoSimpleString item = SimpleString_create (my at [i] -> string.get());
  105. your addItem_unsorted_move (item.move());
  106. }
  107. your sort ();
  108. your unicize ();
  109. return you;
  110. } catch (MelderError) {
  111. Melder_throw (me, U": not converted to StringSet.");
  112. }
  113. }
  114. integer OrderedOfString_getNumberOfDifferences (StringList me, StringList thee) {
  115. integer numberOfDifferences = 0;
  116. if (my size != thy size) {
  117. return -1; // FIXME: this is arbitrary and unexpected
  118. }
  119. for (integer i = 1; i <= my size; i ++) {
  120. if (! Data_equal (my at [i], thy at [i])) { // FIXME: this compares all the data, instead of just the strings
  121. numberOfDifferences ++;
  122. }
  123. }
  124. return numberOfDifferences;
  125. }
  126. double OrderedOfString_getFractionDifferent (StringList me, StringList thee) {
  127. integer numberOfDifferences = OrderedOfString_getNumberOfDifferences (me, thee);
  128. if (numberOfDifferences < 0) {
  129. return undefined;
  130. }
  131. return my size == 0 ? 0.0 : (double) numberOfDifferences / my size;
  132. }
  133. integer OrderedOfString_indexOfItem_c (StringList me, conststring32 str) {
  134. integer index = 0;
  135. autoSimpleString s = SimpleString_create (str);
  136. for (integer i = 1; i <= my size; i ++) {
  137. if (Data_equal (my at [i], s.get())) {
  138. index = i;
  139. break;
  140. }
  141. }
  142. return index;
  143. }
  144. void OrderedOfString_initWithSequentialNumbers (StringList me, integer n) {
  145. for (integer i = 1; i <= n; i ++) {
  146. my addItem_move (SimpleString_create (Melder_integer (i)));
  147. }
  148. }
  149. void OrderedOfString_changeStrings (StringList me, char32 *search, char32 *replace, int maximumNumberOfReplaces, integer *nmatches, integer *nstringmatches, bool use_regexp) {
  150. regexp *compiled_search = nullptr;
  151. try {
  152. Melder_require (search, U"The search string should not be empty.");
  153. Melder_require (replace, U"The replace string should not be empty.");
  154. if (use_regexp) {
  155. compiled_search = CompileRE_throwable (search, 0);
  156. }
  157. for (integer i = 1; i <= my size; i ++) {
  158. SimpleString ss = my at [i];
  159. integer nmatches_sub;
  160. autostring32 r = use_regexp ?
  161. STRreplace_regex (ss -> string.get(), compiled_search, replace, maximumNumberOfReplaces, & nmatches_sub) :
  162. STRreplace (ss -> string.get(), search, replace, maximumNumberOfReplaces, & nmatches_sub);
  163. /*
  164. Change without error.
  165. */
  166. ss -> string = r.move();
  167. if (nmatches_sub > 0) {
  168. *nmatches += nmatches_sub;
  169. (*nstringmatches) ++;
  170. }
  171. }
  172. if (use_regexp) {
  173. free (compiled_search);
  174. }
  175. } catch (MelderError) {
  176. if (use_regexp) {
  177. free (compiled_search);
  178. }
  179. Melder_throw (U"Replace not completed.");
  180. }
  181. }
  182. integer OrderedOfString_isSubsetOf (StringList me, StringList thee, integer *translation) { // ?? test and give number
  183. integer nStrings = 0;
  184. for (integer i = 1; i <= my size; i ++) {
  185. if (translation) {
  186. translation [i] = 0;
  187. }
  188. for (integer j = 1; j <= thy size; j ++)
  189. if (Data_equal (my at [i], thy at [j])) {
  190. if (translation) {
  191. translation [i] = j;
  192. }
  193. nStrings++; break;
  194. }
  195. }
  196. return nStrings;
  197. }
  198. void OrderedOfString_removeOccurrences (StringList me, conststring32 search, bool use_regexp) {
  199. if (! search) {
  200. return;
  201. }
  202. for (integer i = my size; i >= 1; i --) {
  203. SimpleString ss = my at [i];
  204. if ( (use_regexp && strstr_regexp (ss -> string.get(), search)) ||
  205. (!use_regexp && str32str (ss -> string.get(), search))) {
  206. my removeItem (i);
  207. }
  208. }
  209. }
  210. /* End of file Collection_extensions.cpp */