提交 91265c88 编写于 作者: G Gines Hidalgo

NatSort working with numbers longer than the int limit

上级 eef7e8ab
......@@ -397,6 +397,7 @@ OpenPose Library - Release Notes
2. Renamed `dLog()` as `opLogIfDebug()`, `log()` as `opLog()`, `check()` as `checkBool()`, and also renamed all the `checkX()` functions in `include/openpose/utilities/check.hpp`. This avoids compiling crashes when exporting OpenPose to other projects which contain other 3rd-party libraries that define functions with the same popular names with `#define`.
3. Main bugs fixed:
1. Removed many Visual Studio (Windows) warnings.
2. Natural sort now works properly with filenames containining numbers longer than the limit of an int.
4. Changes/additions that affect the compatibility with the OpenPose Unity Plugin:
......
......@@ -22,6 +22,10 @@ namespace op
OP_API std::string toLower(const std::string& string);
OP_API std::string toUpper(const std::string& string);
OP_API std::string remove0sFromString(const std::string& string);
OP_API std::string getFirstNumberOnString(const std::string& string);
}
#endif // OPENPOSE_UTILITIES_STRING_HPP
......@@ -18,35 +18,45 @@ namespace op
{
bool compareNat(const std::string& a, const std::string& b)
{
// If any is empty, that one is shorter
if (a.empty())
return true;
else if (b.empty())
return false;
// If one is digit, return that one
else if (std::isdigit(a[0]) && !std::isdigit(b[0]))
return true;
else if (!std::isdigit(a[0]) && std::isdigit(b[0]))
return false;
// If none is digit, compare those strings
else if (!std::isdigit(a[0]) && !std::isdigit(b[0]))
{
if (std::toupper(a[0]) == std::toupper(b[0]))
return compareNat(a.substr(1), b.substr(1));
return (std::toupper(a[0]) < std::toupper(b[0]));
}
// Both strings begin with digit --> parse both numbers
std::istringstream issa(a);
std::istringstream issb(b);
int ia, ib;
issa >> ia;
issb >> ib;
if (ia != ib)
return ia < ib;
// Numbers are the same --> remove numbers and recurse
std::string anew, bnew;
std::getline(issa, anew);
std::getline(issb, bnew);
return (compareNat(anew, bnew));
// Both strings begin with digit
else
{
// Remove 0s at the beginning
const std::string aNo0s = remove0sFromString(a);
const std::string bNo0s = remove0sFromString(b);
// Get only number
const std::string aNumberAsString = getFirstNumberOnString(aNo0s);
const std::string bNumberAsString = getFirstNumberOnString(bNo0s);
// 1 number is longer --> it is bigger
if (aNumberAsString.size() != bNumberAsString.size())
return aNumberAsString.size() < bNumberAsString.size();
// Both same length --> Compare them
for (auto i = 0 ; i < aNumberAsString.size() ; ++i)
if (aNumberAsString[i] != bNumberAsString[i])
return aNumberAsString[i] < bNumberAsString[i];
// Both same number --> Remove and return compareNat after removing those characters
const std::string aWithoutFirstNumber = aNo0s.substr(aNumberAsString.size(), aNo0s.size());
const std::string bWithoutFirstNumber = bNo0s.substr(bNumberAsString.size(), bNo0s.size());
// Number removed, compared the rest of the string
return compareNat(aWithoutFirstNumber, bWithoutFirstNumber);
}
}
void makeDirectory(const std::string& directoryPath)
......
......@@ -117,4 +117,48 @@ namespace op
return "";
}
}
std::string remove0sFromString(const std::string& string)
{
try
{
std::string stringNo0s;
if (string[0] == '0')
{
// Find first not 0
const std::size_t found = string.find_first_not_of("0");
if (found == std::string::npos)
error("This should not happen.", __LINE__, __FUNCTION__, __FILE__);
// Make sure that 0 is not the only digit
if (string.size() > found && std::isdigit(string[found]))
stringNo0s = string.substr(found);
else
stringNo0s = string.substr(found-1);
}
else
stringNo0s = string;
return stringNo0s;
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return "";
}
}
std::string getFirstNumberOnString(const std::string& string)
{
try
{
const std::size_t found = string.find_first_not_of("0123456789");
if (found == std::string::npos)
error("This should not happen.", __LINE__, __FUNCTION__, __FILE__);
return string.substr(0, found);
}
catch (const std::exception& e)
{
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
return "";
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册