Groovy string match 90% (ignore letter casing) - grails

I need to write a Groovy function to check if two given strings match at least 90%. I just wanted to know if anyone knew of an already existent such utility method that I could use in a Grails project. I haven't really written the method yet but ideally this is how it would work:
def doStringsMatch(String str1, String str2) {
if (str1 and str2 match at least 90% or
str1 appears in str2 somewhere or
str2 appears in str1 somewhere)
return true
else
return false
}
Thanks

This is a groovy implementation of Levenshtein distance, basically it returns a percentage of how similar the two strings appear to be. 0 means they are completely different and 1 means they are the exact same. This implementation is case insensitive.
private double similarity(String s1, String s2) {
if (s1.length() < s2.length()) { // s1 should always be bigger
String swap = s1; s1 = s2; s2 = swap;
}
int bigLen = s1.length();
if (bigLen == 0) { return 1.0; /* both strings are zero length */ }
return (bigLen - computeEditDistance(s1, s2)) / (double) bigLen;
}
private int computeEditDistance(String s1, String s2) {
s1 = s1.toLowerCase();
s2 = s2.toLowerCase();
int[] costs = new int[s2.length() + 1];
for (int i = 0; i <= s1.length(); i++) {
int lastValue = i;
for (int j = 0; j <= s2.length(); j++) {
if (i == 0)
costs[j] = j;
else {
if (j > 0) {
int newValue = costs[j - 1];
if (s1.charAt(i - 1) != s2.charAt(j - 1))
newValue = Math.min(Math.min(newValue, lastValue),
costs[j]) + 1;
costs[j - 1] = lastValue;
lastValue = newValue;
}
}
}
if (i > 0)
costs[s2.length()] = lastValue;
}
return costs[s2.length()];
}

Related

Cs50 speller: not recognising any incorrect words

I'm currently working on the CS50 Speller function. I have managed to compile my code and have finished a prototype of the full program, however it does not work (it doesn't recognise any mispelled words). I am looking through my functions one at a time and printing out their output to have a look at what's going on inside.
// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
char word[LENGTH + 1];
int counter = 0;
FILE *dicptr = fopen(dictionary, "r");
if (dicptr == NULL)
{
printf("Could not open file\n");
return 1;
}
while (fscanf(dicptr, "%s", word) != EOF)
{
printf("%s", word);
node *n = malloc(sizeof(node));
if (n == NULL)
{
unload();
printf("Memory Error\n");
return false;
}
strcpy(n->word, word);
int h = hash(n->word);
n->next = table[h];
table[h] = n;
amount++;
}
fclose(dicptr);
return true;
}
From what I can see this works fine. Which makes me wonder if the issue is with my check function as shown here:
bool check(const char *word)
{
int n = strlen(word);
char copy[n + 1];
copy[n] = '\0';
for(int i = 0; i < n; i++)
{
copy[i] = tolower(word[i]);
printf("%c", copy[i]);
}
printf("\n");
node *cursor = table[hash(copy)];
while(cursor != NULL)
{
if(strcasecmp(cursor->word, word))
{
return true;
}
cursor = cursor->next;
}
return false;
}
If someone with a keener eye can spy what is the issue I'd be very grateful as I'm stumped. The first function is used to load a the words from a dictionary into a hash table\linked list. The second function is supposed to check the words of a txt file to see if they match with any of the terms in the linked list. If not then they should be counted as incorrect.
This if(strcasecmp(cursor->word, word)) is a problem. From man strcasecmp:
Return Value
The strcasecmp() and strncasecmp() functions return an
integer less than, equal to, or greater than zero if s1 (or the first
n bytes thereof) is found, respectively, to be less than, to match, or
be greater than s2.
If the words match, it returns 0, which evaluates to false.

Add char in between string

I want a function which takes string as an argument and add any char between string after every 3 letters.
For example:
func("11111111"){}
will return:
11,111,111
If I understand your question correctly
import 'dart:math' as math;
String convertFun(String src, String divider) {
String newStr = '';
int step = 3;
for (int i = 0; i < src.length; i += step) {
newStr += src.substring(i, math.min(i + step, src.length));
if (i + step < src.length) newStr += divider;
}
return newStr;
}
UPD:
(for separating symbols from end, not from beginning)
String convertFun(String src, String divider) {
String newStr = '';
int step = 3;
for (int i = src.length - 1; i >= 0; i -= step) {
String subString ='';
if (i > 3) {
subString += divider;
}
subString += src.substring( i < step ? 0 : i - step, i);
newStr = subString + newStr;
}
return newStr;
}
String func(String str){
RegExp exp = RegExp(r".{1,3}");
Iterable<Match> matches = exp.allMatches(str);
List<dynamic> list = [];
matches.forEach((m)=>list.add(m.group(0)));
return list.join(',');
}
Try this:
String myFunction(String str, String separator) {
String tempString = "";
for(int i = 0; i < str.length; i++) {
if(i % 3 == 0 && i > 0) {
tempString = tempString + separator;
}
tempString = tempString + str[i];
}
return tempString;
}
And use it for example, like this:
Text(myFunction("111111111", ","))
The other solutions work for your stated problem, but if you are looking to add commas in numbers (as in your example), you'll want to add the comma's from the right to the left instead.
ie: 12345678 you would want 12,345,678 not 123,456,78
String convertFun(String src, String divider) {
StringBuilder newStr = new StringBuilder();
int step = 3;
for (int i = src.length(); i > 0; i -= step) {
newStr.insert(0, src.substring( i < step ? 0 : i - step, i));
if (i > 3) {
newStr.insert(0, divider);
}
}
return newStr.toString();
}

Swap 2 nodes of a single linked list. i have the program. I need to ask where its wrong

I wrote the following program. The swap is working fine if i debug it. However i am not able to return the complete linked list. It is changing the head as well. what is wrong?
public static Node<Integer> swapElementsAtiAndj(Node<Integer> head, int i, int j)
{
Node<Integer> temp= head;
Node<Integer> prev1 = temp;
Node<Integer> prev2 = temp;
Node<Integer> toSwap1 = temp;
Node<Integer> toSwap2 = temp;
int count =0;
int pos1 =i;
int pos2 =j;
if(i>j) {
pos1 = j;
pos2 =i;
}
while (count !=pos1) {
prev1 = toSwap1;
toSwap1 = toSwap1.next;
prev2 = prev1;
toSwap2 = toSwap1;
count++;
}
while(count != pos2) {
prev2 = toSwap2;
toSwap2 = toSwap2.next;
count++;
}
temp.data = toSwap1.data;
temp.next = toSwap2.next;
toSwap2.next = toSwap1.next;
prev2.next = temp;
prev1.next = toSwap2;
return head;
}
Yes, your head is getting modified at
temp.next = toSwap2.next;
Because temp is pointing at head. Here is how you can fix it:
First of all,
prev2 = prev1;
toSwap2 = toSwap1;
can be written outside of while loop.
Now, after second while loop toSwap1 and toSwap2 are pointing at elements to be swapped.
// Swap prev
prev1.next = toSwap2;
prev2.next = toSwap1;
// Store toSwap2's next in temp
temp = toSwap2.next;
// Set toSwap2's next to toSwap1's next
toSwap2.next = toSwap1.next;
// Set toSwap1's next to old toSwap2's next (i.e temp)
toSwap1.next = temp;
// Return
return head;

How to fix the row value mapping Index was out of range. Must be non-negative and less than the size of the collection c#

I am getting the error out of range object[,]
string MissingCompanies="";
List<string> cmp = new List<string>();
cmp = sr.CompanyCode();
int count=0;
if (DataRange!=null)
{
while (DataRange != null)
{
string code;
bool match;
match = false;
code = cmp[count]; //getting error here**
for (int dr = 1; dr <= DataRange.GetUpperBound(0); dr++)
{
if (code.Equals(DataRange[dr, 1]))
{
match = true;
break;
}
}
count++;
if (!match)
{
MissingCompanies = MissingCompanies + "," + code;
}
I'm getting error: code=cmp[count] -- index has out of range.
I'd be grateful for any help with this.

not all code return a value

private static long CalculateScore(byte chances, long millisec) { int score; byte num1 = chances++; byte num2 = (byte)10; byte num3 = (byte)10; switch (Program.currLevelIndex) { case (byte)7: num2 = (byte)10; break; case (byte)11: num2 = (byte)20; break; case (byte)15: num2 = (byte)40; break; }
if ((int)chances >= 1 && (int)chances <= 3)
num1 = (byte)40;
else if ((int)chances >= 4 && (int)chances <= 6)
num1 = (byte)20;
else if ((int)chances > 7)
num1 = (byte)10;
if (millisec > 480000L)
num3 = (byte)10;
else if (millisec >= 240000L && millisec <= 480000L)
num3 = (byte)20;
else if (millisec < 240000L)
num3 = (byte)40;
try
{
score = Convert.ToInt32((int)num2 * (int)num1 * (int)num3);
}
catch
{
score=0;
}
Console.SetCursorPosition(Program.x, Program.y);
Console.Write("Your Score was: " + score);
}`
The error is CalculateScore & I can't find the mistake. this is a method is to work ou Help is nedeed.
private static long CalculateScore expects a return value of type long, but your method does not return anything.
Add the following to the end of the method.
return score;
And you might want to change the return type to int or the score variable to long
private static int CalculateScore(byte chances, long millisec)
{
int score;
byte num1;
Or
private static long CalculateScore(byte chances, long millisec)
{
long score;
byte num1;
You specified that the function will return a value of type long, but there is no return statement returning a value at the end of the function
You need to add
return score;
as score is the result of the calculation

Resources