为什么我不能将 size() 函数编写为 while 循环中的条件?

Why can't I write the size() function as a condition in the while loop?

本文关键字:循环 while 条件 不能 size 函数 为什么      更新时间:2023-10-16

当我学习KMP算法时。我发现如果我在 while 循环中将 size(( 函数编写为条件,我会得到错误的结果。

我发现如果我将 size(( 函数设置为条件。它不能第二次进入 while 循环。

例如,如果haystack="hello"和needle="ll"。正确答案是2。但是在此代码中。结果我得到 -1。因为我第一次进入时发现循环。j 的值变为"-1"。但是 i 的值仍然小于 haystack.size((,而 j 的相同时间值仍然小于 needle.size((。

为什么我不能以这种形式编写代码。

这是我的代码:

class Solution {
public:
int strStr(string haystack, string needle) {
if (needle.size() > haystack.size())
return -1;
if (haystack == "" || needle == "")
return 0;
std::vector<int> next(needle.size(), 0);
getNext(next, needle);
int i = 0, j = 0;
while (i < haystack.size() && j < needle.size()) // it is question location
{
if (j == -1 || haystack[i] == needle[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j == needle.size())
return i - j;
else
return -1;
}
void getNext(std::vector<int>& next, string needle)
{
next[0] = -1;
int i = 0, j = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
};

如果我写这段代码。这是正确的

class Solution {
public:
int strStr(string haystack, string needle) {
if (needle.size() > haystack.size())
return -1;
if (haystack == "" || needle == "")
return 0;
std::vector<int> next(needle.size(), 0);
getNext(next, needle);
int i = 0, j = 0;
int p = haystack.size();//look at this
int q = needle.size(); //look at this
while (i < p && j < q)
{
if (j == -1 || haystack[i] == needle[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j == needle.size())
return i - j;
else
return -1;
}
void getNext(std::vector<int>& next, string needle)
{
next[0] = -1;
int i = 0, j = -1;
while (i < needle.size()-1)
{
if (j == -1 || needle[i] == needle[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
};

对我来说最突出的一件事是你对j和-1的比较,告诉我你期望它在某个时候变成负数(大概是当没有下一个值时(。 假设 j 实际上是负数,您的循环预计会终止。

但它不会。

比较有符号和无符号值有一个令人讨厌的错误,这有令人惊讶的结果。 注意,(-1 <5u(是的(真的!!(,因为负 int 被提升为 unsigned,而表示为 unsigned 的 -1 是 max unsigned。 因此,循环不会在应该终止的时候终止。

int i = 0, j = 0;
while (i < haystack.size() && j < needle.size()) // BUG: signed/unsigned mixture
{
if (j == -1 || haystack[i] == needle[j])
{
i++;
j++;
}
else
j = next[j];
}

相比之下,当您将大小存储在 int 中时,您正在进行整数比较并且循环正确终止:

int p = haystack.size();
int q = needle.size();
while (i < p && j < q) // *** int to int comparison == good
{