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.
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 StringBuilders 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
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
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);
}
}
problems will be there cause i want make Labels from text file and then put it into VBOX and i getting inputmismatchexception and it dont make new Object
VBox vertikalBox = new VBox();
try (Scanner s = new Scanner("rebricek.txt")) {
while (s.hasNext()) {
//InputMismatchException
vertikalBox.getChildren().addAll(new Label(""+ s.nextInt() + " " + s.next() + " " + s.nextInt()));
s.nextLine();
}
} catch (Throwable t) {
// inputmismatchexception - PROBLEM
// this is for NoSuchElementException
System.err.println("Vyskytla sa chyba pri praci zo suborom");
}
FILE content :
1 nikto 10
2 nikto 0
3 nikto 0
4 nikto 0
5 nikto 0
6 nikto 0
7 nikto 0
8 nikto 0
9 nikto 0
10 nikto 0
Your scanner is reading the string "rebrickek.txt" not a file
File file = new File("rebricek.txt");
if(file.exist())
{
Scanner s = new Scanner(file);
.
.
.
}
else
{
System.out.println("The file does note exist!");
}
This is my input file:
0 I 4325 <4214, 6> <4718, 9> <1203, 11>
18 L 4214 12 <4325, 6> <4718, 5> <1483, 9>
35 F 4109
I am trying to write a method that will read in the first column, second column (either I, L or F) and store all the pairs in each row e.g., (4214, 6), (4718, 9). What I've done is used the delimiter from the scanner class to get rid of '<', ',' and '>', and it does but when I try calling temp.next(), I keep on getting an error. My code is below (sometime the error goes away when I use skip(" "):
public void parseFile(Scanner input) {
int prevSeqNo = -1;
while (input.hasNextLine()) {
String line = input.nextLine();
if (!line.startsWith("#") && !line.isEmpty()) { // ignore comments
// and blank lines
Scanner temp = new Scanner(line).useDelimiter("<|,| |>"); // ignore all '<', ',' and '>'
// while(temp.hasNext())
// System.out.print(" " + temp.next() );
// System.out.println();
int timeStamp = temp.nextInt();
System.out.println("Timestamp: " + timeStamp);
temp.skip(" ");
String event = temp.next();
System.out.println("Event: " + event);
if (event.equals("I")) {
temp.skip(" ");
startNode = temp.nextInt();
System.out.println("starting node: " + startNode);
// while (temp.hasNext()) {
temp.skip(" ");
int node = temp.nextInt();
System.out.println(node);
temp.skip("");
int weight = temp.nextInt();
System.out.println(weight);
// System.out.println("<" + node + ", " + weight + ">");
// }
} else if (event.equals("L")) {
int currSeqNo = temp.nextInt();
System.out.println("Sequence number: " + currSeqNo); // discard if LSP has smaller or equal sequence number to max seen so far
if (currSeqNo >= prevSeqNo) {
prevSeqNo = currSeqNo; // update the previous sequence
// number
} else { // else if event == "F"
}
}
}
}
input.close();
}
After removing symbols:
0 I 4325 4214 6 4718 9 1203 11
18 L 4214 12 4325 6 4718 5 1483 9
29 L 4109 78 4718 3 1483 2
35 F 4109
Here is the error message:
Timestamp: 0
Event: I
starting node: 4325
4214
java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at LinkedStateRouting.parseFile(LinkedStateRouting.java:41)
at LinkedStateRouting.main(LinkedStateRouting.java:88)
When the user enters 0, the program is supposed to stop. I can't figure out how to do this. For example:
Enter the integers between 1 and 100: 2 5 6 5 4 3 23 43 2 0
2 occurs 2 times
3 occurs 1 time
4 occurs 1 time
5 occurs 2 times
6 occurs 1 time
23 occurs 1 time
43 occurs 1 time
My code prints the 0.
public class CountOccurrences {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("Enter ten integers between 1 and 100: ");
String userInput = input.nextLine();
//this splits the user input into an array using a space
String[] inputString = userInput.split(" ");
String[] previousValues = new String[inputString.length];
int count = 1;
//Compare elements and update count for new string
for (int i = 0; i < inputString.length; i++) {
for (int j = i+ 1; j < inputString.length; j++) {
if (inputString[i].equals(inputString[j]) && notFound (previousValues, inputString[i]) { `
count++;
}
}
//Prints only unique strings
if(!userInput.equals("0")){
if (notFound(previousValues,inputString[i])) {
if (count>1) {
System.out.println(inputString[i] + " occurs " + count + " times");
} else {
System.out.println(inputString[i] + " occurs " + count + " time");
}
count = 1;
}
if (notFound(previousValues,inputString[i])) {
previousValues[i] = inputString[i];
}
}}
}
//This method returns a boolean value. It is true if the string is not in the array and vice versa
public static boolean notFound(String[] pastValues, String currentString) {
boolean valueNotFound = true;
int index = 0;
while(index < pastValues.length && valueNotFound) {
if ((pastValues!= null) &&(currentString.equals(pastValues[index]))) {
valueNotFound = false;
}
index++;
}
return valueNotFound;
}
//Method for printing an array
public static void printArray(String [] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+ " ");
}
}
}
You can do that by adding an else condition and using System.exit(0) and tell the user that the program is going to terminate.
static void exit(int status) Terminates the currently running program or Java Virtual Machine.
status 0 indicates that the program execution completed without exceptions.
You can look at the API here
I keep getting this error when reading from a text file it gets the first few numbers but then does this there also shouldnt be 0's in there, tried a lot of things not sure what to do. I have to be able to read the file numbers and then multiply specific ones could use some help thanks. (I was using the final println to check what numbers it was getting). Sorry forgot the error is this output
4
32
0
38
0
38
0
16
0
Error: For input string: ""
Here is my file:
Unit One
4
32 8
38 6
38 6
16 7
Unit Two
0
Unit Three
2
36 7
36 7
Unit Four
6
32 6.5
32 6.5
36 6.5
36 6.5
38 6.5
38 6.5
Unit Five
4
32 6.5
32 8
32 7
32 8
Unit Six
5
38 7
30 6.5
24 8
24 8
24 8
Unit Seven
0
Unit Eight
1
40 12
Unit Nine
5
24 8
24 6.5
30 6.5
24 7
32 7
And here is my code:
package question;
import java.io.*;
import java.util.Scanner;
public class Weight
{
public static void main(String[] args)//main method
{
try
{
Scanner input = new Scanner(System.in);
//System.out.print("Please enter proposed weight of stock : ");
// int proposedWeight = input.nextInt();
File file = new File("MathUnits.txt");
System.out.println(file.getCanonicalPath());
FileInputStream ft = new FileInputStream(file);
DataInputStream in = new DataInputStream(ft);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strline;
while((strline = br.readLine()) != null)
{ int i = 0;
if (strline.contains("Unit"))
{
continue;
}
else {
String[] numstrs = strline.split("\\s+"); // split by white space
int[] nums = new int[numstrs.length];
nums[i] = Integer.parseInt(numstrs[i]);
for(int f = 0; f <numstrs.length; f++)
{
System.out.println(""+ nums[f]);
}
}
i ++;
}
//int x = Integer.parseInt(numstrs[0]);
// int m = Integer.parseInt(numstrs[1]);
// int b = Integer.parseInt(numstrs[2]);
// int a = Integer.parseInt(numstrs[3]);
int a = 0;
// System.out.println("this >>" + x + "," + m +"," + b + "," + a);
// if(proposedWeight < a)
// {
// System.out.println("Stock is lighter than proposed and can hold easily");
// System.exit(0);
// }
// else if ( a == proposedWeight)
// {
// System.out.println("Stock is equal to max");
// System.exit(0);
// }
// else
// {
// System.out.println("stock is too heavy");
// System.exit(0);
// }
in.close();
}
catch(Exception e)
{
System.err.println("Error: " + e.getMessage());
}
}
}
One probable error I see
You're not taking newlines into consideration, especially when you're doing a nums[i] = Integer.parseInt(numstrs[i]); on an empty string
Also, I don't think you're getting the numbers into the array correct since you're getting only one int from each line, when some lines have two