Comparing two strings
-
Hey guys, I've recently been messing around with c++ and more recently, qt. I don't have very much experience with this stuff so please bear with me. I'm trying to make a thing that compares two character arrays, and if at least 60% of the words in one, is similar to the other, it will return true. I have made this in the arduino, but I'm trying to switch it to c++. It's pretty similar, but there is some differences. The problem is, it is saying something to the effect of not being able to convert from constant character to character. As you will see, I've tried messing around with the parameters, and was only able to narrow it down to four errors. Any ideas what it wrong? Thanks in advance.
//this is my original arduino code boolean areStringsSimilar(const char* x, const char* y){ float percentage = 0.0; int wordsInY = howManyWords(y); for (int i = 1; i<= wordsInY; i++){ //grabs first word from y and looks to see if it is in x. Then grabs second and so on. if(strstr(x, subStr(y, " ",i))){ percentage++; } } if(percentage/(float)wordsInY* 100 >= 60){//find percentage of words matched. If it's more than 60% return true return true; } return false; } //gets 1 word from a string and returns it //I didn't make this function so I don't really know how it works. In the new one I made my own. const char* subStr (const char* str, char *delim, int index) { char *act, *sub, *ptr; static char copy[MAX_STRING_LEN]; int i; // Since strtok consumes the first arg, make a copy strcpy(copy, str); for (i = 1, act = copy; i <= index; i++, act = NULL) { //Serial.print("."); sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; } return sub; } //returns how many words in a string int howManyWords(const char* y){ int counter = 1; char ch; while(ch = *y++){ if(ch == ' '){ counter++; } } return counter; }
//the qt c++ code //finds how many words in a char array int Widget::howManyWords(char* array){ char* arrayCopy = array; int counter = 1; char ch; while(ch = *arrayCopy++){ if(ch == ' '){ counter++; } } return counter; } //returns word depending on the index from a char array. (e.g. yellow fellow pillow, index of one would return yellow char Widget::getWord(char* array, int index){ int counter = index = 1; char word, ch; char* arrayCopy = array; //check and see if they're trying to get first word if(index == 1){ while(ch = *arrayCopy++){ if(ch == ' '){ break; } word += ch; } } else{ while(ch = *arrayCopy++){ if(ch == ' '){ if(++counter == index){ ch = *arrayCopy++; while(ch != ' '){ word += ch; ch = *arrayCopy++; } } } } } return ch; } bool Widget::areStringsSimilar(char testChar, char compareChar){ float percentage = 0.0; int wordsInTest = howManyWords(testChar); for (int i = 1; i <= wordsInTest; i++){ if(strcmp(getWord(testChar, 1), compareChar)){ percentage++; } } if(percentage/(float)wordsInTest * 100 >= 60){ return true; } return false; }
-
The problem can be solved using some classes in QT. What I am about to write is not the finest piece of code but nonetheless is the first brutal approach to the solution. It can be refined, and I am leaving this as an effort from your side.
bool areStringsSimilar(const char *x, const char *y)
{
qreal percentage = 0;
QString xStr(x);
QString yStr(y);
QStringList xList, yList;
// let us not continue if any of the two char arrays is empty
if (xStr.isEmpty() || yStr.isEmpty()) {
return false;
}
// xList, and yList are going to contain the words in the two QString classes that represent the the two char arrays
xList = xStr.split(' '); // space is the delimiter of a word
yList = yStr.split(' '); // get all the words on *y// now let us do the brutal comparaison for (int i = 0; i < xList.count(); i++) { // if the current word is anywhere is the yList if (yList.contains(xList.at(i), Qt::CaseInsensitive)) { percentage ++; } } return ((percentage/yList.count()) * 100 > 60.00) ? true : false;
}
Good Luck.
-
Hey guys, I've recently been messing around with c++ and more recently, qt. I don't have very much experience with this stuff so please bear with me. I'm trying to make a thing that compares two character arrays, and if at least 60% of the words in one, is similar to the other, it will return true. I have made this in the arduino, but I'm trying to switch it to c++. It's pretty similar, but there is some differences. The problem is, it is saying something to the effect of not being able to convert from constant character to character. As you will see, I've tried messing around with the parameters, and was only able to narrow it down to four errors. Any ideas what it wrong? Thanks in advance.
//this is my original arduino code boolean areStringsSimilar(const char* x, const char* y){ float percentage = 0.0; int wordsInY = howManyWords(y); for (int i = 1; i<= wordsInY; i++){ //grabs first word from y and looks to see if it is in x. Then grabs second and so on. if(strstr(x, subStr(y, " ",i))){ percentage++; } } if(percentage/(float)wordsInY* 100 >= 60){//find percentage of words matched. If it's more than 60% return true return true; } return false; } //gets 1 word from a string and returns it //I didn't make this function so I don't really know how it works. In the new one I made my own. const char* subStr (const char* str, char *delim, int index) { char *act, *sub, *ptr; static char copy[MAX_STRING_LEN]; int i; // Since strtok consumes the first arg, make a copy strcpy(copy, str); for (i = 1, act = copy; i <= index; i++, act = NULL) { //Serial.print("."); sub = strtok_r(act, delim, &ptr); if (sub == NULL) break; } return sub; } //returns how many words in a string int howManyWords(const char* y){ int counter = 1; char ch; while(ch = *y++){ if(ch == ' '){ counter++; } } return counter; }
//the qt c++ code //finds how many words in a char array int Widget::howManyWords(char* array){ char* arrayCopy = array; int counter = 1; char ch; while(ch = *arrayCopy++){ if(ch == ' '){ counter++; } } return counter; } //returns word depending on the index from a char array. (e.g. yellow fellow pillow, index of one would return yellow char Widget::getWord(char* array, int index){ int counter = index = 1; char word, ch; char* arrayCopy = array; //check and see if they're trying to get first word if(index == 1){ while(ch = *arrayCopy++){ if(ch == ' '){ break; } word += ch; } } else{ while(ch = *arrayCopy++){ if(ch == ' '){ if(++counter == index){ ch = *arrayCopy++; while(ch != ' '){ word += ch; ch = *arrayCopy++; } } } } } return ch; } bool Widget::areStringsSimilar(char testChar, char compareChar){ float percentage = 0.0; int wordsInTest = howManyWords(testChar); for (int i = 1; i <= wordsInTest; i++){ if(strcmp(getWord(testChar, 1), compareChar)){ percentage++; } } if(percentage/(float)wordsInTest * 100 >= 60){ return true; } return false; }
The simplest thing that comes to mind is this:
QString string1, string2; //< Strings you compare QRegularExpression rx("\\s+"); QStringList words = string1.split(rx, Qt::SkipEmptyParts); QSet<QString> pattern = string2.split(rx, Qt::SkipEmptyParts).toSet(); //< Amortized O(1) complexity for lookups qint32 mismatch = 0; for (QStringList::ConstIterator i = words.constBegin(), end = words.constEnd(); i != end; i++) { if (!pattern.contains(*i)) mismatch++; } qreal match = 1 - static_cast<qreal>(mismatch) / words.count(); qreal percentage = match * 100;
-
Thanks A LOT guys! It helps A LOT!