简体   繁体   English

解决字符串约简算法

[英]Solving String reduction Algorithm

I am preparing myself for an interview that I have on monday and I found this problem to resolve called " String Reduction ". 我正在准备周一进行的一次采访,我发现这个名为“ String Reduction ”的问题得以解决。 The problem is stated like this : 问题是这样说的:

Given a string consisting of a,b and c's, we can perform the following operation: Take any two adjacent distinct characters and replace it with the third character. 给定一个包含a,b和c的字符串,我们可以执行以下操作:取任意两个相邻的不同字符并将其替换为第三个字符。 For example, if 'a' and 'c' are adjacent, they can replaced with 'b'. 例如,如果“ a”和“ c”相邻,则可以将其替换为“ b”。 What is the smallest string which can result by applying this operation repeatedly? 重复应用此操作可导致的最小字符串是多少?

For instance, cab -> cc or cab -> bb, resulting in a string of length 2. For this one, one optimal solution is: bcab -> aab -> ac -> b. 例如,cab-> cc或cab-> bb,得到一串长度为2的字符串。为此,一种最佳解决方案是:bcab-> aab-> ac-> b。 No more operations can be applied and the resultant string has length 1. If the string is = CCCCC, no operations can be performed and so the answer is 5. 不能再应用任何操作,并且结果字符串的长度为1。如果字符串为= CCCCC,则无法执行任何操作,因此答案为5。

I have seen a lot questions and answers on stackoverflow but I would like to verify my own algorithm. 我在stackoverflow上看到了很多问题和答案 ,但我想验证自己的算法。 Here is my algorithm in pseudo code. 这是我的伪代码算法。 In my code 用我的代码

  1. S is my string to reduce S是我减少的弦
  2. S[i] is the character at index i S [i]是索引i处的字符
  3. P is a stack: P是一个堆栈:
  4. redux is the function that reduces the characters. redux是减少字符的功能。

     function reduction(S[1..n]){ P = create_empty_stack(); for i = 1 to n do car = S[i]; while (notEmpty(P)) do head = peek(p); if( head == car) break; else { popped = pop(P); car = redux (car, popped); } done push(car) done return size(P)} 

The worst-case of my algorithms is O(n) because all the operations on the stack P is on O(1). 我的算法最坏的情况是O(n),因为堆栈P上的所有操作都在O(1)上。 I tried this algorithm in the examples above, I get the expected answers. 我在上面的示例中尝试了该算法,得到了预期的答案。 Let me execute my algo with this example " abacbcaa " : 让我用以下示例“ abacbcaa ”执行算法:

i = 1 :
   car = S[i] = a, P = {∅}
   P is empty, P = P U {car} -> P = {a}

 i = 2 :
   car = S[i] = b, P = {a}
   P is not empty :
       head = a
       head != car ->
            popped = Pop(P) = a 
            car = reduction (car, popped) = reduction (a,b) = c
            P = {∅}

    push(car, P) -> P = {c}



i = 3 :
   car = S[i] = a, P = {c}
   P is not empty :
       head = c
       head != car ->
            popped = Pop(P) = c 
            car = reduction (car, popped) = reduction (a,c) = b
            P = {∅}

    push(car, P) -> P = {b}


 ...


 i = 5 : (interesting case)
  car = S[i] = c, P = {c}
   P is not empty :
       head = c
       head == car -> break

    push(car, P) -> P = {c, c}


 i = 6 :
  car = S[i] = b, P = {c, c}
   P is not empty :
       head = c
       head != car ->
            popped = Pop(P) = c 
            car = reduction (car, popped) = reduction (b,c) = a
            P = {c}

   P is not empty : // (note in this case car = a)
       head = c
       head != car ->
            popped = Pop(P) = c 
            car = reduction (car, popped) = reduction (a,c) = b
            P = {∅}
    push(car, P) -> P = {b}

... and it continues until n

I have run this algorithm on various examples like this, it seems to work. 我已经在像这样的各种示例上运行了该算法,它似乎可以工作。 I have written a code in Java that test this algorithm, when I submit my code to the system, I am getting wrong answers. 我已经用Java编写了代码来测试该算法,当我将代码提交给系统时,我得到了错误的答案。 I have posted the java code on gisthub so you can see it. 我在gisthub上发布了Java代码,因此您可以看到它。

Can someone tell me what is wrong with my algorithm. 有人可以告诉我我的算法有什么问题吗?

I am going to try to explain what nhahtdh means. 我将尝试解释nhahtdh含义。 There are multiple reasons why your algorithm fails. 您的算法失败的原因有多种。 But the most fundamental one is that at each point in time, only the first character observed has a chance to be pushed on the stack p . 但最基本的是,在每个时间点,只有观察到的第一个字符才有机会被压入堆栈p It should not be this way, as you can start a reduction basically from any position. 不应该这样,因为您基本上可以从任何位置开始减少。

Let me give you the string abcc . 让我给你字符串abcc If I breakpoint at 如果我在

car = S[i];

The algo run as : 该算法的运行方式为:

p = {∅}, s = _abcc //underscore is the position
p = {a}, s = a_bcc  
p = {c}, s = ab_cc  

At this point you are stuck with a reduction ccc 在这一点上,您降低了ccc

But there is another reduction : abcc -> aac ->ab ->c 但是还有另一种减少: abcc -> aac ->ab ->c

Besides, returning the size of the stack P is wrong. 此外,返回堆栈P的大小是错误的。 cc cannot be reduced, but the algorithm will return 1 . cc不能减少,但是算法将返回1 You should also count the number of times you skip. 您还应该计算跳过的次数。

you can also solve this question using brute force...and recursion 您也可以使用蛮力...和递归来解决此问题

for all n-1 pairs(2 char) replace it with 3rd char if possible and apply reduce on this new string of length n-1
    for all n-2 pairs replace it with 3rd char and apply reduce on new string
         for all n-3 pairs....and so on

The new string of length n-1 will have n-2 pairs and similarly new string of length n-2 will have n-3 pairs. 长度为n-1的新字符串将具有n-2对,同样,长度为n-2的新字符串将具有n-3对。

while applying this approach keep storing the minimum value 在应用此方法时,请保持最小值

if (new_min < min)
    min = new_min

Implementation: http://justprogrammng.blogspot.com/2012/06/interviewstreet-challenge-string.html 实施: http//justprogrammng.blogspot.com/2012/06/interviewstreet-challenge-string.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM