按字典顺序比较两个字符串中的第 k 个单词
to lexicographically compare kth word from two strings
我正在尝试编写一个 C++ 函数来按字典顺序比较两个字符串中的第 k 个单词。这是我的功能:
bool kth_lexo ()
{
int k = 2 ;
str1 = "123 300 60009" ;
str2 = "1500 10002" ;
// to store the kth word of fist string in ptr1
char *ptr1 = strtok( (char*)str1.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr1 = strtok(NULL," ");
}
// to store the kth word of second string in ptr2
char *ptr2 = strtok( (char*)str2.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr2 = strtok(NULL," ");
}
string st1 = ptr1 ;
string st2 = ptr2 ;
return st1 > st2 ;
}
在这个函数中,我的字典顺序比较工作正常,因为这个函数 returns 1 因为 300(str1 的第二个单词)在字典顺序上大于 10002(str2 的第二个单词)
我的问题:
如果我通过用 return ptr1>ptr2 ;
替换上一个函数的最后一行来稍微修改我的函数
现在我的新功能看起来像这样:
bool kth_lexo ()
{
int k = 2 ;
str1 = "123 300 60009" ;
str2 = "1500 10002" ;
// to store the kth word of fist string in ptr1
char *ptr1 = strtok( (char*)str1.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr1 = strtok(NULL," ");
}
// to store the kth word of second string in ptr2
char *ptr2 = strtok( (char*)str2.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr2 = strtok(NULL," ");
}
// modified line compared to previous function
return ptr1 > ptr2 ;
}
对于这个修改后的函数,每次我的输出始终为 0,无论存储在 ptr1 中的 str1 的第 k 个字按字典顺序大于还是小于存储在 ptr2 中的 str2 的第 k 个字。
即使通过此行修改 return 语句也没有带来太大帮助:
return (*ptr1)>(*ptr2) ;
那么我修改后的函数中用于比较两个字符串的第 k 个单词的这两个 return 语句行有什么问题:
return ptr1 > ptr2 ;
或
return (*ptr1) > (*ptr2) ;
如果您停止使用 C 而转而使用 C++,则不会出现此问题。
您在这里混淆了 C++ std::string
和 char*
或 const char*
。基本上,对于字符串,std::string
优于旧式 C 字符数组或 char*
,从现在开始和将来您永远不应该使用 std::string
字符指针是指向内存中存储字符数据的某个区域的地址。使用 * 取消引用指针,将为您提供存储在此地址的元素。所以只有一个元素。不是字符串或其他任何东西。只有一个字符。
比较ptr1 > ptr2
,不会比较字符串。它将比较一些值,其中字符串存储在内存中。 “ptr1”可以是 0x578962574,“ptr2”可以是 0x95324782,或其他。我们不知道地址。这将由链接器定义。
如果你比较 (*ptr1)>(*ptr2)
,那么你只比较 2 个单个字符,这也可能给你错误的结果。
另一方面,比较 2 std::string
s,将始终按预期工作。
所以,简单的答案:对所有字符串使用 std::string
。
您正在使用非常类似于 C 的程序。使用现代 C++ 使这变得更简单和更容易阅读,因为我们可以使用非常有表现力的语法:
#include <string_view>
#include <iostream>
#include <cassert>
auto find_kth_char(std::string_view to_search, char c, std::size_t k, std::size_t pos = 0) {
for (; pos < std::string_view::npos && k > 0; --k) {
pos = to_search.find(c, pos + 1);
}
return pos;
}
auto get_kth_word(std::string_view to_search, std::size_t k) {
// We count starting on 1
assert(k > 0);
auto start = find_kth_char(to_search, ' ', k - 1);
if (start == std::string_view::npos) {
return std::string_view{};
}
auto end = find_kth_char(to_search, ' ', 1, start);
return to_search.substr(start, end - start);
}
auto compare_kth(std::string_view lhs, std::string_view rhs, std::size_t k) {
auto l_word = get_kth_word(lhs, k);
auto r_word = get_kth_word(rhs, k);
// returnvalue <=> 0 == lhs <=> rhs
return l_word.compare(r_word);
}
int main() {
auto str1 = "123 300 60009";
auto str2 = "1500 10002";
for (std::size_t k = 1; k < 4; ++k) {
std::cout << k << ":\t" << compare_kth(str1, str2, k) << '\n';
}
}
我正在使用 C++17 的 string_view
,因为我们不更改字符串中的任何内容,并且采用子字符串等对它们来说非常便宜。我们使用 find
and compare
成员函数来完成实际工作。
我们函数的 return 值是一个整数,它告诉我们左侧是否小于(负结果)、等于 (0) 或大于(正结果)右侧。
我正在尝试编写一个 C++ 函数来按字典顺序比较两个字符串中的第 k 个单词。这是我的功能:
bool kth_lexo ()
{
int k = 2 ;
str1 = "123 300 60009" ;
str2 = "1500 10002" ;
// to store the kth word of fist string in ptr1
char *ptr1 = strtok( (char*)str1.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr1 = strtok(NULL," ");
}
// to store the kth word of second string in ptr2
char *ptr2 = strtok( (char*)str2.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr2 = strtok(NULL," ");
}
string st1 = ptr1 ;
string st2 = ptr2 ;
return st1 > st2 ;
}
在这个函数中,我的字典顺序比较工作正常,因为这个函数 returns 1 因为 300(str1 的第二个单词)在字典顺序上大于 10002(str2 的第二个单词)
我的问题:
如果我通过用 return ptr1>ptr2 ;
现在我的新功能看起来像这样:
bool kth_lexo ()
{
int k = 2 ;
str1 = "123 300 60009" ;
str2 = "1500 10002" ;
// to store the kth word of fist string in ptr1
char *ptr1 = strtok( (char*)str1.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr1 = strtok(NULL," ");
}
// to store the kth word of second string in ptr2
char *ptr2 = strtok( (char*)str2.c_str() ," ");
for(int i = 1; i<k; i++)
{
ptr2 = strtok(NULL," ");
}
// modified line compared to previous function
return ptr1 > ptr2 ;
}
对于这个修改后的函数,每次我的输出始终为 0,无论存储在 ptr1 中的 str1 的第 k 个字按字典顺序大于还是小于存储在 ptr2 中的 str2 的第 k 个字。
即使通过此行修改 return 语句也没有带来太大帮助:
return (*ptr1)>(*ptr2) ;
那么我修改后的函数中用于比较两个字符串的第 k 个单词的这两个 return 语句行有什么问题:
return ptr1 > ptr2 ;
或
return (*ptr1) > (*ptr2) ;
如果您停止使用 C 而转而使用 C++,则不会出现此问题。
您在这里混淆了 C++ std::string
和 char*
或 const char*
。基本上,对于字符串,std::string
优于旧式 C 字符数组或 char*
,从现在开始和将来您永远不应该使用 std::string
字符指针是指向内存中存储字符数据的某个区域的地址。使用 * 取消引用指针,将为您提供存储在此地址的元素。所以只有一个元素。不是字符串或其他任何东西。只有一个字符。
比较ptr1 > ptr2
,不会比较字符串。它将比较一些值,其中字符串存储在内存中。 “ptr1”可以是 0x578962574,“ptr2”可以是 0x95324782,或其他。我们不知道地址。这将由链接器定义。
如果你比较 (*ptr1)>(*ptr2)
,那么你只比较 2 个单个字符,这也可能给你错误的结果。
另一方面,比较 2 std::string
s,将始终按预期工作。
所以,简单的答案:对所有字符串使用 std::string
。
您正在使用非常类似于 C 的程序。使用现代 C++ 使这变得更简单和更容易阅读,因为我们可以使用非常有表现力的语法:
#include <string_view>
#include <iostream>
#include <cassert>
auto find_kth_char(std::string_view to_search, char c, std::size_t k, std::size_t pos = 0) {
for (; pos < std::string_view::npos && k > 0; --k) {
pos = to_search.find(c, pos + 1);
}
return pos;
}
auto get_kth_word(std::string_view to_search, std::size_t k) {
// We count starting on 1
assert(k > 0);
auto start = find_kth_char(to_search, ' ', k - 1);
if (start == std::string_view::npos) {
return std::string_view{};
}
auto end = find_kth_char(to_search, ' ', 1, start);
return to_search.substr(start, end - start);
}
auto compare_kth(std::string_view lhs, std::string_view rhs, std::size_t k) {
auto l_word = get_kth_word(lhs, k);
auto r_word = get_kth_word(rhs, k);
// returnvalue <=> 0 == lhs <=> rhs
return l_word.compare(r_word);
}
int main() {
auto str1 = "123 300 60009";
auto str2 = "1500 10002";
for (std::size_t k = 1; k < 4; ++k) {
std::cout << k << ":\t" << compare_kth(str1, str2, k) << '\n';
}
}
我正在使用 C++17 的 string_view
,因为我们不更改字符串中的任何内容,并且采用子字符串等对它们来说非常便宜。我们使用 find
and compare
成员函数来完成实际工作。
我们函数的 return 值是一个整数,它告诉我们左侧是否小于(负结果)、等于 (0) 或大于(正结果)右侧。