制作字符串算法的问题

时间:2014-03-14 04:49:13

标签: algorithm greedy

给出由' a'组成的字符串。和' b'只是,允许的操作是删除" abb"的子字符串。如果从字符串出现。我的问题是在应用此操作后,任何时候都不能使字符串为空。我需要一个O(n)算法。

示例, abbabb - >是

aabbbb->是的,因为aabbbb-> abb->空

aaabbb->自aaabbb-> aab

以来没有

我现在所能想到的只是一个O(n ^ 2)算法,其中我使用substr()或find()逐步找到子串的位置,然后删除它直到字符串不为空或找不到& #34; ABB"在里面。

4 个答案:

答案 0 :(得分:3)

以下是我在评论中建议的一个示例:

for i = 0 to word.length-1
    if word[i] == 'b'
        if stack.empty() //no corresponding a
            return false
        if stack.top() == 'a' //first b after an a
            stack.push('b')
        else                  //second b after an a
            stack.pop()       //pop last two letters
            stack.pop()
    else
        stack.push('a')
return stack.empty()

可能存在一些需要检查的边界条件,当然在任何时候pop()失败都需要返回false。似乎正在为我发生的可能输入而努力。

我认为,需要在数学上证明的一点是我在" 之后评论"第二个b的部分。假设堆栈在开始时是空的,如果我没有错过任何看起来正确的点。

答案 1 :(得分:2)

没有必要存储除字符串末尾未使用的b对的数量,因为你从右到左阅读。 (并且它只解读了一次输入,因此O(n)时间为O(1)空间)这非常让人联想到为常规语言找到离散有限自动机。如果你看到两个b,请增加count。如果你看到一个b,添加一对(更新布尔变量并可能增加计数)。如果你看到a并且没有b对,则失败,否则count--。如果到达字符串的末尾并且没有额外的b,则字符串有效。

答案 2 :(得分:1)

使用两个计数器以避免使用堆栈。这是c ++实现希望它的工作原理。

bool canBeDone(string s)
{
int aCount = 0;
int bCount = 0;
for(int i=0;i<s.length();++i)
{
    if(s[i] == 'a')
    {
        aCount++;
        continue;
    }
    if(s[i] == 'b' && aCount == 0)
        return false;
    else
    {
        bCount += 1;
        if(bCount == 2)
        {
            bCount = 0;
            aCount--;
        }
    }
}
if(!aCount && !bCount)return true;
return false;
}

答案 3 :(得分:0)

在Erlang O(n)空间和时间中非常简单直接的实现(不幸的是,clwhisk algorithm需要clwhisk在Erlang中需要O(n)空间,因为{{1 }}):

lists:reverse/1

algorithm&#39; s {{3}}的C实现作为过滤器:

-module(abb).

-export([check/1, clwhisk/1, test/0]).

check(L) when is_list(L) ->
    check(L, []).

check(L, "bba" ++ T) -> check(L, T);
check([H|T], S) -> check(T, [H|S]);
check([], S) -> S =:= [].

clwhisk(L) when is_list(L) ->
    clwhisk(lists:reverse(L), 0).

clwhisk([$b|T], C) -> clwhisk(T, C+1);
clwhisk([$a|T], C) -> C >= 2 andalso clwhisk(T, C-2);
clwhisk(L, C) -> L =:= [] andalso C =:= 0.

test() ->
    true = abb:check("abbabb"),
    true = abb:check("aabbbb"),
    false = abb:check("aaabbb"),
    true = abb:check("ababbb"),
    true = abb:clwhisk("abbabb"),
    true = abb:clwhisk("aabbbb"),
    false = abb:clwhisk("aaabbb"),
    true = abb:clwhisk("ababbb"),
    ok.