Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何减少内存使用,搜索序列中的第k个字符?_String_Algorithm_Memory_Out Of Memory - Fatal编程技术网

String 如何减少内存使用,搜索序列中的第k个字符?

String 如何减少内存使用,搜索序列中的第k个字符?,string,algorithm,memory,out-of-memory,String,Algorithm,Memory,Out Of Memory,问题陈述: 一位老师曾经说过:“好文章就是好文章就是好文章。” 因此,老师定义f0=“好文章就是好文章。” 为了使引语更有趣,老师定义fn=“好的写作是好的”+fn−1+“写作很好”+fn−1+“写得很好。”对所有人来说≥一, 例如,f1是: 好文章就是好文章就是好文章。写作是好的写作是好的写作是好的写作。写得很好。 请注意,引号不是f1的一部分 老师想问q问题。每次她都想找到fn的第k个角色。 字符的索引从1开始。如果fn包含少于k个字符,则输出 在所有测试中 一,≤Q≤十, 0≤N≤三十 一

问题陈述:

一位老师曾经说过:“好文章就是好文章就是好文章。” 因此,老师定义f0=“好文章就是好文章。” 为了使引语更有趣,老师定义fn=“好的写作是好的”+fn−1+“写作很好”+fn−1+“写得很好。”对所有人来说≥一,

例如,f1是:

好文章就是好文章就是好文章。写作是好的写作是好的写作是好的写作。写得很好。

请注意,引号不是f1的一部分

老师想问q问题。每次她都想找到fn的第k个角色。 字符的索引从1开始。如果fn包含少于k个字符,则输出

在所有测试中

一,≤Q≤十,

0≤N≤三十

一,≤K≤231−一,

例如:

输入:

3
0 4
1 100
1 1111111
3
0 6  
1 13
1 22
输出:

d
g
.
w

G
输入:

3
0 4
1 100
1 1111111
3
0 6  
1 13
1 22
输出:

d
g
.
w

G
我的问题:

到目前为止,我所做的只是创建一个数组来存储f0到f31的预计算字符串

        String[] f = new String[31];
        f[0] = "Good writing is good writing is good writing.";
        f[1] = "Good writing is good Good writing is good writing is good writing. writing is good Good writing is good writing is good writing. is good writing.";
        for(int i = 2; i < 31; i++) {
            f[i] = "Good writing is good " + f[i-1] + " writing is good " + f[i-1] + " is good writing.";
        }
String[]f=新字符串[31];
f[0]=“好文章就是好文章就是好文章。”;
f[1]=“好文章就是好文章就是好文章。好文章就是好文章。好文章就是好文章。好文章就是好文章。好文章就是好文章。”;
对于(int i=2;i<31;i++){
f[i]=“好的写作是好的”+f[i-1]+“写作是好的”+f[i-1]+“是好的写作。”;
}
预计算最大值31后,我查询输入:

        while(q-->0) {
            int n = readInt();
            int k = readInt();
            System.out.println(f[n]);
            if(f[n].length() < k) {
                System.out.println(".");
            } else {
                System.out.println(f[n].charAt(k-1));
            }
        }
while(q-->0){
int n=readInt();
int k=readInt();
System.out.println(f[n]);
if(f[n].length()

现在的问题是,当我这样做的时候,我得到了一个内存不足的错误。这让我想到有一种更快更简单的方法来回答这个问题。我觉得有一种模式,但我可能错了。有什么想法吗?

一个想法是确定第k个字符在添加的部分中的位置。为此,除了第k个字符外,我们可以使前一个调用返回其结果的长度,而不是结果本身。然后我们就可以决定kth落在什么地方。以下代码还返回字符串,但仅用于演示

您可以看到,在我们的函数中,
f(n,k)
,若我们确定第k个字符落在
f(n-1)
的一个部分中,我们从
k
中减去前面部分/s的长度,并从
f(n-1,k-前缀的长度)
中获得
kth
,因为这就像查找(新)kth-inside
f(n-1)
。我们根据需要递归执行该搜索

JavaScript代码:

//返回[len\u fn,kth,fn]
函数f(n,k){
const f_0=“好文章就是好文章。”
常数len_0=f_0.length
const str_1=“好的写作是好的”
const str_2=“写作很好”
const str_3=“是一篇好文章。”
常数len_1=str_1.length
常量len_2=str_2.length
常量len_3=str_3.length
如果(n==0)
返回[len_0,f_0[k-1],f_0]
常数[len_fn1,kth1,fn1]=f(n-1)
常数fn=str_1+fn1+str_2+fn1+str_3
常数len_fn=len_1+len_fn1+len_2+len_fn1+len_3
常数pos_fn1_2=长度1+len_fn1+len_2

if(k)请注意,每个字符串的长度是前一个字符串的两倍以上。f30的长度为几十GB。@BenVoigt谢谢你,但再一次,你认为有更有效的方法吗?我建议改为:建立一个fi长度表,即字符串中前一个字符串(fi-1)所在的点第一次出现,第二次出现的点。@BenVoigt by fi你是说fn吗?我是说
f[I]
就像在循环准备中一样,而不是
f[n]
where
n=readInt()
你能解释一下这些代码部分吗?我对JavaScript
const[len_fn1,kth1,fn1]=f不太熟悉(n-1)
console.log(JSON.stringify(fn.split(“”).map((x,i)=>[i+1,x]))
@TimothyW553当然。
const[len_fn1,kth1,fn1]=f(n-1)
:由于函数
f
返回一个由三项组成的数组,该数组会立即将它们分配给三个变量,
len_fn1,kth1,fn1
。您询问的第二个变量,
console.log(JSON.stringify(fn.split(“”.map((x,i)=>[i+1,x]))
将长字符串结果
fn
记录为元组列表,这样我们可以看到每个字符的索引,更容易确认函数返回的答案是否正确。@TimothyW553我稍微修改了代码,在结果之后手动记录索引字符串,而不是作为递归的一部分。