Convert a 1D string to a 2D array of Integers - java

I have a string and I want to convert it to a 2D array of integers. This is what I am doing:
String string1="[1,2,3]~[4,5,6]~[7,8,9]~";
//Putting each element into an array of strings
String stringArray[]=string1.split("~");
//Determining the number of columns for the 2D array
int countints=0;
Scanner ins = new Scanner(stringArray[0]);
while (ins.hasNext()){
countints+=1;
ins.next();
}
//converting into an array of integers
int intArray[][]=new int[stringArray.length][countints];
Here I'm stuck as how to parse each integer into the 2D array.

String string1="[1,2,3]~[4,5,6]~[7,8,9]~";
String string2 = string1.replace("[","").replace("]","");
for(int i = 0; i < stringArray.length; i++)
{
String s = stringArray[i].substring(1, stringArray[i].length()-1);
String[] elementArray = s.split(",");
for(int j = 0; j < elementArray.length; j++)
{
int val = Integer.parseInt(elementArray[j]);
intArray[i][j] = val;
}
}

For a totally dynamic array:
String string1 = "[1,2,3]~[4,5,6]~[7,8,9]~";
String[] lines = string1.split("(^|~)\\[");
int[][] array = new int[lines.length][0];
Pattern pat = Pattern.compile("\\d+");
int lineIndex = 0;
for (String line : lines) {
//if the row size is dynamic
Matcher m1 = pat.matcher(line);
int rowSize = 0;
while (m1.find())
rowSize++;
array[lineIndex] = new int[rowSize];
int colIndex = 0;
Matcher m2 = pat.matcher(line);
while (m2.find()) {
array[lineIndex][colIndex++] = Integer.parseInt(m2.group());
}
lineIndex++;
}
for(int i=0; i<array.length;i++){
for(int j=0; j<array[i].length;j++){
System.out.print(array[i][j] + " ");
}
System.out.println();
}
It prints:
1 2 3
4 5 6
7 8 9

Once you have initialized the 2D array, you need to parse each element in stringArray by getting rid of trailing and leading '[', ']' bracket pairs and splitting it with "," and parse each element of the split string into Integer and put that int value to the given 2d array at correct postion.
EDIT: WORKING SOLUTION
String string1="[1,2,3]~[4,5,6]~[7,8,9]~";
String stringArray[]=string1.split("~");
int countints = stringArray[0].substring(1, stringArray[0].length()-1).split(",").length;
int intArray[][]=new int[stringArray.length][countints];
for(int i = 0; i < stringArray.length; i++)
{
String s = stringArray[i].substring(1, stringArray[i].length()-1);
String[] elementArray = s.split(",");
for(int j = 0; j < elementArray.length; j++)
{
int val = Integer.parseInt(elementArray[j]);
intArray[i][j] = val;
}
}

Here is a clean solution that works. I started working on it before I got through all of the other answers, so my apologies if it doesn't meaningfully add to what is already here:
public class SO {
public static int[][] parse(String input) {
String[] rows = input.split("~");
int[][] ints = new int[rows.length][];
int j = 0;
for(String row : rows) {
String[] cols = row.substring(1, row.length()-1).split(",");
int k = 0;
ints[j] = new int[cols.length];
for(String col : cols) {
ints[j][k++] = Integer.parseInt(col);
}
j++;
}
return ints;
}
public static void main(String[] args) {
for(int[] row : parse("[1,2,3]~[4,5,6]~[7,8,9]~")) {
for(int col : row) {
System.out.print(","+col);
}
System.out.println();
}
}
}
This produces the output:
,1,2,3
,4,5,6
,7,8,9
As for error checking you should decide upfront how you want to handle error checking, As this is written a single invalid int will throw an exception, which I think is the correct behavior. Malformed rows on the other hand might give unpredictable output (which I would say is wrong if the input has even the slightest potential to be malformed).

Related

Parse file and splitting individual lines into 2d array

I have one text file in which each String holds one line of numbers say 203 and I have one 2d array int puzzle[][].
The lines of file are in the array list Arraylist<String> lines .The first String from the array list goes into puzzle[0].The second String goes into puzzle[1], etc.
The problem I'm having is that after splitting the lines I cannot convert those numbers into integers because it gives me number format exception for -1 what if I will split that - and 1 as well.
I tried the following and also making deep copy of the string array and then transforming each string into an integer
public void parseFile(ArrayList<String> lines)
{
ArrayList<String> l = lines;
for(int i =0; i<puzzle.length; i++)
puzzle[i][0] = Integer.parseInt(l.get(i).split(""));
}
it should give me 2d array with integers
Here is a method that will take a list of strings made up of single digit numbers and convert the list to a 2d array of int. This code makes no use of Java 8 streams.
public static int[][] parseFile(List<String> lines) {
int[][] result = new int[lines.size()][];
int multiplier = 1;
int counter = 0;
for (String line : lines) {
List<Integer> row = new ArrayList<>();
for (int i = 0; i < line.length(); i++) {
char c = line.charAt(i);
if (c == '-') {
multiplier = -1;
continue;
}
int n = (int)c - 48;
row.add(n * multiplier);
multiplier = 1;
}
int[] rowArray = new int[row.size()];
for (int j = 0; j < row.size(); j++) {
rowArray[j] = row.get(j);
}
result[counter] = rowArray;
counter++;
}
return result;
}
Below is my test code, execute from main
List<String> list = new ArrayList<>();
list.add("-111");
list.add("2-13");
int[][] result = parseFile(list);
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
System.out.printf("%d ", result[i][j]);
}
System.out.print("\n");
}
Output
-1 1 1
2 -1 3

Code improvement, array of Strings

I am completely new to programming. Can you give me some tips on how to improve my code?
The problem was:
Given an array of strings, return a new array without the strings that are equal to the target string. One approach is to count the occurrences of the target string, make a new array of the correct length, and then copy over the correct strings.
And my code:
public String[] wordsWithout(String[] words, String target) {
int numberOfTargets = 0;
for (int i = 0; i < words.length; i++){
if ( words[i].equals(target) ) numberOfTargets++;
}
String[] result = new String[words.length - numberOfTargets];
for (int i = 0; i < words.length - numberOfTargets; i++){ // 1
result[i] = "0"; // 1
} // 1
for (int i = 0; i < words.length; i++){
if ( !words[i].equals(target) ){
int j = 0; // 2
while ( !result[j].equals("0") ){ // 2
j++; // 2
} // 2
result[j] = words[i];
}
}
return result;
}
Example of how code works:
wordsWithout(["aa", "ab", "ac", "aa"], "aa") → ["ab", "ac"]
I know that new array of ints is filled by zeros dy default. What about new array of Strings? I had to artificially fill it by zeros in part marked as //1, so that I could "scroll" to the right element, when I have to add elements to my new array in part marked as //2.
My code seems to be kind of awkward. Are there any standard methods or general ways to improve my code?
You don't need to set each element to "0".
Just do this:
public static String[] wordsWithout(String[] words, String target) {
int numberOfTargets = 0;
for (int i = 0; i < words.length; i++){
if ( words[i].equals(target) ) numberOfTargets++;
}
String[] result = new String[words.length - numberOfTargets];
int j =0; // for indices of result
for (int i = 0; i < words.length; i++){
if (!words[i].equals(target) ){
result[j++] = words[i];
}
}
return result;
}
Looks like your code could be simplified a lot by just using an ArrayList.
public String[] wordsWithout(String[] words, String target)
{
ArrayList<String> list = new ArrayList<String>();
for(int i = 0; i < words.length; ++i)
{
if(!words[i].equals(target))
{
list.add(words[i]);
}
}
return list.toArray(new String[0]);
}
Basically instead of calculating the size of the target array and initialising it, you use a list (which is variable in size), put in all the elements you need, and then create a new array from it.
Unrelated to that, please don't invent your own values ("0") to describe a null value - there's a dedicated keyword, null, for that.
Use
for (String s : words) {
if (s.equals(target))
numberOfTargets++;
}
This might be a bit simpler. Using the split string method allows you to create an array with each value separated by white space.
public String[] wordsWithout(String[] words, String target) {
String newStr = "";
for (int i = 0; i < words.length; i++){
if (words[i].equals(target))
continue;
newStr = newStr + words[i] +" ";
}
return newStr.split(" ");
}

Why do I get an extra output in my code?

I'm trying to write a code which gets as an input an array of strings, and creates a two-dimensoinal array of type char, the number of lines is as the number of words in the string and in each line there is a reversed array of the letters in the word.
for example if my input is: start at the end!
my output will be :
[t, r, a, t, s]
[t, a]
[e, h, t]
[!, d, n, e]
This is my code:
public static void main(String[] args) {
char thelist[][] = new char[args.length][];
for (int i = 0; i < args.length; i++) {
thelist[i] = new char[args[i].length()];
for (int k = 0; k < args[i].length(); k++) {
char letter = args[i].charAt(args[i].length() - k - 1);
thelist[i][k] = letter;
}
for (char[] word : thelist) {
String list = Arrays.toString(word);
System.out.println(list);
}
}
}
The code should be like this :
String str ="start at the end!";
String[] splitString = str.split(" ");
int length=0;
for(String string:splitString ){
if(string.length()>length){
length=string.length();
}
}
Character[][] charArray = new Character[splitString.length][length];
int index=0;
for(String string:splitString ){
length=string.length();
for(int i=0;i<string.length();i++){
charArray[index][--length]=string.charAt(i);
}
index++;
}
for (int i=0;i<charArray.length;i++){
for (int j=0;j<charArray[i].length && charArray[i][j]!=null;j++) {
System.out.print(charArray[i][j]);
}
System.out.println();
}
OUTPUT:
trats
ta
eht
!dne
You are getting extra lines because you are printing inside the outer for loops. try this. it should work.
public static void main(String[] args) {
char thelist[][] = new char[args.length][];
for (int i = 0; i < args.length; i++) {
thelist[i] = new char[args[i].length()];
for (int k = 0; k < args[i].length(); k++) {
char letter = args[i].charAt(args[i].length() - k - 1);
thelist[i][k] = letter;
}
}
for (char[] word : thelist) {
String list = Arrays.toString(word);
System.out.println(list);
}
}
While editing your question I fixed indentation of your code which showed your problem clearly: you placed code responsible for printing result array in same loop which fills this array. In other words you are printing array after you add new row to it.
That is why you see results in form
[row1]
null
null
null
[row1]
[row2]
null
null
[row1]
[row2]
[row3]
null
[row1]
[row2]
[row3]
[row4]
To solve this problem simply place loop responsible for printing outside of loop responsible in generating content of result array (remember that indentation is not responsible for scoping but placement of { and } brackets is, so move one } from end before printing loop). So change your code to
char thelist[][] = new char[args.length][];
for (int i = 0; i < args.length; i++) {
thelist[i] = new char[args[i].length()];
for (int k = 0; k < args[i].length(); k++) {
char letter = args[i].charAt(args[i].length() - k - 1);
thelist[i][k] = letter;
}
}
for (char[] word : thelist) {
String list = Arrays.toString(word);
System.out.println(list);
}

How to split a string into equal parts and store it in a string array

I'm fairly new to Java and am stuck on a particular homework question where a String gets passes and from there I have to split it into parts equal to an Integer that was passed.
For example: String "HelloWorld" is input and it has to be divided by 2 and those parts then have to be put into an array that has two parts like: array[hello, world].
Is there anyway to do this using a FOR loop?
My code so far enters the whole String into each array element. Here is my code:
String[] splitIntoParts(String word, int size) {
String[] array = new String[size];
for (int i = 0; i < array.length; i++) {
array[i] = word;
println(array[i]);;
}
return array;
}
There are many ways:
Here's the regex version:
public void splitEqual(String s){
int length = s.length();//Get string length
int whereToSplit;//store where will split
if(length%2==0) whereToSplit = length/2;//if length number is pair then it'll split equal
else whereToSplit = (length+1)/2;//else the first value will have one char more than the other
System.out.println(Arrays.toString(s.split("(?<=\\G.{"+whereToSplit+"})")));//split the string
}
\G is a zero-width assertion that matches the position where the previous match ended. If there was no previous match, it matches the beginning of the input, the same as \A. The enclosing lookbehind matches the position that's four characters along from the end of the last match.
Both lookbehind and \G are advanced regex features, not supported by all flavors. Furthermore, \G is not implemented consistently across the flavors that do support it. This trick will work (for example) in Java, Perl, .NET and JGSoft, but not in PHP (PCRE), Ruby 1.9+ or TextMate (both Oniguruma).
Using Substring:
/**
* Split String using substring, you'll have to tell where to split
* #param src String to split
* #param len where to split
* #return
*/
public static String[] split(String src, int len) {
String[] result = new String[(int)Math.ceil((double)src.length()/(double)len)];
for (int i=0; i<result.length; i++)
result[i] = src.substring(i*len, Math.min(src.length(), (i+1)*len));
return result;
}
You should also check this answer: Google Guava split
First check if the length of the string is a multiple of the divisor:
if(str.length() % divisor == 0)
Then you know that you can grab equal chunks of it. So you use substring to pull them out, in a loop.
while(str.length() > 0) {
String nextChunk = str.substring(0,divisor);
// store the chunk.
str = str.substring(divisor,str.length());
}
Will cycle through and grab a chunk that is divisor long each time.
Try the following application.It is dividing the provided word into equal parts based on the provided size per part
public class WordSpliter {
public static void main(String[] args) {
String[] words = new WordSpliter().splitter("abcdefghij", 4);
for(String s : words) System.out.println(s);
}
private String[] splitter(String word, int size) {
// Decide the size of the String array
int rest = word.length() % size;
int arrSize = ((word.length() - rest) / size) + 1;
// Declare the array and the start point of the word
String[] words = new String[arrSize];
int startPoint = 0;
for (int i = 0; i < words.length; i++) {
if (i + 1 == words.length) {
words[i] = word.substring(startPoint, startPoint + rest);
} else {
words[i] = word.substring(startPoint, startPoint + 4);
startPoint += 4;
}
}
return words;
}
}
Good Luck !!!!
You can use Brute force
public static List<String> splitStringEqually(String text, int size)
{
List<String> result = new ArrayList<String>((text.length() + size - 1) / size);
for (int i = 0; i < text.length(); i += size) {
result.add(text.substring(i, Math.min(text.length(), i + size)));
}
return result;
}
String s = "HelloWorld";
String firts_part=(String) s.subSequence(0, s.length() / 2);
String second_part=(String) s.subSequence((s.length() / 2)+1,s.length()-1 );
Try subSequence();
This is not plagarism, formatted the answer mentioned here - https://stackoverflow.com/a/3761521 as per the question.
public static void main(String[] args){
String str = "HelloWorld";
int parts = str.length()/3;
System.out.println(Arrays.toString(
str.split("(?<=\\G.{"+parts+"})")
));
}
Since length of a string is dived by 2
Code:
String st ="HelloWorld";
String firstPart = "";
String secondPart = "";
for (int j = 0; j < st.length(); j++) {
if ( j < st.length() /2) {
firstPart += st.charAt(j);
}else
secondPart += st.charAt(j);
}
System.out.println(firstPart);
System.out.println(secondPart);
Output:
Hello
World
Explanation: you add to firstPart String as long as your index has not met the middle index of the String. When it passed the middle index of String, you make the secondPart
Just looking at your input HelloWorld, You are trying to substring your input by Upper case letter.
You should go with that.
String str = "HelloWorldUser";
List<Integer> indexList = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
String temp = (str.charAt(i) + "").toUpperCase();
if (temp.equals(str.charAt(i) + "")) { // check for upper case letters
indexList.add(i);
}
}
List<String> subStrings = new LinkedList<>(); // to keep the insertion order
for (int i = indexList.size() - 1; i > -1; i--) { // substring reverse order
subStrings.add(str.substring(indexList.get(i)));
str=str.substring(0,indexList.get(i));
}
Collections.reverse(subStrings); // reverse to get original order
System.out.println(subStrings);
Out put:
[Hello, World, User]
If you want to get final result in to an array you can use
String[] arr= subStrings.toArray(new String[subStrings.size()]);
I figured it out. Here is my code:
String[] array = new String[size];
char[] charArray = new char[length(word)];
char[] temp = new char[length(word) / size];
int place = 0;
// turn the string into an array of chars
for (int i = 0; i < charArray.length; i++) {
charArray[i] = getChar(word, i);
}
// loop for each element of the desired string array
for (int i = 0; i < array.length; i++) {
// fill a temp array with the correct characters and the corect amount of characters
for (int j = 0; j < charArray.length / size; j++) {
temp[j] = charArray[place];
++place;
}
// insert the temp array into each element of the string array
array[i] = new String(temp);
}
return array;
A Simple solution is like
static void split(String str, int n) {
int partSize = str.length() / n;
while (str.length() - partSize > 0) {
String s = str.substring(0, partSize-1);
System.out.print(s + " ");
str = str.substring(partSize-1);
}
if (str.length() > 0) {
System.out.print(str);
}
}
You can do it using regex as follows:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
// Tests
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 5)));
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 4)));
System.out.println(Arrays.toString(splitIntoParts("HelloWorld", 2)));
}
static String[] splitIntoParts(String word, int size) {
return word.replaceAll("(.{" + size + "})", "$1\n").split("\n");
}
}
Output:
[Hello, World]
[Hell, oWor, ld]
[He, ll, oW, or, ld]

Fill a string array by repeating each element according to the values of another int array

I have a string array [x,y,z] and an int array [2,3,4] and I need to create an array by appending the two, but having the last 3 values multiplied by the integers in the int array, like so:
[x,y,z,xx,yyy,zzzz]. I can't figure out how to do this.
What I wrote is this:
public static String[] bigArr (String[] letters, int[] numbers) {
int l = letters.length;
int n = numbers.length;
String[] answer = new String[l+n];
for (int i=0; i<n;i++){
answer[i]=letters[i]+numbers[i];
}
return answer;
}
Obviously it returns nonsense at this point, but I am stuck and need a good explanation on how to do this. I am very new to Java.
try this:
public static void main(String[] args) throws Exception {
String[] letters = {"x", "y", "z"};
int[] numbers = {2, 3, 4};
String[] result = bigArr(letters, numbers);
// prints [x, y, z, xx, yyy, zzzz]
System.out.println(Arrays.toString(result));
}
private static String[] bigArr(String[] letters, int[] numbers) {
int lettersLength = letters.length;
int numbersLength = numbers.length;
String[] result = new String[lettersLength + numbersLength];
for (int n = 0; n < lettersLength; ++n) {
result[n] = letters[n];
}
StringBuilder sb = new StringBuilder();
for (int n = lettersLength; n < result.length; ++n) {
sb.setLength(0); // reset the StringBuilder
for (int m = 0; m < numbers[n - lettersLength]; ++m) {
sb.append(letters[n - lettersLength]);
}
result[n] = sb.toString();
}
return result;
}
1 . First, copy the letters to answer
2 . Then, for each letter l[i],
answer[l + i - 1] = string_consisting_of_letter_l[i]_repeated_n[i]_times

Categories