空字符串 - 最长回文子串

空字符串 - 最长回文子串

1. 空字符串

字符串常量的书写方式是用一对双引号包围一串字符,如下所示:

“Hello”
“\aWarning!\a”
“Line 1\nLine2”
“”

字符串常量 (不像字符常量) 可以是空的。即使是空字符串,依然存在作为终止符的 NUL 宇节。

literal [ˈlɪtərəl]:adj. 文字的,逐字的,无夸张的
string [strɪŋ]:n. 线,弦,细绳,一串,一行

2. 最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"

如果一个字符串正着读和反着读是一样的,那它就是回文字符串。

  • 奇数长度的回文子串,以 idx 为中心,向两侧延伸,直到不再满足回文。
  • 偶数长度的回文子串,以 idx+0.5 为中心,向两侧延伸,直到不再满足回文。

回文字符串一定是关于中心对称的,所以每次循环的时候选择一个中心进行左右两边扩展,判断左右字符是否相等即可。由于可能存在奇数或者偶数个字符的回文字符串,所以需要从一个字符开始扩展,或者从两个字符之间开始扩展

在这里插入图片描述

char * longestPalindrome(char * s)
{
	int len_s = 0;
	int idx = 0, jdx = 0;
	char *ret = NULL;
	char *ps = s;
	int len_subs = 0;
	int start = 0;

	if (NULL == s)
	{
		return NULL;
	}

	len_s = strlen(s);

	if (0 == len_s)
	{
		ret = (char *) malloc((len_s + 1) * sizeof(char));
		ret[0] = '\0';
		return ret;
	}

	// odd number - center = idx
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx - 1;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

	ret = (char *) malloc((len_subs + 1) * sizeof(char));

	for (jdx = 0, idx = start; idx < start + len_subs; idx++, jdx++)
	{
		ret[jdx] = ps[idx];
	}

	ret[jdx] = '\0';

	return ret;
}

在这里插入图片描述

在这里插入图片描述

3. 特殊测试用例

3.1 空字符串 - s = "";

char * longestPalindrome(char * s)
{
	int len_s = 0;
	int idx = 0, jdx = 0;
	char *ret = NULL;
	char *ps = s;
	int len_subs = 0;
	int start = 0;
    int end = 0;

	if (NULL == s)
	{
		return NULL;
	}

	len_s = strlen(s);

	// if (0 == len_s)
	// {
	// 	ret = (char *) malloc((len_s + 1) * sizeof(char));
	// 	ret[0] = '\0';
	// 	return ret;
	// }

	// odd number - center = idx
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx - 1;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
            end = right_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
            end = right_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

    printf("start = %d\n", start);
    printf("end = %d\n", end);
    printf("len_s = %d\n", len_s);
    printf("len_subs = %d\n", len_subs);

	ret = (char *) malloc((len_subs + 1) * sizeof(char));

	for (jdx = 0, idx = start; idx <= end; idx++, jdx++)
	{
		ret[jdx] = ps[idx];
	}

	ret[jdx] = '\0';

	return ret;
}
AddressSanitizer: heap-buffer-overflow on address 0x6020000000f1 at pc 0x000000401f21 bp 0x7fff364b6380 sp 0x7fff364b6370

在这里插入图片描述

char * longestPalindrome(char * s)
{
	int len_s = 0;
	int idx = 0, jdx = 0;
	char *ret = NULL;
	char *ps = s;
	int len_subs = 0;
	int start = 0;
    int end = 0;

	if (NULL == s)
	{
		return NULL;
	}

	len_s = strlen(s);

	// if (0 == len_s)
	// {
	// 	ret = (char *) malloc((len_s + 1) * sizeof(char));
	// 	ret[0] = '\0';
	// 	return ret;
	// }

	// odd number - center = idx
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx - 1;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
            end = right_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < len_s; idx++)
	{
		int left_idx = idx;
		int right_idx = idx + 1;

		while ((left_idx >= 0) && (right_idx < len_s) && (ps[left_idx] == ps[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		if ((right_idx - left_idx + 1) > len_subs)
		{
			start = left_idx;
            end = right_idx;
			len_subs = right_idx - left_idx + 1;
		}
	}

    printf("start = %d\n", start);
    printf("end = %d\n", end);
    printf("len_s = %d\n", len_s);
    printf("len_subs = %d\n", len_subs);

	ret = (char *) malloc((len_subs + 1) * sizeof(char));

	for (jdx = 0, idx = start; idx < start + len_subs; idx++, jdx++)
	{
		ret[jdx] = ps[idx];
	}

	ret[jdx] = '\0';

	return ret;
}

在这里插入图片描述

在这里插入图片描述

4. 题目描述

工作中使用一些对称的密码进行通信,例如 ABBAABAA123321 等,但是有时会在开始或结束时加入一些无关的字符以防止破译。例如 ABBA->12ABBA,ABA->ABAKK,123321->51233214。考虑到字符串的长度,存在多种可能的情况 (abaaab 可看作是 ababaaab 的加密形式),编程查找最长的有效密码串。

输入描述:
输入一个字符串。

输出描述:
返回有效密码串的最大长度。

示例 1
输入:ABBA
输出:4

#include <stdio.h>
#include <string.h>

int inference_function(const char *input_string)
{
	int string_length = 0, output_length = 0;
	int left_idx = 0, right_idx = 0;
	int idx = 0;

	if (NULL == input_string)
	{
		return 0;
	}

	string_length = strlen(input_string);
	if (0 == string_length)
	{
		return 0;
	}

	// odd number - center = idx
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx - 1;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	return output_length;
}

int main()
{
	char input_string[5000] = { 0 };
	int output_length = 0;

	while (NULL != gets(input_string))
	{
		output_length = inference_function(input_string);
		printf("%d\n", output_length);
	}

	return 0;
}

在这里插入图片描述

4.1 特殊测试用例

gets 函数从标准输入读取一行文本并把它存储于作为参数传递给它的数组中。一行输入由一串字符组成,以一个换行符 (newline) 结尾。gets 函数丢弃换行符,并在该行的末尾存储一个 NUL 字节 (一个 NUL 字节是指字节模式为全 0 的字节,类似 '\0' 这样的字符常量)。然后,gets 函数返回一个非 NULL 值,表示该行己被成功读取。gets 函数被调用但事实上不存在输入行时,它就返回 NULL 值,表示它到达了输入的末尾 (文件尾)。

#include <stdio.h>
#include <string.h>

int inference_function(const char *input_string)
{
	int string_length = 0, output_length = 0;
	int left_idx = 0, right_idx = 0;
	int idx = 0;

	if (NULL == input_string)
	{
		return 0;
	}

	string_length = strlen(input_string);
	if (0 == string_length)
	{
		return 0;
	}

	// odd number - center = idx
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx - 1;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	return output_length;
}

int main()
{
	char input_string[5000] = { 0 };
	int output_length = 0;
    int ret = 0;

	while (NULL != gets(input_string))
	{
		output_length = inference_function(input_string);
		printf("%d\n", output_length);
	}
    
    printf("%d\n", ret);

	return 0;
}

gets 函数被调用但事实上不存在输入行时,它就返回 NULL 值,表示它到达了输入的末尾 (文件尾)。按照网站上给的测试用例可以理解,gets 函数返回 NULL 值,不需要打印 0 值。

在这里插入图片描述

4.2 特殊测试用例

#include <stdio.h>
#include <string.h>

int inference_function(const char *input_string)
{
	int string_length = 0, output_length = 0;
	int left_idx = 0, right_idx = 0;
	int idx = 0;

	if (NULL == input_string)
	{
		return 0;
	}

	string_length = strlen(input_string);
	if (0 == string_length)
	{
		return 0;
	}

	// odd number - center = idx
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx - 1;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	// even number - center = idx + 0.5
	for (idx = 0; idx < string_length; idx++)
	{
		int tmp_length = 0;
		left_idx = idx;
		right_idx = idx + 1;

		while ((left_idx > 0) && (right_idx < string_length) && (input_string[left_idx] == input_string[right_idx]))
		{
			left_idx--;
			right_idx++;
		}

		left_idx++;
		right_idx--;

		tmp_length = right_idx - left_idx + 1;
		if (tmp_length > output_length)
		{
			output_length = tmp_length;
		}
	}

	return output_length;
}

int main()
{
	char input_string[5000] = { 0 };
	int output_length = 0;

	if (NULL == gets(input_string))
	{
        return 0;
	}
    
    output_length = inference_function(input_string);
    printf("%d\n", output_length);
    
	return 0;
}

在这里插入图片描述

请检查一下你的代码,有没有循环输入处理多个 case.
在线判题系统 (Online Judge,OJ) 一次处理多个 case,所以代码需要循环处理,一般通过 while 循环来出来多个 case

#include <stdio.h>

int main()
{
	int a, b;
	while (scanf("%d %d", &a, &b) != EOF) // 注意 while 处理多个 case
	{
		printf("%d\n", a + b);
	}

	return 0;
}

用例:
dsuehgfqxzrnkmtmiwytshrerjfybxirufrsobkjeghiunftxyqqcyoreevvktxgvjjqzvcujsynsrlgllebyukyxgugrvkesovfhzdznstvtbblmjcngwsdrmfczsihiblqhkfvhzylwopepfmnixeesvugyifdxvpcknpqunolpgjehoxgylnzoggqpbdkhrngchidhfdktblrifjvppttemmplzrsbjhltvwprhkigkvfkxcxfsgyiyuuziqurgcmddqshenindtrfzlrqpfpekfosmugpwjgydtbwexcwrvdedposftffjrfeojsqpxtoguroojsgrwpyiyhurprcfsgnnykjtrjjzdswfqfwuohpcssgjzyikruvomeggqzyslmfurgnmhyvnksktvdcidvutrrxzixbxiypbvozgnmopfjiljggqrronwkfqvlpdwhtzfpsokfbvftyxdinknsrjlxbzyfmsinegprbnuezqlikgsbbixfdjtsjxojqwxdrvwfflrwjsnpcxqvfpmbidyvvlcnvvvvbglhhmkpuzhosfitgzclicpzsvozsbtvtlmjffqieosliqysgyxmceytmezfbtkcprfomftlkyortyfmykslfdmxzfeetmzxbuvoorpwmkerujcjcuuyvmpqidrrksrtmxhqoqdyvjgvcftbhywmbdfoixecfgorpxoxbqlhbnynwflbodsdqvwwoizdfyczefvonoczocvtbixehcvpmimyxgzddvomklofuthtytqougojqwmxvhzpmvtfsjwrgmxuoeizmnfptssolqbmnrhfjitoqxizflyoddgjlxknumclfmpmrzpomrqqogvmwgclpquhuqbkriyjkwcusetkyxozomcrsuyfmsddwubkiyyjoeqlzjsfnwkhdpgxkeicbivlwbdvcbvdqbyxuwdolmtxzgpogtzctlcjemoxdrbrmmtkuuidtiebckmqluiszgichpmgbsxdiurxdgkvvufyihcjejgwwepswxmjducltnxngtylgiqcvxldeebykysdgwokcupxmjnbiqlzovnocuesodotqivceqhimuhtromxxullejgzhzevzvtdhbfhcwbdivgslkfmudzofbmeeqixuprbsyrelcgvvkbtkgckezrrisnnkwwchcfwlqdoucccqinjplgwlqcylqojstlvdjmcjyqjsqwrvxjmujcuzirinocnnwszxjnyszncytltbusmcsxustpxeuxgmwlixnjnigsxnollfbpqrwohbshbohhnpsvenvgreqfwqypkkibenvgjcwmumwcgehehiyediindvppefciihjkcnzvelorusllpbexivekbflpyqpefpjlumctorwejnefenhrlfugnkywvwuvrdrxsxjksgowxholmpjfyjcksmhwpcpjcodwzmolzgkcjxmiqxdpewlyjilcbbwyxmxhqvsxkepiwdvmfxdceiswscupzpmhvmyciyosxuwnmjxnkdhhnquxsmekmcwgcklxzhhqxkebqcvxpsqzuoxikverbskrwvewomemysgcmrdnzgufysnoxuerrqcufevwwumrvbowvvkjuediygphwgwgdrpbgreytkmgcmzonbyxwkolywjcigvyqqhwsjmtkvvhbtuhctcigvfnkkffvsjrjiumlowlwvsbuopmsfcqrxlpprtmswlkdmkoxewhtfkzzoohdbutqccmzsscjdozeeecdqmugcrqqfjingovwfmvnltdfcmrofcftnoozquguyyzdxqqgwbdpotbquhokorykpurvwbvcwdnmzgimuzjipikdtvhstsgeykmunxvbszjmbgwhiymumfmlhennthtjwspxvqrelkhwqxjrzbkqbobfetlejvdhzpmwreqfhnupgovixdemmngzorgfooiruhjbjmvwgmzrvjgrwouxugmysbrdtdujjeffomribgqkhjohitgonqevcweedmleexqjgtywpwbwmoltxbdkiyvgrykhbesgckhvecyvcjryqbhstwrcloqmoivrmkkimzwbywumxfrzyterxmwpqcullcvebkflwmbbexqifohjrrgsnbsqhlxkwkuhwocmjfrhyfkqpqlbvxokbvbufqffclzlnlszcimzucrsrohldxeohdiktubdrvkzvgvhnrkeenmhcvujlxlpcyhohumnuxmswwfwyhuyqhurvcrvmnkgsyygunrvpbvdmpetuixhwtnswhmgtuunzybkyosezpzttrzcdukbtmxxeschlkjgqgrnhvixqbcusimvwdceedhhbbbrxefvztdcfdtzglhmzfthlmc
对应输出应该为:
7
你的输出为:
空.请检查一下你的代码,有没有循环输入处理多个case.点击查看如何处理多个case
发布了523 篇原创文章 · 获赞 1850 · 访问量 112万+

猜你喜欢

转载自blog.csdn.net/chengyq116/article/details/104954073