我需要帮助来理解我的C代码的问题。我正在尝试在给定字符串中找到最长的子字符串,而无需重复字符。在leetcode平台上运行时,下面的代码给了我一个字符串"amqpcsrumjjufpu"
错误:
运行时错误消息:第 17 行:类型"int [256]"的索引 -3 越界
但是,当我从计算机或任何在线编辑器运行它时,相同的代码可以正常工作。请帮助我理解这种行为差异。
#include <stdio.h>
#include <string.h>
int lengthOfLongestSubstring(char* s) {
char *h = s;
int A[256] = {0};
int length = 0;
int temp = 0;
int max = 0;
int len = strlen(s);
for(int i = 0; i < len;i ++){
int A[256] = {0};
length = 0;
h = s + i;
for(int j = i; j < len-1; j++){
if (A[h[j]] == 1) {
break;
} else {
A[h[j]] = 1;
length +=1;
}
if (max < length) {
max = length;
}
}
}
return max;
}
int main() {
char *s = "amqpcsrumjjufpu";
int ret = lengthOfLongestSubstring(s);
printf("SAURABH: %d",ret);
}
您似乎正在尝试编写一个函数来查找唯一字符的最长子字符串的长度。
对于初学者来说,函数应该像这样声明
size_t lengthOfLongestSubstring( const char *s );
^^^^^^ ^^^^^
函数外部作用域中的这些声明
int A[256] = {0};
//...
int temp = 0;
是多余的。函数中不使用变量。
类型char
的行为可以是类型signed char
或类型unsigned char
。 因此,在像这样的表达式中A[h[j]]
您必须显式地将用作索引的字符转换为类型unsigned char
A[( unsigned char )h[j]]
内环
for(int j=i;j<len-1;j++){
不会对仅包含一个字符的字符串执行。所以它写得没有意义。
这个 if 语句
if (max < length) {
max = length ;
}
需要放置在内环外。
您可以使用的算法可以通过以下方式实现
#include <stdio.h>
#include <limits.h>
size_t lengthOfLongestSubstring(const char *s)
{
size_t longest = 0;
for (; *s; ++s )
{
size_t n = 0;
unsigned char letters[UCHAR_MAX] = { 0 };
for ( const char *p = s; *p && !letters[(unsigned char)*p - 1]++; ++p) ++n;
if (longest < n) longest = n;
}
return longest;
}
int main( void )
{
char *s = "123145";
printf("The longest substring has %zu characters.n",
lengthOfLongestSubstring(s));
return 0;
}
程序输出为
The longest substring has 5 characters.
你的代码崩溃了,因为你读取的数据超出了范围,假设你的输入字符串是amqpcsrumjjufpu,它的长度是15,在外循环中,i = 13
你做同理
h = s + i; // h was updated to indicate to 13th element of s
在第一次迭代的内部循环中,您读取此元素 (j == i == 13)
A[h[j]]
所以,你尝试A[*(h+j)]
读取这个元素,但h
表示 s 的第 13 个元素,现在你尝试在这个值上加 13,你想读取s
的第 26 个位置,你超出了s
字符串的范围。
感谢大家的回复。虽然 Vlad 的代码适用于所有测试用例,但这是我的代码,在 Vlad 和 rafix 建议的更改后也通过了所有测试用例。
int lengthOfLongestSubstring(char* s) {
char *h = s;
int max = 0;
int len = strlen(s);
if (len == 1) {
return 1;
}
for(int i = 0; i < len;i ++){
int A[256] = {0};
int length = 0;
for(int j = i; j < len; j++){
if (A[(unsigned char)h[j]] == 1) {
break;
} else {
A[(unsigned char) h[j]] = 1;
length +=1;
}
}
if (max < length) {
max = length;
}
}
return max;
}