Angel  Valenzuela
Angel Valenzuela

Reputation: 377

Remove all Adjacent duplicates using a loop

I'm trying to solve this problem. I have seen other solutions that involve lists and using recursion but I'm interested in learning how to solve this with loops and my problem is I can't get the last char to print out since it equals an empty variable.

input:abbabd
expected output:aabd

Code:

answer = input("enter a string: ")
new_answer = ""
p = ""
repeat = ""
len_answer = len(answer)
run = False

for c in answer:
    if c != p and run == False:
        new_answer += p
        p = c
        run = False

    elif c == p:
        p = c 
        run = True

    elif run == True and c != p:
        p = c 
        run = False 

    else: 
        new_answer += p


print(new_answer)

Upvotes: 3

Views: 191

Answers (5)

Girish Rathi
Girish Rathi

Reputation: 111

To solve this we are using a stack and doing for loop.

Time complexity for this is O(n).

    public class RemoveAdjacentDuplicates {

        public static void main(String[] args) {
            System.out.println(removeDuplicates("abbabd"));
        }

         public static String removeDuplicates(String S) {
             char[] stack = new char[S.length()];

             int i = 0;

             for(int j = 0 ; j < S.length() ; j++) {

                 char currentChar = S.charAt(j);
                 if(i > 0 && stack[i-1] == currentChar) {
                     i--;
                 }else {
                     stack[i] = currentChar;
                     i++;
                 }

             }
             return new String(stack , 0 , i);
         }

    }

Result of the program is :

    input:abbabd
    output:aabd

Upvotes: 0

Chiheb Nexus
Chiheb Nexus

Reputation: 9257

Another approach using zip_longest from itertools and defaultdict modules:

from itertools import zip_longest
from collections import defaultdict

def remove_dup(iterable):
    # seen[0] will be for non adjacent duplicates
    # the other indexes will be used in comparisons                 
    seen = defaultdict(list)
    seen[0], index = [''], 1
    for k, v in zip_longest(iterable, iterable[1:]):
        if not seen[index]:
            seen[index] = ['']
        # Here we compare with the last element of seen[index]
        # in order to escape multiples successive adjacent chars
        if k != v and k != seen[0][-1] and k != seen[index][-1]:
            # adding index to escape the scenario
            # where the last char of the previous index
            # is the same as the actual index
            index += 1
            seen[0] += [k]
        else:
            # add chars for further comparison in another index
            seen[index] += [k]

    return ''.join(seen[0])


# test:
tests = ['abbabd', 'aaabbbcdddeeefghkkkm', 'abbdddckkfghhhree', 'xaabx']
for test in tests:
    print('{} => {}'.format(test, remove_dup(test)))

Output:

abbabd => abd
aaabbbcdddeeefghkkkm => cfghm
abbdddckkfghhhree => acfgr
xaabx => xbx

Upvotes: 1

hygull
hygull

Reputation: 8740

@Angel, you can also try the below code to remove the adjacent duplicates from input string answer and return output string new_answer.

I have organized code inside a function remove_adjacent_duplicates() for code reusability and documented most of the lines using comments.

Try the code online at http://rextester.com/YWWFZ33548

def remove_adjacent_duplicates(answer):
    new_answer = ""    # output string
    ch_last = ""       # current character of last iteration
    start, end = 0, 0  # start and end indices of adjacent characters sequence

    for index, ch in enumerate(answer):
        if index: # for index 1 and onwards
            if ch == ch_last:
                end = index 
            else: # if new character encountered after repetition of any character
                if start == end: # if there is a repetition
                    new_answer = new_answer + ch_last
                start, end = index, index
        else:   # index == 0 (only 1st time)
            start, end = index, index

        ch_last = ch # save the current character to use it in next iteration

    if start == end: # if the last encountered character is not of repeating nature
        new_answer = new_answer + ch_last

    return new_answer

# START
if __name__ == "__main__":
    # INPUT 1
    answer = input("Enter a string: ")         # abbabd
    print(remove_adjacent_duplicates(answer))  # aabd

    # INPUT 2
    answer = input("Enter a string: ")         # abcddddeefffghii
    print(remove_adjacent_duplicates(answer))  # abcgh

    # INPUT 3
    answer = input("Enter a string: ")         # abcddddeefffghi
    print(remove_adjacent_duplicates(answer))  # abcghi    

    # INPUT 4
    answer = input("Enter a string: ")         # aa**mmmxxnnnnRaaI++SH((IKES))H
    print(remove_adjacent_duplicates(answer))  # RISHIKESH

Upvotes: 1

lenik
lenik

Reputation: 23538

The easiest way would be:

result = [[data[0], 1]]
for a in data[1:] :
    if a == result[-1][0] :
        result[-1][1] += 1
    else :
        result.append( [a,1] )

result = ''.join( [i[0] for i in result if i[1] == 1] )

Upvotes: 1

Blckknght
Blckknght

Reputation: 104722

All you need to fix your code is to add some extra code that runs after the end of the loop and adds p to the end of the result if necessary:

if not run:
    new_answer += p

You could simplify your loop a bit more though, if you combined some of the conditions. It can be pretty simple:

for c in answer:
    if c == p:
        loop = True          # no need for p = c in this case, they're already equal
    else:
        if not loop:
            new_answer += p
        loop = False
        p = c

You'll still need the lines from the first code block after this version of loop.

Upvotes: 2

Related Questions