我需要帮助来理解我的C代码的问题。我试图找到给定字符串中最长的子字符串而不重复字符。在leetcode平台上运行时,下面的代码给出了一个String "amqpcsrumjjufpu"
的错误:
运行时错误消息:第17行:索引-3超出类型'int [256]的范围
但是,当我从我的计算机或任何在线编辑器运行它时,相同的代码工作正常。请帮我理解这种行为差异。
#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;
}