Rohit Pathak
Rohit Pathak

Reputation: 67

Replace the multiple string with the other multiple string

I have strings like -

  1. yes, I have two, three, four numbers
  2. I have five, six, seven alphabets.
  3. eight, two, five are my lucky numbers.

and I also have Map

Map <String, String> wordToDigit = new HashMap<>;
Map.put("two", 2);
Map.put("three", 3);
Map.put("four", 4);
Map.put("five", 5);
Map.put("six", 6);
Map.put("eight",8);

I need to replace the words in a string with the corresponding value in the map. As each string does not contain all the keys, stored in a map. So, How can I do it more efficiently by iterating over the attribute which is the part of the string and not iterate over whole map?

In output :-

1. yes, I have 2, 3, 4 numbers.
2. I have 5, 6, 7 alphabets.
3. 8, 2, 5 are my lucky numbers. 

Upvotes: 1

Views: 105

Answers (2)

Arvind Kumar Avinash
Arvind Kumar Avinash

Reputation: 79035

Given below are two different implementations: (1) Using Map (2) Using List and array:

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {

    public static void main(String[] args) throws IOException {
        // Test
        String[] sentences = { "yes, I have two, three, four numbers.", "I have five, six, seven alphabets.",
                "eight, two, five are my lucky numbers.", "Someone gave him FIVE canines and asked him to feed two." };
        System.out.println("Using Map: ");
        for (String sentence : sentences) {
            System.out.println(replaceWordsWithValue1(sentence));
        }
        System.out.println("Using List and array: ");
        for (String sentence : sentences) {
            System.out.println(replaceWordsWithValue2(sentence));
        }
    }

    static String replaceWordsWithValue1(String str) {
        Map<String, String> wordToDigit = Map.of("two", "2", "three", "3", "four", "4", "five", "5", "six", "6",
                "seven", "7", "eight", "8", "nine", "9");
        for (String key : wordToDigit.keySet()) {
            Pattern pattern = Pattern.compile("\\b" + Pattern.quote(key) + "\\b", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(str);
            while (matcher.find()) {
                str = str.replaceAll(matcher.group(), wordToDigit.get(key));
            }
        }
        return str;
    }

    static String replaceWordsWithValue2(String str) {
        String[] values = { "2", "3", "4", "5", "6", "7", "8", "9" };
        List<String> keys = List.of("two", "three", "four", "five", "six", "seven", "eight", "nine");
        for (String key : keys) {
            Pattern pattern = Pattern.compile("\\b" + Pattern.quote(key) + "\\b", Pattern.CASE_INSENSITIVE);
            Matcher matcher = pattern.matcher(str);
            while (matcher.find()) {
                str = str.replaceAll(matcher.group(), values[keys.indexOf(key)]);
            }
        }
        return str;
    }
}

Output:

Using Map: 
yes, I have 2, 3, 4 numbers.
I have 5, 6, 7 alphabets.
8, 2, 5 are my lucky numbers.
Someone gave him 5 canines and asked him to feed 2.
Using List and array: 
yes, I have 2, 3, 4 numbers.
I have 5, 6, 7 alphabets.
8, 2, 5 are my lucky numbers.
Someone gave him 5 canines and asked him to feed 2.

The logic in both the implementations is straightforward.

Upvotes: 1

RaffleBuffle
RaffleBuffle

Reputation: 5455

I would split the sentence up into words and then rebuild the sentence, using your map to check if each word has a numeric version, and if it does using that in place of the word.

The trick is to add the delimiters back in, as these aren't included by the standard String.split method.

Map <String, Integer> wordToDigit = new HashMap<>();
wordToDigit.put("two", 2);
wordToDigit.put("three", 3);
wordToDigit.put("four", 4);
wordToDigit.put("five", 5);
wordToDigit.put("six", 6);
wordToDigit.put("eight",8); 

String sentence = "yes, I have two, three, four numbers";

String[] words = sentence.split("[^a-zA-Z]+", -1);

int pos = 0;
StringBuilder sb = new StringBuilder();
for(String word : words)
{
    int idx = sentence.indexOf(word, pos);
    String delim = sentence.substring(pos, idx);
    sb.append(delim);        

    Integer n = wordToDigit.get(word.toLowerCase());
    sb.append(n == null ? word : n);

    pos += delim.length() + word.length();      
}
sb.append(sentence.substring(pos, sentence.length()));        

System.out.println(sb);

Output:

yes, I have 2, 3, 4 numbers

and for the other 2 sentences

I have 5, 6, seven alphabets
8, 2, 5 are my lucky numbers.

Upvotes: 1

Related Questions