I am trying to populate a two dimensional array in Java by using a user-inputted string. I have already got the string and I have figured out how to create the array. I am just having trouble figuring out how to get the values into the array. In case you are wondering, yes I have to use an array. Here is what I have so far:
private static int[][] parseTwoDimension(String strInput)
{
int rows = 0; //number of rows in the string
for (int i = 0; i < strInput.length(); i++)
{
if (strInput.charAt(i) == '!') //the ! is an indicator of a new row
{
rows++;
}
}
int[][] arr = new int[rows][]; //create an array with an unknown number of columns
int elementCounter = 0; //keep track of number of elements
int arrayIndexCounter = 0; //keep track of array index
for (int i = 0; i < strInput.length(); i++)
{
if (strInput.charAt(i) != '!') //while not the end of the row
{
elementCounter++; //increase the element count by one
}
else //reached the end of the row
{
arr[arrayIndexCounter] = new int[elementCounter]; //create a new column at the specified row
elementCounter = 0; //reset the element counter for the next row
arrayIndexCounter++; //increase the array index by one
}
}
/*
This is where I need the help to populate the array
*/
char c; //each character in the string
int stringIndex = -1; //keep track of the index in the string
int num; //the number to add to the array
for (int i = 0; i < arr.length; i++)
{
for (int j = 0; j < arr[i].length; j++)
{
stringIndex++; //increment string index for next element
c = strInput.charAt(stringIndex); //the character at stringIndex
if (c == '!') //if it is the end of the row, do nothing
{
}
else //if it is not the end of the row...
{
String s = Character.toString(c); //convert character to String
num = Integer.parseInt(s); //convert String to Integer
arr[i][j] = num; //add Integer to array
}
}
}
return arr; //return a two dimensional array the user defined
}
Any help is greatly appreciated :)
I've edited your code and posted it below. This is a general outline of how to solve it:
Use string.split("!") to separate your String by the delimiter '!'. This returns an array
Then, use string.split("") to separate the String into individual characters
Code posted below:
private static int[][] parseTwoDimension(String strInput)
{
String[] rows = strInput.split("!");
int[][] arr = new int[rows.length()][];
for(int i = 0; i < rows.length; i++)
{
String[] elements = rows[i].split("");
int[] intElements = new int[elements.length];
for(int j = 0; j < elements.length; j++)
{
intElements[j] = Integer.parseInt(elements[j]);
}
arr[i] = intElements;
}
}
Let me know if this works. The string.split() function is really useful when parsing Strings into arrays
Related
I have a 2D array acting as a grid.
int grid[][] = new int[5][5];
How do I search through the grid sequentially as in (0,0), (1,0), (2,0), (3,0), (4,0) then (0,1), (1,1), (2,1) ... without getting any array out of bounds exceptions.
I'm new to programming and I just can't get my head around how to do this.
You know your lengths, now use a for loop to circle through the array.
for (int i = 0;i<5;i++){
for (int j = 0;i<5;i++){
int myInt = grid[i][j];
//do something with my int
}
}
To get the lengths at runtime you could do
int lengthX = grid.length; //length of first array
int lengthY = 0;
if ( lengthX>0){ //this avoids an IndexOutOFBoundsException if you don't know if the array is already initialized yet.
lengthY = grid[0].length; //length of "nested" array
}
and then do the for loop with lengthX and lengthY.
You will need two nested loop in order to access the two dimensions of your array:
int grid[][] = new int[5][5];
for(int i = 0; i < 5; i++ ) {
for(int j = 0; j < 5; j++ ) {
int value = grid[i][j];
}
}
Use 2 forloops like the following example:
for(int i = 0; i < 5; i++){
for(int j = 0; j < 5; j++){
System.out.println(grid[i][j]);
}
}
Also i would suggest that when initializing an array to write it like this:
int[][] grid = new int[5][5]; // note the double brackets are after int and not grid
Try this:
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
System.out.println(grid[j][i]);
}
}
This code (like the other answers) uses two for loops.
It does however add some handling of edge-cases
static int[] find(int[][] mtx, int valueToLookFor)
{
int rows = mtx.length;
if(rows == 0)
return new int[]{-1,-1};
int cols = mtx[0].length;
if(cols == 0)
return new int[]{-1, -1};
for(int r=0;r<rows;r++)
{
for(int c=0;c<cols;c++)
{
if(mtx[r][c] == valueToLookFor)
return new int[]{r,c};
}
}
return new int[]{-1,-1};
}
I'm trying to populate a 2D array with char's from a string I've read in. I'm having a problem with actually populating this 2D array. It keeps printing a 2D array bigger than what I've given it, and the number always seems to be 6 rather than the letters from the string.
I store the string in an ArrayList called tempArray.
Input strings:
WUBDLAIUWBD
LUBELUFBSLI
SLUEFLISUEB
I instantiate a 2D array with columnlength = 11, and rowcount 3
epidemicArray = new int[rowCount][columnCount];
Array before I try to populate it:
00000000000
00000000000
00000000000
My code:
public static void updateArray(){
//extract string from temp
for (int i = 0; i < tempArray.size(); i++){
String temp = tempArray.get(i);
char[] charz = temp.toCharArray();
for (int j = 0; j < charz.length; j++){
for (int k = 0; k < rowCount; k++){
for (int l = 0; l < columnCount; l++){
epidemicArray[k][l] = charz[j];
}
}
}
}
}
Output: Which I didn't expect
6666666666666666666666
6666666666666666666666
6666666666666666666666
Expected output: (2D array)
WUBDLAIUWBD
LUBELUFBSLI
SLUEFLISUEB
Thanks, this is really bugging me.
Change your code to this:
public static void updateArray(){
//extract string from temp
for (int i = 0; i < tempArray.size(); i++){
String temp = tempArray.get(i);
char[] charz = temp.toCharArray();
for (int j = 0; j < charz.length; j++){
epidemicArray[i][j] = charz[j];
}
}
}
This edit should work since the number of columns is the length of one of the string (same length for the 3 of them).
Here is my output
[EDIT]. #magna_nz, I used the following methods to print the array
public static void printRow(int rowNumber) {
for (int i = 0; i < 11; i++) {
System.out.print( epidemicArray[rowNumber][i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
updateArray();
for (int i = 0; i < 3; i++) {
printRow(i);
}
}
This will print the numbers, but if you want to print characters you can change the above printRow method to something like:
public static void printRow(int rowNumber) {
for (int i = 0; i < 11; i++) {
System.out.print( (char)epidemicArray[rowNumber][i] + " ");
}
System.out.println();
}
And this will give you the following result:
You're overwriting your entire epidemicArray with the last value that charz[j] gets. Which is apparently 66. Actually you're overwriting that entire array with every value from charz and the last one won.
I'm trying to populate an array of bytes from a string that contains numbers(some being 2 digits) with spaces in between. I know there is an parseByte function but I'm unsure how to use that when populating an array as it seems to just take the string as one whole number.
my not-working-code:
public static void popArray(byte[][] array, String numbers)
{
int counter = 0; //counter to track position in string of data
for(int i=0; i<20; i++) //cycle rows
{
for(int y=0; y<20; y++) //cycle columns
{
array[i][y] = (byte)(Character.digit(.charAt(counter), 10));
counter++; //increase place in data string
}
}
}
Split the string at spaces, then iterate over the resulting array:
String[] parts = numbers.split("\\s+");
int counter = 0; //counter to track position in string of data
for (int i = 0; i < 20; i++) { //cycle rows
for (int y = 0; y < 20; y++) { //cycle columns
String s = parts[counter];
byte b = (byte)(Integer.parseInt())
array[i][y] = b;
counter++; //increase place in data string
}
}
I have problem with conversion from String into two dimension int array.
Let's say I have:
String x = "1,2,3;4,5,6;7,8,9"
(In my program it will be String from text area.) and I want to create array n x n
int[3][3] y = {{1,2,3},{4,5,6},{7,8,9}}
(Necessary for next stages.) I try to split the string and create 1 dimensional array, but I don't have any good idea what to do next.
As you suggest I try split at first using ; then , but my solution isn’t great. It works only when there will be 3 x 3 table. How to create a loop making String arrays?
public int[][] RunMSTFromTextFile(JTextArea ta)
{
String p = ta.getText();
String[] tp = p.split(";");
String tpA[] = tp[0].split(",");
String tpB[] = tp[1].split(",");
String tpC[] = tp[2].split(",");
String tpD[][] = {tpA, tpB, tpC};
int matrix[][] = new int[tpD.length][tpD.length];
for(int i=0;i<tpD.length;i++)
{
for(int j=0;j<tpD.length;j++)
{
matrix[i][j] = Integer.parseInt(tpD[i][j]);
}
}
return matrix;
}
After using split, take a look at Integer.parseInt() to get the numbers out.
String lines[] = input.split(";");
int width = lines.length;
String cells[] = lines[0].split(",");
int height = cells.length;
int output[][] = new int[width][height];
for (int i=0; i<width; i++) {
String cells[] = lines[i].split(",");
for(int j=0; j<height; j++) {
output[i][j] = Integer.parseInt(cells[j]);
}
}
Then you need to decide what to do with NumberFormatExceptions
Split by ; to get rows.
Loop them, incrementing a counter (e.g. x)
Split by , to get values of each row.
Loop those values, incrementing a counter (e.g. y)
Parse each value (e.g. using one of the parseInt methods of Integer) and add it to the x,y of the array.
If you have already created an int[9] and want to split it into int[3][3]:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
toArray[i][j] = fromArray[(3*i) + j);
}
}
Now, if the 2-dimensional array is not rectangular, i.e. the size of inner array is not same for all outer arrays, then you need more work. You would do best to use a Scanner and switch between nextString and next. The biggest challenge will be that you will not know the number of elements (columns) in each row until you reach the row-terminating semi-colon
A solution using 2 splits:
String input = "1,2,3;4,5,6;7,8,9";
String[] x = input.split(";");
String[][] result = new String[x.length][];
for (int i = 0; i<x.length; i++) {
result[i] = x[i].split(",");
}
This give a 2 dimension array of strings you will need to parse those ints afterwards, it depends on the use you want for those numbers. The following solution shows how to parse them as you build the result:
String input = "1,2,3;4,5,6;7,8,9";
String[] x = input.split(";");
int[][] result = new int[x.length][];
for (int i = 0; i < x.length; i++) {
String[] row = x[i].split(",");
result[i] = new int[row.length];
for(int j=0; j < row.length; j++) {
result[i][j] = Integer.parseInt(row[j]);
}
}
Super simple method!!!
package ADVANCED;
import java.util.Arrays;
import java.util.Scanner;
public class p9 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
String x=sc.nextLine();
String[] array = x.split(",");
int length_x=array.length;
int[][] two=new int[length_x/2][2];
for (int i = 0; i <= length_x-1; i=i+2) {
two[i/2][0] = Integer.parseInt(array[i]);
}
for (int i = 1; i <= length_x-1; i=i+2) {
two[i/2][1] = Integer.parseInt(array[i]);
}
}
}
I'm trying to resolve all the combinations of elements based on a given string.
The string is like this :
String result="1,2,3,###4,5,###6,###7,8,";
The number of element between ### (separated with ,) is not determined and the number of "list" (part separated with ###) is not determined either.
NB : I use number in this example but it can be String too.
And the expected result in this case is a string containing :
String result = "1467, 1468, 1567, 1568, 2467, 2468, 2567, 2568, 3467, 3468, 3567, 3568"
So as you can see the elements in result must start with an element of the first list then the second element must be an element of the second list etc...
From now I made this algorithm that works but it's slow :
String [] parts = result.split("###");
if(parts.length>1){
result="";
String stack="";
int i;
String [] elmts2=null;
String [] elmts = parts[0].split(",");
for(String elmt : elmts){ //Browse root elements
if(elmt.trim().isEmpty())continue;
/**
* This array is used to store the next index to use for each row.
*/
int [] elmtIdxInPart= new int[parts.length];
//Loop until the root element index change.
while(elmtIdxInPart[0]==0){
stack=elmt;
//Add to the stack an element of each row, chosen by index (elmtIdxInPart)
for(i=1 ; i<parts.length;i++){
if(parts[i].trim().isEmpty() || parts[i].trim().equals(","))continue;
String part = parts[i];
elmts2 = part.split(",");
stack+=elmts2[elmtIdxInPart[i]];
}
//rollback i to previous used index
i--;
if(elmts2 == null){
elmtIdxInPart[0]=elmtIdxInPart[0]+1;
}
//Check if all elements in the row have been used.
else if(elmtIdxInPart[i]+1 >=elmts2.length || elmts2[elmtIdxInPart[i]+1].isEmpty()){
//Make evolve previous row that still have unused index
int j=1;
while(elmtIdxInPart[i-j]+1 >=parts[i-j].split(",").length ||
parts[i-j].split(",")[elmtIdxInPart[i-j]+1].isEmpty()){
if(j+1>i)break;
j++;
}
int next = elmtIdxInPart[i-j]+1;
//Init the next row to 0.
for(int k = (i-j)+1 ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i-j]=next;
}
else{
//Make evolve index in current row, init the next row to 0.
int next = elmtIdxInPart[i]+1;
for(int k = (i+1) ; k <elmtIdxInPart.length ; k++){
elmtIdxInPart[k]=0;
}
elmtIdxInPart[i]=next;
}
//Store full stack
result+=stack+",";
}
}
}
else{
result=parts[0];
}
I'm looking for a more performant algorithm if it's possible. I made it from scratch without thinking about any mathematical algorithm. So I think I made a tricky/slow algo and it can be improved.
Thanks for your suggestions and thanks for trying to understand what I've done :)
EDIT
Using Svinja proposition it divide execution time by 2:
StringBuilder res = new StringBuilder();
String input = "1,2,3,###4,5,###6,###7,8,";
String[] lists = input.split("###");
int N = lists.length;
int[] length = new int[N];
int[] indices = new int[N];
String[][] element = new String[N][];
for (int i = 0; i < N; i++){
element[i] = lists[i].split(",");
length[i] = element[i].length;
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++){
res.append(element[i][indices[i]]);
}
res.append(",");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
System.out.println(res);
This is my solution. It's in C# but you should be able to understand it (the important part is the "calculate next element" section):
static void Main(string[] args)
{
// parse the input, this can probably be done more efficiently
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
int[] indices = new int[N];
for (int i = 0; i < N; i++)
length[i] = lists[i].Split(',').Length - 1;
string[][] element = new string[N][];
for (int i = 0; i < N; i++)
{
string[] list = lists[i].Split(',');
element[i] = new string[length[i]];
for (int j = 0; j < length[i]; j++)
element[i][j] = list[j];
}
// solve
while (true)
{
// output current element
for (int i = 0; i < N; i++) Console.Write(element[i][indices[i]]);
Console.WriteLine(" ");
// calculate next element
int ind = N - 1;
for (; ind >= 0; ind--)
if (indices[ind] < length[ind] - 1) break;
if (ind == -1) break;
indices[ind]++;
for (ind++; ind < N; ind++) indices[ind] = 0;
}
}
Seems kind of similar to your solution. Does this really have bad performance? Seems to me that this is clearly optimal, as the complexity is linear with the size of the output, which is always optimal.
edit: by "similar" I mean that you also seem to do the counting with indexes thing. Your code is too complicated for me to go into after work. :D
My index adjustment works very simply: starting from the right, find the first index we can increase without overflowing, increase it by one, and set all the indexes to its right (if any) to 0. It's basically counting in a number system where each digit is in a different base. Once we can't even increase the first index any more (which means we can't increase any, as we started checking from the right), we're done.
Here is a somewhat different approach:
static void Main(string[] args)
{
string input = "1,2,3,###4,5,###6,###7,8,";
string[] lists = input.Replace("###", "#").Split('#');
int N = lists.Length;
int[] length = new int[N];
string[][] element = new string[N][];
int outCount = 1;
// get each string for each position
for (int i = 0; i < N; i++)
{
string list = lists[i];
// fix the extra comma at the end
if (list.Substring(list.Length - 1, 1) == ",")
list = list.Substring(0, list.Length - 1);
string[] strings = list.Split(',');
element[i] = strings;
length[i] = strings.Length;
outCount *= length[i];
}
// prepare the output array
string[] outstr = new string[outCount];
// produce all of the individual output strings
string[] position = new string[N];
for (int j = 0; j < outCount; j++)
{
// working value of j:
int k = j;
for (int i = 0; i < N; i++)
{
int c = length[i];
int q = k / c;
int r = k - (q * c);
k = q;
position[i] = element[i][r];
}
// combine the chars
outstr[j] = string.Join("", position);
}
// join all of the strings together
//(note: joining them all at once is much faster than doing it
//incrementally, if a mass concatenate facility is available
string result = string.Join(", ", outstr);
Console.Write(result);
}
I am not a Java programmer either, so I adapted Svinja's c# answer to my algorithm, assuming that you can convert it to Java also. (thanks to Svinja..)