Casting string to integer array [duplicate] - java

//convert the comma separated numeric string into the array of int.
public class HelloWorld
{
public static void main(String[] args)
{
// line is the input which have the comma separated number
String line = "1,2,3,1,2,2,1,2,3,";
// 1 > split
String[] inputNumber = line.split(",");
// 1.1 > declare int array
int number []= new int[10];
// 2 > convert the String into int and save it in int array.
for(int i=0; i<inputNumber.length;i++){
number[i]=Integer.parseInt(inputNumber[i]);
}
}
}
Is it their any better solution of doing it. please suggest or it is the only best solution of doing it.
My main aim of this question is to find the best solution.

Java 8 streams offer a nice and clean solution:
String line = "1,2,3,1,2,2,1,2,3,";
int[] numbers = Arrays.stream(line.split(",")).mapToInt(Integer::parseInt).toArray();
Edit: Since you asked for Java 7 - what you do is already pretty good, I changed just one detail. You should initialize the array with inputNumber.length so your code does not break if the input String changes.
Edit2: I also changed the naming a bit to make the code clearer.
String line = "1,2,3,1,2,2,1,2,3,";
String[] tokens = line.split(",");
int[] numbers = new int[tokens.length];
for (int i = 0; i < tokens.length; i++) {
numbers[i] = Integer.parseInt(tokens[i]);
}

By doing it in Java 7, you can get the String array first, then convert it to int array:
String[] tokens = line.split(",");
int[] nums = new int[tokens.length];
for(int x=0; x<tokens.length; x++)
nums[x] = Integer.parseInt(tokens[x]);

Since you don't like Java 8, here is the Bestâ„¢ solution using some Guava utilities:
int[] numbers = Ints.toArray(
Lists.transform(
Splitter.on(',')
.omitEmptyStrings()
.splitToList("1,2,3,1,2,2,1,2,3,"),
Ints.stringConverter()));

Related

Convert a string into a multidimensional arrays with different lengths

I need to execute by command line a code that will provide a multidimensional array with elements with not necessarily equal lengths.
The execution string is bellow:
start /wait java -jar testMSMWithIndex.jar Foursquare_weather_day_root-type_type 0,1,2-4
I'm considering to pass the parameter 0,1,2-4 and then convert it in a multidimensional array with elements of different lengths in this case, i.e. {{0}, {1}, {2, 4}}.
Note that {{0, null}, {1, null}, {2, 4}} does not work to my problem.
Do you guys know how to develop a method or even get directly as an array from args?
I really appreciate any help you can provide.
It's doubtful that anything already exists to do this for you, so you'll have to parse the string for yourself. Something like this would do it:
public static int[][] parseRaggedArrayFromString(String s)
throws NumberFormatException {
String[] ss = s.split(",");
int[][] result = new int[ss.length][];
for (int i = 0; i < ss.length; ++i) {
if (!ss[i].contains("-")) {
result[i] = new int[1];
result[i][0] = Integer.parseInt(ss[i]);
} else {
String[] range = ss[i].split("-", 2);
int lo = Integer.parseInt(range[0]);
int hi = Integer.parseInt(range[1]);
int size = hi - lo + 1;
result[i] = new int[size > 0 ? size : 1];
int j = 0;
do {
result[i][j] = lo;
++lo;
++j;
} while (lo <= hi);
}
}
return result;
}
It's basically a split on , and -. From there is just handling the data. Comments in the code.
/**
* #author sedj601
*/
public class Main {
public static void main(String[] args) {
String input = "0,1,2-3";
String[] firstArray = input.split(",");//Split on ,.
String[][] outputArray = new String[firstArray.length][];//The array that will be holding the output
//Used to process the firstArray
for (int i = 0; i < firstArray.length; i++) {
if (firstArray[i].length() > 1) {//If the lenght is greater than one. split on -.
String[] secondArray = firstArray[i].split("-");
//Subtract the two numbers and add one to get the lenght of the array that will hold these values
int arrayLength = Integer.parseInt(secondArray[1]) - Integer.parseInt(secondArray[0]) + 1;
String[] tempArray = new String[arrayLength];
int increment = 0;//Keeps up with the tempArray index.
//loop from the first number to the last number inclusively.
for (int t = Integer.parseInt(secondArray[0]); t <= Integer.parseInt(secondArray[1]); t++) {
tempArray[increment++] = Integer.toString(t);//Add the data to the array.
}
outputArray[i] = tempArray;//Add the array to the output array.
} else {//If the lenght is 1, creat an array and add the current data.
String[] tempArray = new String[1];
tempArray[0] = firstArray[i];
outputArray[i] = tempArray;
}
}
//Print the output.
for (String[] x : outputArray) {
for (String y : x) {
System.out.print(y + " ");
}
System.out.println();
}
}
}
Output:
--- exec-maven-plugin:1.5.0:exec (default-cli) # JavaTestingGround ---
0
1
2 3
------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------
Total time: 1.194 s
Finished at: 2021-01-08T00:08:15-06:00
------------------------------------------------------------------------
I really think that's possible when you create an array of type Object .(not a good idea) Since multi-D arrays can only hold arrays of same length (int[][]). Then you create and retrieve values from array by casting...
I am trying here to be creative and adopt to your requirements..
public class x {
public static void main(String[] args) {
Object[] arguments = new Object[args.length];
// Then make a loop to capture arguments in array..
// or add manually
arguments[0] = new String[]{args[0]};
arguments[1] = new String[]{args[1],args[2]};
//Then retrieve info from object later by casting
System.out.println(java.util.Arrays.toString((String[]) arguments[1]));
}
}
...
Although, please consider using a collection...
While I waited for the answer, I found a way to solve the problem.
The relevant information here is that we do not need to set the second array dimension in its instantiation.
The code is below:
// INPUT string = "2-3,1,4-5"
private static String[][] featuresConversion(String string) {
String[] firstLevel = string.split(","); // 1st lvl separator
String[][] features = new String[firstLevel.length][]; // Sets 1st lvl length only
int i = 0;
for (String element : firstLevel) {
features[i++] = element.split("-");
}
return features;
}
I want to thank you all. All suggested solutions also work fine!

Input Strings into Array and then Splitting the Strings into a Single Char Array

I am writing a program in java that allows a user to enter n and puts them strings into an array. Then, the program takes those strings and splits them up into single char characters and places those characters into a new char array.
An example of what I'm trying to do is below:
Input n: 3
Input strings: "Cat", "Dog", "Mouse"
Original Input Array: [Cat][Dog][Mouse]
Desired Output Array: [C][a][t][D][o][g][M][o][u][s][e]
There are a few problems that occur with my code when I run it:
I get an exception error with the line of code that takes in my input strings. Line of code: exp[i] = input.nextLine();
Netbeans IDE is telling me it can not find the symbol for the split function I'm trying to use.
I am not sure what is wrong with my code, but I feel like at least the part where I input the strings should be working. I realize I don't have any output code yet, as I am just trying to get the input part working right now. Any suggestions would be appreciated!
public class Strings {
Scanner input = new Scanner(System.in);
int n; //number of strings
String[] exp = new String[n]; //input strings
char[] tokens = new char[n]; //individual char characters
//Gather data
public void SetNumberStrings(){
n = input.nextInt();
}
public void SetExpressions(){
for (int i = 0; i < n; i++){
exp[i] = input.nextLine();
}
}
public void SplitExpressions(){
for (int i = 0; i < n; i++){
tokens[i] = exp.split(" ");
}
}
public static void main(String[] args) {
Strings exp1 = new Strings();
exp1.SetNumberStrings();
exp1.SetExpressions();
exp1.SplitExpressions();
}
}
There are multiple issues with your code:
The array initialization is not working like that. Having int n;
//number of strings as a class field, means it will be initialized
with 0, resulting in your arrays having a length of 0. To fix this
you may declare your arrays after giving a value to n.
At line tokens[i] = exp.split(" "); there is indeed a compilation
error, because you are trying to call the split method on the exp
array, but the split method is from String class. So you would need
to call exp[i].split
split method is not doing what you think it's doing. I think you
are looking for the toCharArray() method.
tokens array should have the length of all the strings that you
scanned.
There are several issues with your program. The initialisation of class member variables seems to be wrong (considering your requirement). The call to SetExpressions in main will not alter the members n, exp and tokens as you are expecting. Value of n will be 0 by default and it remains so by the time exp and tokens get initialised. Hence, when you try to assign the input strings to the elements of exp, you get java.lang.ArrayIndexOutOfBoundsException.
Further, you are trying to invoke split method on a String[] object (exp), which is wrong (a String has split() method not String[]).
If you just trying to take a string of words and convert them all into a char[], then may be you can simply concatenate all the words into a single String object, and then do a toCharArray() on that.
Hope this helps.
import java.util.Scanner;
public class Strings {
Scanner input = new Scanner(System.in);
int n; //number of strings
String[] exp; //Fix...This line was causing exception in your program We should not initialize array here because at this point we don't have the length from user
char[] tokens; //Fix...We are not confirmed of the length of token array at this point
//Gather data
public void SetNumberStrings(){
n = input.nextInt();
}
public void SetExpressions(){
exp= new String[n];
for (int i = 0; i <n; i++){
exp[i] = input.next();//.next() function should be used.
}
}
public void SplitExpressions(){
int length=0;
int l=0;
for(int i=0; i<exp.length; i++) {
length+= exp[i].length();
}//this loop will calculate the required length for character array
tokens =new char[length];//Giving length of array here
for(int i=0; i<exp.length; i++) {
for(int j=0; j<exp[i].length(); j++) {
tokens[l]=exp[i].charAt(j);//
l++;
}
}
}
public static void main(String[] args) {
Strings exp1 = new Strings();
exp1.SetNumberStrings();
exp1.SetExpressions();
exp1.SplitExpressions();
}
}
I have cleared all the problems in the code. As mentioned in comments.You had initialized all class variables in class, this is not a good programming practice.

How to order an array/list of int that is received as a string by input in Java

I was trying to test my skills and I try to do a test.
I receive the following input:
[7,11,10,6,9]
[21,24,25,23,26]
[116,115,117,120,121,119]
I need to sort all these values.
I try to do the following:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] parts = null;
List<String> linhas = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String line = br.readLine();
line = line.replace("[","");
line = line.replace("]","");
line = line.replace(" ","");
System.out.println(line);
parts = line.split(",");
}
This way I got to show the output
7,11,10,6,9
21,24,25,23,26
116,115,117,120,121,119
The "String[parts]" got all values, but I don't know how to sort it, because the "parts" parameter is inside a "for loop".
How can I convert it to int/Integer and sort each line?
Assuming [7,11,10,6,9] be the input, we can try converting to a list of integers, and then sort that list:
String input = "[7,11,10,6,9]";
input = input.replaceAll("\\[(.*)\\]", "$1");
String[] vals = input.split(",");
List<Integer> output = Arrays.stream(vals)
.map(v -> Integer.parseInt(v))
.collect(Collectors.toList());
Collections.sort(output);
System.out.println(Arrays.toString(output.toArray()));
This prints:
[6, 7, 9, 10, 11]
Once you have parts you must convert this String[] into an int[]. To do this, first create an int[] for your results to go in. It must be the same size as your String[]:
int[] ints = new int[parts.length];
Then, iterate through the String[] and fill in values in the int[]:
for (int i = 0; i < parts.length; i++) {
ints[i] = Integer.parseInt(parts[i]); // converts a string containing an integer into its int value
}
Finally, to sort each line, a simple call to Arrays.sort(ints); will sort your array of integers.
Bonus:
This can be achieved more cleanly in a single line using Java 8 Streams, as follows:
List<Integer> sortedInts = Arrays.stream(parts).map(Integer::parseInt).sorted().collect(Collectors.toList());
You can do the replace() lines at once and split more cleanly with a regex:
parts = line.split("[\\[\\], ]+");
and use the Iterable technique that cameron1024 demonstrates in his answer. I think that using Iterable is a better choice for this use case than using Streams because the input size is trivially small and Streams has to spend more time to spin up.
The whole thing would look like:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] parts;
List<String> linhas = new ArrayList<>();
for (int i = 0; i < 3; i++) {
String line = br.readLine();
parts = line.split("[\\[\\] ,]+");
}
int ints[] = new int[parts.length];
for(int i = 0; i < parts.length; i++){
ints[i] = Integer.parseInt(parts[i]);
}
Arrays.sort(ints);

Java extract integers from a string containing delimiters and range symbols

Is there a library that can help me split a String to integers by delimiters and range marks?
for instance
values="32,38,42-48,84"
output:
int[] = 32,38,42,43,44,45,46,47,48,84
You can use builtin java functions of string class like split and contains to achieve it. In order to convert string to int use Integer.parseInt. E.g.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SimpleParser {
public static void main(String[] args) {
String input = "32,38,42-48,84";
String[] chunks = input.split(",");
System.out.println(Arrays.toString(chunks));
List<Integer> ints = new ArrayList<>();
for (String chunk : chunks) {
if (chunk.contains("-")) {
String[] rangeChunks = chunk.split("-");
if (rangeChunks.length != 2) {
throw new IllegalArgumentException("Invalid range");
}
for (int i = Integer.parseInt(rangeChunks[0]); i <= Integer.parseInt(rangeChunks[1]) ; i++) {
ints.add(i);
}
}else {
ints.add(Integer.parseInt(chunk));
}
}
System.out.println(ints);
}
}
Outputs
[32, 38, 42, 43, 44, 45, 46, 47, 48, 84]
If what you want is to get the whole range (From 42-55 for example), then I'm not entirely sure, but you can always use Regular Expressions to find everything that's not a number . The expression could be "[^0-9] Then use replace and change by some character (e.g commas). Then just split by commas. Feel free to read more about this here: http://www.vogella.com/tutorials/JavaRegularExpressions/article.html (NOTE: I'm not related in any way to Vogella. I just liked the tuto :)
EDIT:
I can now see the output you want (which I believe wasn't there). If that's what you want, then find all split by commas first. After, check if you have elements in which you have a symbol (- for example), and if so, then split by it and use the numbers to create the range. Here's an example of a working code:
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
String[] splitted = s.split(",");
for(int i = 0; i < splitted.length;i++){
if(splitted[i].contains("-")){
String[] nums = splitted[i].split("-");
int from = Integer.parseInt(nums[0]);
int to = Integer.parseInt(nums[1]);
for(int j = from;j <= to;j++)
System.out.print(j+",");
}
else
System.out.print(splitted[i] + ",");
}
Might not be the most efficient solution, but it works.
Get the individual items
//Creates an array of numbers (e.g. "32") and ranges (e.g. "42-48")
String[] items = String.split(",");
Loop through the array and split into ranges if range mark exists
if (items[i].contains("-")
{
//creates an array of two containing the start and end of range
String[] ranges = items[i].split("-");
}
Then for each String you have in your arrays, parse out the Integer
Integer parsedInt = Integer.parseInt(item[i]);
Lastly, convert and add the items to a collection like ArrayList then convert the ranges and loop through the range (42-48), adding the numbers to the collection as well.
I have used simple String arrays ans array list for the solution:
String[] values_s = items.split(",")
List<Integer> values_i = new ArrayList<Integer>();
for(String s: values_s){
if ( s.contains('-') ){
int sum = 0;
String[] g = s.split("-");
for (int i=Integer.parseInt(g[0]); i<Integer.parseInt(g[g.length-1]); i++)
values_i.add(i);
} else {
values_i.add(Integer.parseInt(s));
}
}
int[] n = (int[])values_i.toArray(int[values_i.size()]);
That should do it.

List<String> ----> to int [ ] [ ] arr

Well I have been stumped as to the best way to do this, I have written the code to read in lines of code from txt files as List. I can then print specific parts or convert this to an array of objects. But, ultimately I would like to have just a 2d int array you can see often in C/C++. I am very green when it comes to java, having only started earlier this week. I have like it up until this point of making dynamic 2d arrays at run time. Can any of you suggest a good way to get to a 2d int array from where i am currently stuck. I was just about to convert it to a char array using 'toChar', then to take the (value#index-48) and store it in its corresponding spot, but that seems pretty ghetto to me.
====updated==========================
eh, thanks for all the replies, but I just figured out how to do it using doubles, so for anyone else, here you go. I would still rather have int, since I have already built my other matrixops classes using this type, but Double shouldn't be an issue i guess.
package uaa.cse215;
import java.io.*;
import java.util.*;
public class ReadMatrix {
private Double[][] A;
private Double[][] B;
private int count;
public int filedir(String matrix) throws Exception{
Double[][] Temp;
String[] arr;
BufferedReader rd = new BufferedReader(new FileReader(matrix));
String s;
List<String> textFile = new ArrayList<String>();
while ((s=rd.readLine())!=null) {
textFile.add(s);
}
String splitarray[] = textFile.get(0).split(" ");//run once to grab # cols
int rows = textFile.size();//number of rows
int cols = splitarray.length;//number of cols
Temp = new Double[rows][cols]; // now can initiate array
for (int i=0; i<rows; i++) {
s = textFile.get(i);
arr = s.split(" ");
for (int j=0; j<cols; j++) {
Temp[i][j] = Double.parseDouble(arr[j]);
}
}
count++;
if (count == 1){
A = Temp;
}
else
B = Temp;
rd.close();
return(1);
}
}
Please note that Java has the char data type which is a 16bit unsigned integer holding a UTF-16 code point. int is in Java always a signed 32 bit integer. So if you want a C like Arrays of chars representing the content of a String, you should use a char[][]
To convert the content of your List<String> into a 2d array you can use the following code:
char[][] twoDarray = new char[textFile.size()];
for(int i = 0; i < textFile.size(); i+)
{
twoDarray[i] = textFile.get(i).toCharArray();
}
The array twoDarray then contains all Strings each as a char array.
This line won't compile
splitarray[j] = textFile.get(i).split(" ");
as splitarray[j] is of type String and split returns an array of Strings
Do the following instead:
for(int row=0;row<textFile.size();row++){
String[] splitarray = textFile.get(row).split(" ");
for(int col=0;col<splitarray.length;col++){
tmp[row][col] = Integer.parse(splitarray[col]);
}
}
if the input matrix dimentions are dynamic or jagged you can use
List<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
to read numbers and than copy it to raw 2d array if you want.
java.util.Scanner has many handy methods for reading "typed" data from input
Here's an example reading file to 2D array
public static int[][] read2DArray(String fileName) throws FileNotFoundException {
Scanner sc = null;
List<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
int columnCount = 0;
int[][] arr = null;
try {
sc = new Scanner(new File(fileName));
while (sc.hasNextLine()) {
// Read line
String line = sc.nextLine();
// Split it
String[] nums = line.split(" ");
if (nums.length > columnCount) {
columnCount = nums.length;
}
// Convert to integers and add to list
list.add(new ArrayList<Integer>());
for (String n : nums) {
list.get(list.size() - 1).add(new Integer(n));
}
}
// Convert list to array
int rowCount = list.size();
arr = new int[rowCount][columnCount];
for (int i = 0; i < rowCount; i++) {
for (int j = 0; j < list.get(i).size(); j++) {
arr[i][j] = list.get(i).get(j);
}
}
} finally {
if (sc != null) {
sc.close();
}
}
return arr;
}
Assuming your data file contains ascii-represented numbers that you want parsed into integers:
11 -9 13
12 55 102
1 1 1024
Then you can use the Integer(String s) constructor to parse your string objects.
Also, I suggest splitting each row only once. It won't matter much for small arrays, but the larger your inputs get, the more you'll needlessly recompute the splits.
An (untested) re-writing:
int tmp[][] = new int [rows][cols];
for(int i=0;i<rows;i++){
splitarray = textFile.get(i).split(" ");
for(int j=0;j<cols;j++){
tmp[i][j] = Integer(splitarray[j]);
}
}

Categories

Resources