Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.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
Java 如何优化此算法?与chars一起工作_Java - Fatal编程技术网

Java 如何优化此算法?与chars一起工作

Java 如何优化此算法?与chars一起工作,java,Java,任务:给我们两个长度相同的字符串,m和n。我们想把m修改成n。我们可以执行两个操作 我们可以获取当前字符串的一个连续段,并将该段中的每个字母在字母表中向前移动一次,或在字母表中向后移动一次 我们希望以最少的步骤完成这项工作,目标是一个O(n)算法 这是我的第一次尝试;显然,它甚至还没有达到优化的程度,但我对如何优化它有点迷茫。我不知道如何确定哪段信最好。目前,我的实现一次只完成一个字母 public static void shift(String m, String n) { char

任务:给我们两个长度相同的字符串,m和n。我们想把m修改成n。我们可以执行两个操作

我们可以获取当前字符串的一个连续段,并将该段中的每个字母在字母表中向前移动一次,或在字母表中向后移动一次

我们希望以最少的步骤完成这项工作,目标是一个O(n)算法

这是我的第一次尝试;显然,它甚至还没有达到优化的程度,但我对如何优化它有点迷茫。我不知道如何确定哪段信最好。目前,我的实现一次只完成一个字母

public static void shift(String m, String n) {
    char mChar[] = m.toCharArray();
    char nChar[] = n.toCharArray();

    int count = 0;
    for (int i = 0; i < m.length(); i++){
        while (mChar[i] != nChar[i]){
            if (mChar[i] - nChar[i] < 0){
                //System.out.println("SHIFT FORWARD");
                mChar[i]++;
                count++;
            }
            else{
                //System.out.println("SHIFT BACKWARD");
                mChar[i]--;
                count++;
            }
            System.out.println(mChar[i]);
        }
    }
    System.out.println(mChar);
    System.out.println(count);
}
公共静态无效移位(字符串m、字符串n){
char mChar[]=m.toCharArray();
char nChar[]=n.toCharArray();
整数计数=0;
对于(int i=0;i

这个算法的时间复杂度是多少?For循环使其最小为O(n),而while循环在最坏的情况下可以运行25次(如果我们有“y”并且想要“a”)。我这样想对吗?

既然你应该学习如何编程,我就不给你代码,但在这种情况下,我可以帮助你使用正确的算法

我将举例说明:

shift( "AAAAZZZZ", "BCDBZYYX" )
这里的目标是最小化移位操作的数量,因此需要优化正在移位的块大小

首先,确定每个字符所需的移位数:

A  A  A  A  Z  Z  Z  Z
B  C  D  B  Z  Y  Y  X
+1 +2 +3 +1 0  -1 -1 -2
从第一个位置开始,如果换档为正,则查找正换档的最大连续块。如果为负,则查找负移位块。实行轮班制。重复到零,然后转到下一个字符

1:索引0到3,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
2:索引1到2,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
3:索引2,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
4:索引5到7,下移:

B  C  D  B  Z  Y  Y  Y
0  0  0  0  0  0  0  -1
B  C  D  B  Z  Y  Y  X
0  0  0  0  0  0  0  0
5:索引7,下移:

B  C  D  B  Z  Y  Y  Y
0  0  0  0  0  0  0  -1
B  C  D  B  Z  Y  Y  X
0  0  0  0  0  0  0  0
在5班操作中完成

更新


优化:程序不需要提前或根本不需要“确定班次”。这主要是为了帮助说明算法。

既然你应该学习如何编程,我就不给你代码了,但在这种情况下,我可以帮助你使用正确的算法

我将举例说明:

shift( "AAAAZZZZ", "BCDBZYYX" )
这里的目标是最小化移位操作的数量,因此需要优化正在移位的块大小

首先,确定每个字符所需的移位数:

A  A  A  A  Z  Z  Z  Z
B  C  D  B  Z  Y  Y  X
+1 +2 +3 +1 0  -1 -1 -2
从第一个位置开始,如果换档为正,则查找正换档的最大连续块。如果为负,则查找负移位块。实行轮班制。重复到零,然后转到下一个字符

1:索引0到3,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
2:索引1到2,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
3:索引2,上移:

B  B  B  B  Z  Z  Z  Z
0  +1 +2 0  0  -1 -1 -2
B  C  C  B  Z  Z  Z  Z
0  0  +1 0  0  -1 -1 -2
B  C  D  B  Z  Z  Z  Z
0  0  0  0  0  -1 -1 -2
4:索引5到7,下移:

B  C  D  B  Z  Y  Y  Y
0  0  0  0  0  0  0  -1
B  C  D  B  Z  Y  Y  X
0  0  0  0  0  0  0  0
5:索引7,下移:

B  C  D  B  Z  Y  Y  Y
0  0  0  0  0  0  0  -1
B  C  D  B  Z  Y  Y  X
0  0  0  0  0  0  0  0
在5班操作中完成

更新


优化:程序不需要提前或根本不需要“确定班次”。这主要是为了帮助说明算法。

尽管@Andreas的答案是可行的,但不是O(N)。当你想知道最坏的情况时,你会在细节上考虑它

如何实施Andreas的回答 您需要知道间隙的大小,这样就不会改变索引的位置,而是块本身。有两个临时变量->
int startIndex,endIndex

首先是
startIndex=0,endIndex=-1
,然后当您看到符号更改时,更改
endIndex=i
,将块长度
i-startIndex
记录在
blockSize[]
追加中

然后,当您看到另一个更改时,
startIndex=endIndex
endIndex=i
,将
i-startIndex
记录在您的
blockSize[]
追加中

当你完成这项工作后,产生答案的代码块如下所示

思考 “我需要增加…最后4个块..让我们看看数组大小可能是N,让我们看看..好的,最后4个是最大的块,现在让我们增加最后4个”

现在为什么那么糟糕? 每次通过递增过程时,都需要通过大小为N的数组,这就是为什么它会导致N^2,明白我的意思吗?对于big Oh,你总是需要考虑字面上最坏的情况,在你的情况下是

[1, -1, 1, -1, 1, -1]
那你怎么办?您将创建一个

[1,1,1,1,1,1]
然后你必须通过这些间隙大小数组N次,找到最大的尺寸,实际上是它们中的任何一个,然后你要通过N次,找到最大的尺寸,通过一个N大小的交替数组,因此N^2

这里有另一种方法,但我不完全确定它是O(N)还是O(N*k),其中k是将一个字母一个字母移位所需的过程中的因子(因为您指定了)

当然,我的方法也有最坏的情况,如下所示:

[1, 4, 12, -3, -2, 3] let's say... 
1st. [0,3,11,-4,-3,2]
2nd. [0,0,8,-7,-6,-1]
3rd. [0,0,0,-15,-14,-9]
这将导致总共6次操作,但要增加的索引在过去3年中几乎翻了四倍。我不知道你是直接从a->z,还是a->b->c。。。如果是前者,那么我认为雪崩效应不会很明显

除此之外,我想不出任何O(N)运算,它要求k是常数

当有人回答一个关于大O计算速度的问题时,你应该始终想到这句话:

函数的一种描述,通常只用大O表示法 提供增长的上限