Hackerrank--String Function Calculation(后缀数组)

本文介绍了一种解决字符串问题的方法,通过构建后缀数组和最长公共前缀(LCP)数组,来找到字符串所有子串中特定函数的最大值。此函数定义为子串的长度与其在原字符串中出现次数的乘积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

Jane loves string more than anything. She made a function related to the string some days ago and forgot about it. She is now confused about calculating the value of this function. She has a string T with her, and value of string S over function f can be calculated as given below:

f(S)=|S|NumberoftimesSoccuringinT

Jane wants to know the maximum value of f(S) among all the substrings (S) of string T. Can you help her?

Input Format
A single line containing string T in small letter('a' - 'z').

Output Format
An integer containing the value of output.

Constraints
1 ≤|T|≤ 105

Sample Input #00

aaaaaa

Sample Output #00

12

Explanation #00

f('a') = 6
f('aa') = 10
f('aaa') = 12
f('aaaa') = 12
f('aaaaa') = 10
f('aaaaaa') = 6

Sample Input #01

abcabcddd

Sample Output #01

9

Explanation #01

f("a") = 2
f("b") = 2
f("c") = 2
f("ab") = 4
f("bc") = 4
f("ddd") = 3
f("abc") = 6
f("abcabcddd") = 9

Among the function values 9 is the maximum one.

题意:求字符串所有子串中,f(s)的最大值。这里s是某个子串,f(s) = s的长度与s在原字符串中出现次数的乘积。

求得lcp, 转化为求以lcp为高的最大子矩形。

Accepted Code:

 1 #include <string>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 const int MAX_N = 100002;
 7 int sa[MAX_N], rk[MAX_N], lcp[MAX_N], tmp[MAX_N], n, k;
 8 
 9 bool compare_sa(int i, int j) {
10     if (rk[i] != rk[j]) return rk[i] < rk[j];
11     int ri = i + k <= n ? rk[i + k] : -1;
12     int rj = j + k <= n ? rk[j + k] : -1;
13     return ri < rj;
14 }
15 
16 void construct_sa(const string &S, int *sa) {
17     n = S.length();
18     for (int i = 0; i <= n; i++) {
19         sa[i] = i;
20         rk[i] = i < n ? S[i] : -1;
21     }
22     
23     for (k = 1; k <= n; k *= 2) {
24         sort(sa, sa + n + 1, compare_sa);
25         
26         tmp[sa[0]] = 0;
27         for (int i = 1; i <= n; i++) {
28             tmp[sa[i]] = tmp[sa[i - 1]] + (compare_sa(sa[i - 1], sa[i]) ? 1 : 0);
29         }
30         for (int i = 0; i <= n; i++) rk[i] = tmp[i];
31     }
32 }
33 
34 void construct_lcp(const string &S, int *sa, int *lcp) {
35     n = S.length();
36     for (int i = 0; i <= n; i++) rk[sa[i]] = i;
37     
38     int h = 0;
39     lcp[0] = 0;
40     for (int i = 0; i < n; i++) {
41         int j = sa[rk[i] - 1];
42         
43         if (h > 0) h--;
44         for (; i + h < n && j + h < n; h++) if (S[i + h] != S[j + h]) break;
45             
46         lcp[rk[i] - 1] = h;
47     }
48 }
49 
50 string S;
51 int lft[MAX_N], rgt[MAX_N], st[MAX_N], top;
52 void solve() {
53     construct_sa(S, sa);
54     construct_lcp(S, sa, lcp);
55     
56     lcp[n] = n - sa[n];
57    // for (int i = 1; i <= n; i++) cerr << lcp[i] << ' ';
58    // cerr << endl;
59     top = 0;
60     for (int i = 1; i <= n; i++) {
61         while (top && lcp[st[top-1]] >= lcp[i]) top--;
62         if (top) lft[i] = st[top - 1] + 1;
63         else lft[i] = 1;
64         st[top++] = i;
65     }
66     top = 0;
67     for (int i = n; i > 0; i--) {
68         while (top && lcp[st[top-1]] >= lcp[i]) top--;
69         // attention: rgt[i] should be asigned to st[top - 1]
70         // rather than st[top - 1] - 1 because lcp[i] is the
71         // length of the longest common prefix of sa[i] and sa[i + 1]. 
72         if (top) rgt[i] = st[top - 1];
73         else rgt[i] = n;
74         st[top++] = i;
75     }
76     long long ans = n;
77     for (int i = 1; i <= n; i++) ans = max(ans, (long long)lcp[i] * (rgt[i] - lft[i] + 1));
78     cout << ans << endl;
79 }
80 
81 int main(void) {
82     //ios::sync_with_std(false);
83     while (cin >> S) solve();
84     return 0;
85 }

 

转载于:https://www.cnblogs.com/Stomach-ache/p/3930096.html

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include “aip_common.h” #include <string.h> #include <stdlib.h> #define ZERO (0) #define MAX_LINE_LENGTH (256) #define ADD_VALUE (0xF) #define FALSE (0) #define WRONG (1) #define SUCCESS (1) #define TRUE (1) #define STORESIZE (9) #define ENDOFSTRING (8) #define FOUR (4) /* / / Display Application : Main Processing Task / / ---------------------------------------------------------------------------------------------------------------------------------/ / Function: main / / Description: This function processes DA_510B_IMG_1.mhx file to extract address values, applies offset calculation, / / and generates WRITE_ADDRESS.TXT output file with formatted address pairs. / / Arguments: void / / Return: U4 - Process execution status (ZERO for success, WRONG for failure) / /=/ U4 main(void) { U4 u4_t_search_target; FILE stp_t_creatfile_da_510b_img_1; FILE* stp_t_creatfile_write_address; U1 u1_t_p_test_line[MAX_LINE_LENGTH]; size_t u4_t_test_len; U1* u1p_t_s315_pos; U1* u1p_t_addr_start; U1 u1_t_p_test_new_hex_addr[STORESIZE]; U4 u4_t_test_address; U4 u4_t_test_new_address; S4 s4_tp_store_string[STORESIZE] = { ZERO }; U4 u4_t_return_value = ZERO; /* Unified return status variable */ u4_t_search_target =(U4) FALSE; stp_t_creatfile_da_510b_img_1 = NULL; stp_t_creatfile_write_address = NULL; u1p_t_s315_pos = NULL; u1p_t_addr_start = NULL; u4_t_test_address = (U4)ZERO; u4_t_test_new_address = (U4)ZERO; /* Open input file for reading / stp_t_creatfile_da_510b_img_1 = fopen(“DA_510B_IMG_1.mhx”, “rb”); / Handle input file open failure / if (NULL == stp_t_creatfile_da_510b_img_1) { printf(“Input file open failed\n”); u4_t_return_value = (U4)WRONG; } else { / Create output file for writing / stp_t_creatfile_write_address = fopen(“WRITE_ADDRESS.TXT”, “w”); / Handle output file creation failure / if (NULL == stp_t_creatfile_write_address) { printf(“Output file creation failed\n”); fclose(stp_t_creatfile_da_510b_img_1); u4_t_return_value = (U4)WRONG; } else { printf(“Input file opened successfully\n”); / Process each line in input file / while (fgets(u1_t_p_test_line, (U4)MAX_LINE_LENGTH, stp_t_creatfile_da_510b_img_1) != NULL) { / Remove newline character from line end / u4_t_test_len = strlen(u1_t_p_test_line); if (u4_t_test_len > 0 && u1_t_p_test_line[u4_t_test_len - 1] == ‘\n’) { u1_t_p_test_line[u4_t_test_len - 1] = ‘\0’; } / Search for “S315” marker in current line / u1p_t_s315_pos = strstr(u1_t_p_test_line, “S315”); / Process line containing target marker / if (u1p_t_s315_pos != NULL) { printf(“Target line found: %s\n”, u1_t_p_test_line); u1p_t_addr_start = u1p_t_s315_pos + (U4)FOUR; / Verify sufficient characters after marker / if (strlen(u1p_t_addr_start) >= (U4)ENDOFSTRING) { / Extract and store address string / strncpy(s4_tp_store_string, u1p_t_addr_start, (U4)ENDOFSTRING); s4_tp_store_string[(U4)ENDOFSTRING] = ‘\0’; printf(“Raw hexadecimal address: %p\n”, s4_tp_store_string); / Convert hex string to numeric value / u4_t_test_address = strtoul(s4_tp_store_string, NULL, 16); / Apply address offset calculation / u4_t_test_new_address = u4_t_test_address + ADD_VALUE; / Format new address as 8-digit hex string / snprintf(u1_t_p_test_new_hex_addr, sizeof(u1_t_p_test_new_hex_addr), “%08lX”, u4_t_test_new_address); printf(“Address after adding 16: 0x%s\n”, u1_t_p_test_new_hex_addr); / Write formatted address pair to output file / fprintf(stp_t_creatfile_write_address, “0x40000000,0x%s\n”, u1_t_p_test_new_hex_addr); fprintf(stp_t_creatfile_write_address, “0x43FFFFF0,0x43FFFFFF\n”); printf(“File written successfully: WRITE_ADDRESS.TXT\n”); u4_t_search_target = (U4)SUCCESS; } else { printf(“Error: Characters after S315 less than 8\n”); } break; } } / Handle case where target marker was not found / if (!u4_t_search_target) { printf(“line S315 not found\n”); / Write default address format to output file / fprintf(stp_t_creatfile_write_address, “0x40000000,0x00000000\n”); fprintf(stp_t_creatfile_write_address, “0x43FFFFF0,0x43FFFFFF\n”); printf(“Default format written to file\n”); } / Close output file handle / fclose(stp_t_creatfile_write_address); } / Close input file handle */ fclose(stp_t_creatfile_da_510b_img_1); } system(“pause”); return u4_t_return_value; }帮我把main函数里面函数功能封装到不同函数中,按照我的编码习惯
07-31
重新写代码,参考如下代码:Sub BatchCopyFilesWithSuffix() Dim FSO As Object, wbSource As Workbook, wbTarget As Workbook Dim wsSource As Worksheet, wsTarget As Worksheet Dim sourcePath As String: sourcePath = "C:\Users\74153\Desktop\工作产出\DAY14 5.29\供应商主数据导入生产机\excel宏版本\宏测试复制文档\1\" Dim targetPath As String: targetPath = "C:\Users\74153\Desktop\工作产出\DAY14 5.29\供应商主数据导入生产机\excel宏版本\宏测试复制文档\2\" Dim fileName As String, baseName As String, newName As String Set FSO = CreateObject("Scripting.FileSystemObject") If Not FSO.FolderExists(targetPath) Then MkDir targetPath Application.ScreenUpdating = False On Error GoTo ErrorHandler fileName = Dir(sourcePath & "*.xls*") Do While fileName <> "" ' 处理文件名 baseName = FSO.GetBaseName(fileName) Set wbSource = Workbooks.Open(sourcePath & fileName) Set wbTarget = Workbooks.Add ' 复制工作表优化 For Each wsSource In wbSource.Worksheets newName = GenerateUniqueName(wbTarget, wsSource.Name) ' 安全添加工作表 Set wsTarget = wbTarget.Worksheets.Add( _ After:=wbTarget.Worksheets(wbTarget.Worksheets.Count)) wsTarget.Name = newName ' 复制数据 wsSource.UsedRange.Copy wsTarget.Range("A1").PasteSpecial xlPasteAll wsTarget.Range("A1").PasteSpecial xlPasteColumnWidths Next ' 保存优化 wbTarget.SaveAs targetPath & baseName & "-1." & FSO.GetExtensionName(fileName), _ FileFormat:=wbSource.FileFormat wbTarget.Close False wbSource.Close False fileName = Dir Loop Cleanup: Application.ScreenUpdating = True MsgBox "处理完成!共处理 " & FSO.GetFolder(sourcePath).Files.Count & " 个文件", vbInformation Exit Sub ErrorHandler: MsgBox "错误 " & Err.Number & ": " & Err.Description, vbCritical Resume Cleanup End Sub ' 生成唯一名称函数 Function GenerateUniqueName(wb As Workbook, rawName As String) As String Dim cleanName As String, suffix As Integer: suffix = 1 ' 清理非法字符 cleanName = Replace(rawName, ":", "") cleanName = Replace(cleanName, "\", "") cleanName = Left$(cleanName, 31) ' 检查唯一性 Do While WorksheetExists(wb, cleanName) cleanName = Left$(cleanName, 28) & "_" & suffix suffix = suffix + 1 Loop GenerateUniqueName = cleanName End Function ' 存在性检查函数 Function WorksheetExists(wb As Workbook, sName As String) As Boolean On Error Resume Next WorksheetExists = Not wb.Worksheets(sName) Is Nothing On Error GoTo 0 End Function
05-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值