0

I am currently training with the following programming exercise: "Without repeats". The statement explains the following:

Given a String of words, return a String with all repeated words replaced with the appropriate numbers of underscores. For example, if the given String was: Here here here we go! Go w'e!?.

The expected output would be: Here __ __ we go! __ __

Notice how punctuation (commas, periods, etc.) and case are ignored for determining whether a word has been used, but they still show up in the final String.

I have thought the following in pseudocode:

Remove all special characters and get just alphabetic ones
Split words by space
For each word
  if word is not in result
    add the word into result
  else
    add underscores as needed
return result

In Java I wrote the following code:

import java.util.*;

public class RepeatDelete
{
   public static String withoutRepeats /**/(String s)
   {
      //System.out.println("s: "+s); 
      List<String> uniques = new ArrayList<String>();
      List<String> result = new ArrayList<String>();
      String[] words = s.split(" ");
      //System.out.println("words: "+Arrays.toString(words)); 
      for(int i = 0, j = 0; i < words.length; i++){
        String word = words[i];
        String alphabetic = word.replaceAll("[^A-Za-z]","");
        //System.out.println("alphabetic: "+alphabetic); 
        for(; j < uniques.size(); j++){
          String unique = uniques.get(j);
          if(unique.toLowerCase().equals(alphabetic.toLowerCase())){
            result.add("_".repeat(word.length()));
            break;
          }
        }
        if(j == uniques.size()){
          result.add(word);
          uniques.add(alphabetic.toLowerCase());
        }
      }
      System.out.println("uniques: "+Arrays.toString(uniques.toArray()));
      return String.join(" ",result.toArray(new String[0]));
   }
}

And the test case (taken from the exercise):

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ExampleTest
{
   @Test public void FixedTest1()
   {
      String lyrics="Here here here we go!\n"+
         "\n"+
         "So they're finally here, performing for you\n"+
         "If you know the words, you can join in too\n"+
         "Put your hands together, if you want to clap\n"+
         "As we take you through this monkey rap!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "\n"+
         "\n"+
         "He's the leader of the bunch, you know him well\n"+
         "He's finally back to kick some tail\n"+
         "His coconut gun can fire in spurts\n"+
         "If he shoots ya, it's gonna hurt!\n"+
         "He's bigger, faster, and stronger too\n"+
         "He's the first member of the DK crew!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "DK\n"+
         "Donkey Kong is here!\n"+
         "\n"+
         "\n"+
         "This Kong's got style, so listen up dudes\n"+
         "She can shrink in size, to suit her mood\n"+
         "She's quick and nimble when she needs to be\n"+
         "She can float through the air and climb up trees!\n"+
         "If you choose her, you'll not choose wrong\n"+
         "With a skip and a hop, she's one cool Kong!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "\n"+
         "\n"+
         "He has no style, he has no grace\n"+
         "Th-this Kong has a funny face\n"+
         "He can handstand when he needs to\n"+
         "And stretch his arms out, just for you\n"+
         "Inflate himself just like a balloon\n"+
         "This crazy Kong just digs this tune!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "DK\n"+
         "Donkey Kong is here!\n"+
         "\n"+
         "\n"+
         "He's back again and about time too\n"+
         "And this time he's in the mood\n"+
         "He can fly real high with his jetpack on\n"+
         "With his pistols out, he's one tough Kong!\n"+
         "He'll make you smile when he plays his tune\n"+
         "But Kremlings beware 'cause he's after you!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "Finally, he's here for you\n"+
         "It's the last member of the DK crew!\n"+
         "This Kong's so strong, it isn't funny\n"+
         "Can make a Kremling cry out for mummy\n"+
         "Can pick up a boulder with relative ease\n"+
         "Makes crushing rocks seem such a breeze\n"+
         "He may move slow, he can't jump high\n"+
         "But this Kong's one hell of a guy!\n"+
         "\n"+
         "\n"+
         "C'mon Cranky, take it to the fridge!\n"+
         "\n"+
         "\n"+
         "Walnuts, peanuts, pineapple smells\n"+
         "Grapes, melons, oranges and coconut shells\n"+
         "Aww yeah!\n"+
         "Walnuts, peanuts, pineapple smells\n"+
         "Grapes, melons, oranges and coconut shells\n"+
         "Aww yeah!";
      String without="Here ____ ____ we go!\n"+
         "\n"+
         "So they're finally _____ performing for you\n"+
         "If ___ know the words, ___ can join in too\n"+
         "Put your hands together, __ ___ want to clap\n"+
         "As __ take ___ through this monkey rap!\n"+
         "Huh!\n"+
         "\n"+
         "\n"+
         "DK\n"+
         "Donkey Kong!\n"+
         "\n"+
         "\n"+
         "He's ___ leader of ___ bunch, ___ ____ him well\n"+
         "____ _______ back __ kick some tail\n"+
         "His coconut gun ___ fire __ spurts\n"+
         "__ he shoots ya, it's gonna hurt!\n"+
         "____ bigger, faster, and stronger ___\n"+
         "____ ___ first member __ ___ __ crew!\n"+
         "____\n"+
         "\n"+
         "\n"+
         "__\n"+
         "______ _____\n"+
         "__\n"+
         "______ ____ is _____\n"+
         "\n"+
         "\n"+
         "____ Kong's got style, __ listen up dudes\n"+
         "She ___ shrink __ size, __ suit her mood\n"+
         "She's quick ___ nimble when ___ needs __ be\n"+
         "___ ___ float _______ ___ air ___ climb __ trees!\n"+
         "__ ___ choose ____ you'll not ______ wrong\n"+
         "With a skip ___ _ hop, _____ one cool _____\n"+
         "____\n"+
         "\n"+
         "\n"+
         "__\n"+
         "______ _____\n"+
         "\n"+
         "\n"+
         "__ has no ______ __ ___ __ grace\n"+
         "Th-this ____ ___ _ funny face\n"+
         "__ ___ handstand ____ __ _____ __\n"+
         "___ stretch ___ arms out, just ___ ___\n"+
         "Inflate himself ____ like _ balloon\n"+
         "____ crazy ____ ____ digs ____ tune!\n"+
         "____\n"+
         "\n"+
         "\n"+
         "__\n"+
         "______ _____\n"+
         "__\n"+
         "______ ____ __ _____\n"+
         "\n"+
         "\n"+
         "____ ____ again ___ about time ___\n"+
         "___ ____ ____ ____ __ ___ ____\n"+
         "__ ___ fly real high ____ ___ jetpack on\n"+
         "____ ___ pistols ____ ____ ___ tough _____\n"+
         "He'll make ___ smile ____ __ plays ___ ____\n"+
         "But Kremlings beware 'cause ____ after ____\n"+
         "____\n"+
         "\n"+
         "\n"+
         "__\n"+
         "______ _____\n"+
         "____\n"+
         "\n"+
         "\n"+
         "________ ____ ____ ___ ___\n"+
         "____ ___ last ______ __ ___ __ _____\n"+
         "____ ______ __ strong, it isn't _____\n"+
         "___ ____ _ Kremling cry ___ ___ mummy\n"+
         "___ pick __ _ boulder ____ relative ease\n"+
         "Makes crushing rocks seem such _ breeze\n"+
         "__ may move slow, __ can't jump ____\n"+
         "___ ____ ______ ___ ____ __ _ guy!\n"+
         "\n"+
         "\n"+
         "C'mon Cranky, ____ __ __ ___ fridge!\n"+
         "\n"+
         "\n"+
         "Walnuts, peanuts, pineapple smells\n"+
         "Grapes, melons, oranges ___ _______ shells\n"+
         "Aww yeah!\n"+
         "________ ________ _________ ______\n"+
         "_______ _______ _______ ___ _______ ______\n"+
         "___ _____";
      assertEquals(without, RepeatDelete.withoutRepeats(lyrics));
   }

We see that the test expects:

expected:<...
So they're finally [_____ performing for you
If ___ know the words, ___ can join in too
Put your hands together, __ ___ want to clap
As __ take ___ through this monkey rap!
Huh!


DK
Donkey Kong!


He's ___ leader of ___ bunch, ___ ____ him well
____ _______ back __ kick some tail
His coconut gun ___ fire __ spurts
__ he shoots ya, it's gonna hurt!
____ bigger, faster, and stronger ___
____ ___ first member __ ___ __ crew!
____


__
______ _____
__
______ ____ is _____


____ Kong's got style, __ listen up dudes
She ___ shrink __ size, __ suit her mood
She's quick ___ nimble when ___ needs __ be
___ ___ float _______ ___ air ___ climb __ trees!
__ ___ choose ____ you'll not ______ wrong
With a skip ___ _ hop, _____ one cool _____
____


__
______ _____


__ has no ______ __ ___ __ grace
Th-this ____ ___ _ funny face
__ ___ handstand ____ __ _____ __
___ stretch ___ arms out, just ___ ___
Inflate himself ____ like _ balloon
____ crazy ____ ____ digs ____ tune!
____


__
______ _____
__
______ ____ __ _____


____ ____ again ___ about time ___
___ ____ ____ ____ __ ___ ____
__ ___ fly real high ____ ___ jetpack on
____ ___ pistols ____ ____ ___ tough _____
He'll make ___ smile ____ __ plays ___ ____
But Kremlings beware 'cause ____ after ____
____


__
______ _____
____


________ ____ ____ ___ ___
____ ___ last ______ __ ___ __ _____
____ ______ __ strong, it isn't _____
___ ____ _ Kremling cry ___ ___ mummy
___ pick __ _ boulder ____ relative ease
Makes crushing rocks seem such _ breeze
__ may move slow, __ can't jump ____
___ ____ ______ ___ ____ __ _ guy!


C'mon Cranky, ____ __ __ ___ fridge!


Walnuts, peanuts, pineapple smells
Grapes, melons, oranges ___ _______ shells
Aww yeah!
________ ________ _________ ______
_______ _______ _______ ___ _______ ______
___ _____]>

However, the code outputs:

but was:<...
So they're finally [here, performing for you
If you know the words, you can join in too
Put your hands together, if you want to clap
As we take you through this monkey rap!
Huh!


DK
Donkey Kong!


He's the leader of the bunch, you know him well
He's finally back to kick some tail
His coconut gun can fire in spurts
If he shoots ya, it's gonna hurt!
He's bigger, faster, and stronger too
He's the first member of the DK crew!
Huh!


DK
Donkey Kong!
DK
Donkey Kong is here!


This Kong's got style, so listen up dudes
She can shrink in size, to suit her mood
She's quick and nimble when she needs to be
She can float through the air and climb up trees!
If you choose her, you'll not choose wrong
With a skip and a hop, she's one cool Kong!
Huh!


DK
Donkey Kong!


He has no style, he has no grace
Th-this Kong has a funny face
He can handstand when he needs to
And stretch his arms out, just for you
Inflate himself just like a balloon
This crazy Kong just digs this tune!
Huh!


DK
Donkey Kong!
DK
Donkey Kong is here!


He's back again and about time too
And this time he's in the mood
He can fly real high with his jetpack on
With his pistols out, he's one tough Kong!
He'll make you smile when he plays his tune
But Kremlings beware 'cause he's after you!
Huh!


DK
Donkey Kong!
Huh!


Finally, he's here for you
It's the last member of the DK crew!
This Kong's so strong, it isn't funny
Can make a Kremling cry out for mummy
Can pick up a boulder with relative ease
Makes crushing rocks seem such a breeze
He may move slow, he can't jump high
But this Kong's one hell of a guy!


C'mon Cranky, take it to the fridge!


Walnuts, peanuts, pineapple smells
Grapes, melons, oranges and coconut shells
Aww yeah!
Walnuts, peanuts, pineapple smells
Grapes, melons, oranges and coconut shells
Aww yeah!]>

I understand that the code is inserting into result a repeated "here", but why?

As you would notice, "here" has been already added to uniques, so then it should be not added into result!

Could you help me please?

I have also read:

How would you debug this code, or even propose a simpler approach?

How could we replace repeated words by underscores, Java‽

EDIT: After trying to understand @kevin ternet answer, and not copying it, I have coded:

import java.util.*;

public class RepeatDelete
{
   public static String withoutRepeats(String s)
   {
      String[] words = s.split(" ");
      List<String> result = new ArrayList<String>(Arrays.asList(words));
      return String.join(" ",replaceRepeatedWords(result, 0));
   }
   public static List<String> replaceRepeatedWords(List<String> result, int i){
     String originalWord = result.get(i);
     Collections.replaceAll(result, result.get(i), "_".repeat(result.get(i).length()));
     result.set(i, originalWord);
     if(i == result.size() - 1){
       return result;
     }
     return replaceRepeatedWords(result, i+1);
   }
}

Which instead of replacing all repeated words with underscores, it replaces the last one.

Given:

"Here here here we go!\n"

It outputs:

Here here ____ we go!

Instead of:

Here ____ ____ we go!

Enoy
  • 1,724
  • 3
  • 19
  • 39

2 Answers2

1

Without running your code I can't see anything obvious that stands out, however I would propose you write it in a simpler way so that it will be easier for you to debug:

The JDK provides some classes that will make your life easier, for instance the List of unique words would be better implemented as a Set<String>, then you don't need your second nested loop since you can simply ask it if (uniques.contains(alphabetic)). (As a bonus, testing it this way offers better performance, although performance shouldn't be your concern right now). You can also use a for-each loop instead of using numeric indexes:

for (String word : words.split(" ") {
    String alphabetic = word.replaceAll("...");
    // ...
}

Most people would agree that this "reads" better as a human, and readable code is a lot easier to debug and work with.

I'd also recommend using a StringBuilder to build up your output string, instead of another List. This is pretty much the use-case that it was designed for.

StringBuilder output = new StringBuilder();
output.append(word);
// etc...
System.out.println(output.toString());

Good luck, i think you have the right approach, but there are cleaner (and easier) ways to implement it. Be sure to use an IDE that allows you to set breakpoints and step through the running code line-by-line.

Stik
  • 337
  • 3
  • 14
0

Or shorter on this basis with Stream and a little recursivity :

public static void main(String[] args) {

     String lyrics="Here here here we go!\n";
     String[] tableau = lyrics.split(" ");
     List<String> liste = Arrays.stream(tableau).map(String::toLowerCase).collect(Collectors.toList());
     System.out.println(liste);
     play(liste, 0);
     System.out.println(liste);
}
public static void play (List<String> phrase, int i) {
    if (i <phrase.size()- 1) {
        String mot = phrase.get(i);
        String repeat = mot.replaceAll("[a-z]", "_");
        Collections.replaceAll(phrase, mot, repeat);
        phrase.set(i, mot);
        play(phrase, i+1);
    }
}

output :

[here, here, here, we, go! ]

[here, ____, ____, we, go! ]

kevin ternet
  • 3,779
  • 2
  • 14
  • 23