Is it possible to group a string every nth character?
For example, suppose I have a string containing the following: "Hello how are you"
What I'm trying to do is if the user inputs 4, then based on the integer, break into 4 groups and assign those to strings.
1 2 3 4 1 2 3 4 1 2 3 4 1 2
H E L L O H O W A R E Y O U
All the letters that has 1 assigned will be group 1, similarly, all the letters that has 2 assigned will be group 2.
Group 1 - "HOAO", Group 2 - "EHRU", Group 3 - "LOE", Group 4 - "LWY"
Below is what I have so far
import java.util.*;
class groupChar {
static void groupLetters(String str, int n) {
String result="";
for(int i = 0; i < str.length(); i = i n){
result = result str.charAt(i);
}
System.out.println(result);
}
public static void main(String[] args) {
Scanner inputMessage = new Scanner(System.in);
System.out.println("Enter string : ");
String message = inputMessage.nextLine();
System.out.println("Enter a number : ");
Scanner inputNumber = new Scanner(System.in);
int number = Integer.parseInt(inputNumber.nextLine());
System.out.println("String is - " message);
System.out.println("Number is - " number);
groupLetters(message, number);
}
}
So far I'm only able to create one group based on the user input.
CodePudding user response:
You can approach this problem using Map
to track all the groups and using StringBuilder
to construct the individual group.
Firstly, we need to generate a HashMap
populated with entries having the keys corresponding to the indices of the groups and empty StringBuilder
s as *values.
Then we have to iterate over the given string, maintaining two indices: i
- position in the string and groupId
- index of the group. At iteration step, we need to update the current group by appending the current character.
That's how it can be implemented:
public static Map<Integer, StringBuilder> groupLetters(String str, int n) {
Map<Integer, StringBuilder> groupByGroupId = createGroups(n);
for (int i = 0, groupId = 1; i < str.length(); i , groupId = (groupId % n) 1) {
groupByGroupId.get(groupId).append(str.charAt(i));
}
return groupByGroupId;
}
public static Map<Integer, StringBuilder> createGroups(int n) {
Map<Integer, StringBuilder> groupByGroupId = new HashMap<>();
for (int i = 1; i <= n; i ) {
groupByGroupId.put(i, new StringBuilder());
}
return groupByGroupId;
}
main
public static void main(String[] args) {
for (Map.Entry<Integer, StringBuilder> entry: groupLetters("hellohowareyou", 4).entrySet()) {
System.out.println("Group " entry.getKey() " -> " entry.getValue());
}
}
Output:
Group 1 -> hoao
Group 2 -> ehru
Group 3 -> loe
Group 4 -> lwy
CodePudding user response:
The suggested solution would be to use a map or dictionary with <int,List>. But I recommend the most simple and understandable way without using Map based on your code.
I used the same example as you provided, but starting from 0 would make it easier to understand the code.
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 1 2 3 0 1 2 3 0 1 2 3 0 1
H E L L O H O W A R E Y O U
The Algorithm:
- Group 1 : 0,(0 (1 x 4)),(0 (2 x 4)),(0 (3 x 4)) ...
- Group 2 : 1,(1 (1 x 4)),(1 (2 x 4)),(1 (3 x 4)) ...
- Group 3 : 2,(2 (1 x 4)),(2 (2 x 4)),(2 (3 x 4)) ...
Therefore, Group a 1 : a, (a (1 x N)), (a (2 x N)), (a (3 x N))... WHERE the total number of elements in each group is
(total number of Char in string) / (number of droup) 1
Code
We used a for loop for a AND a for loop for the increment 1,2,3...
Therefore, I have modified your code to meet the requirement :
static void groupLetters(String str,int n) {
//Remove the string space and to UPPER CASE
str = str.toUpperCase().replaceAll("\\s ","");
for(int a = 0; a < n; a ){
String result = "";
//Get the Char in Group a with the algorithm mentioned above
for(int i = 0; i < str.length() / n 1; i ){
if(a (i * n) < str.length()){
result = result str.charAt(a (i * n));
}
}
System.out.println("Group " (a 1) ": " result);
}
}
public static void main(String[] args) {
Scanner inputMessage = new Scanner(System.in);
System.out.println("Enter string : ");
String message = inputMessage.nextLine();
System.out.println("Enter a number of group gonna break into : ");
Scanner inputNumber = new Scanner(System.in);
int number = Integer.parseInt(inputNumber.nextLine());
System.out.println("String is - " message);
System.out.println("Number of Group is - " number);
groupLetters(message,number);
}
OUTPUT:
String is - Hello how are you
Number of Group is - 4
Group 1: HOA
Group 2: EHR
Group 3: LOE
Group 4: LWY
CodePudding user response:
Splitter can be used to split text by length
com.google.common.base.Splitter , see -> https://www.geeksforgeeks.org/splitter-class-guava-java/
I slightly modified the code :
import java.util.Scanner;
import com.google.common.base.Splitter;
public class test {
public static String result="";
public static int index = 0;
static void groupLetters(String str, int n) {
str = str.replaceAll("\\s", "");
Iterable<String> fullString = Splitter.fixedLength(n).split(str);
int length = str.length() % n == 0 ? str.length() / n : (str.length() / n) 1;
for(int i = 0; i < length 1; i ){
fullString.forEach(s->{
if(s.length()>index){
result =s.charAt(index) "";
}
});
result =" ";
index ;
}
System.out.println(result);
}
public static void main(String[] args) {
Scanner inputMessage = new Scanner(System.in);
System.out.println("Enter string : ");
String message = inputMessage.nextLine();
System.out.println("Enter a number : ");
Scanner inputNumber = new Scanner(System.in);
int number = Integer.parseInt(inputNumber.nextLine());
System.out.println("String is - " message);
System.out.println("Number is - " number);
groupLetters(message, number);
}
}