creating a 2d array from a String - java

I am trying to create a 2d array from a String. But i am getting some weird results when i try to set the value of elements in the array.
Here String s = 120453678;
public int[][] create2D(String s){
int[][] puzzle = new int[3][3];
int a;
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
puzzle[i][j] = (int)s.charAt(i*3+j);
System.out.println(s.charAt(i*3+j));
System.out.println(i +" "+ j+" "+ puzzle[i][j]);
}
}
return puzzle;
}
The output i am getting is. Don't know why its 49, 50 , 51 and so on
1
0 0 49
2
0 1 50
3
0 2 51
4
1 0 52
5
1 1 53
0
1 2 48
6
2 0 54
7
2 1 55
8
2 2 56

You are converting the character to it's int representation. That's why you are getting this result.
puzzle[i][j] = (int)s.charAt(i*3+j);
ASCII table can be referred below. You can see that 49 is ASCII value of character '1'.
http://www.asciitable.com/
To fix your code, you can use
puzzle[i][j] = Character.getNumericValue(s.charAt(i*3+j));

Related

Printing a snake pattern using an array

I'm having trouble with an assignment where we are required to print out this array:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
My code is somewhat correct but it is not printing 10 and 19 where it should be.
My output:
Choose a number for the rows from 0 to 16.
5
Choose a number for the columns from 0 to 16
5
1 0 10 0 19
2 9 11 18 20
3 8 12 17 21
4 7 13 16 22
5 6 14 15 23
My code:
//snake move with the number
import java.util.Scanner;
public class SnakeMove {
public static void main(String[] args) {
//create Scanner object
Scanner inScan = new Scanner(System.in);
//prompt the user to choose number for the Row from 0 to 16
System.out.println("Choose a number for the rows from 0 to 16.");
//take the input from user with nextInt() method
//use the variable int row
int row = inScan.nextInt();
//prompt the user to choose number for the Col from 0 to 16
System.out.println("Choose a number for the columns from 0 to 16");
//take the input from user with nextInt()
//use the variable int col
int col = inScan.nextInt();
if (row != col) {
System.out.println("Run the program again and choose the same number for Row and Col");
System.exit(0);
}
int[][] arr = move(row, col);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}//main method
static int[][] move(int row, int col) {
boolean flag = true;
int count = 1;
int[][] array = new int[row][col];
for (int j = 0; j < array[0].length; j++) {
if (flag) {
for (int i = 0; i < array.length; i++) {
//assign the increment value of count
// to specific array cells
array[i][j] = count;
count++;
}
flag = false;
} else {
//row decrement going up
for (int i = array.length - 1; i > 0; i--) {
//assign the increment value of count
// to specific array cells
array[i][j] = count;
count++;
}
flag = true;
}
}//column increment
return array;
}//move method
}//end SnakeMove class
Can anyone detect what is causing the error? Any help would be appreciated.
I believe this is a good alternative and easy to understand. Do comment if you have a simplified version of the same.
Code:
import java.util.Arrays;
import java.util.Scanner;
public class SnakePatternProblem {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // *INPUT*
int row = scanner.nextInt();
int col = scanner.nextInt();
int[][] array = new int[row][col];
// Initializing first row of the array with a generalized expression
for (int i = 0; i < col; i++) {
if (i % 2 != 0) array[0][i] = col * (i+1);
else array[0][i] = (col * i) + 1;
}
array[0][0] = 1; // this element is not covered in the above loop.
// Nested loop for incrementing and decrementing as per the first row of elements.
for (int i= 1; i< row; i++){
for (int j=0; j< col; j++){
if(j%2==0) array[i][j] = array[i-1][j] + 1;
else array[i][j] = array[i-1][j] - 1;
}
}
System.out.println(Arrays.deepToString(array)); // *OUTPUT
}
}
Explanation:
Consider first row of 5 x 5 matrix named "arr" with snake pattern:
1 10 11 20 21
The element in the odd column is equivalent to ((currentColumn + 1) * Total_No_Of_columns);
Example: arr[0][1] = (1 + 1)* 5 = 10
The element in the even column is equivalent to (currentColumn * Total_No_Of_columns) + 1;
Example: arra[0][2] = (2 * 5) + 1 = 11;
Important Note: element at first row, first column is Zero
arr[0][0] = 1 -> must be declared
Now, the remaining matrix is incrementing or decrementing loop from the first element in that column.
Elements with even column number gets incremented by 1 in each row from the first element of that column.
1 -> First element of column-0
2 -> (1 + 1)
3 -> (2 + 1).... so on
4
5
Elements with odd column number gets decremented by 1 in each row from the first element of that column.
10 -> First element of column - 1
9 -> (10 - 1)
8 -> (9 - 1).... so on
7
6
This will generate the "snaking" pattern you described.
It could be simplified with ternary but this makes it more readable I think
It would be interesting to find a more clever way about it though, if anyone finds a better way pls comment
public static int[][] genArray(int length) {
int[][] arr = new int[length][length];
int counter = 0;
for (int col = 0; col < arr.length; col++) {
if (col % 2 == 0) {
for (int row = 0; row < arr.length; row++) {
arr[row][col] = counter++;
}
} else {
for (int row = arr.length - 1; row >= 0; row--) {
System.out.println("row: " + row + ", col: " + col);
arr[row][col] = counter++;
}
}
}
}
return arr;
}
You can create such an array as follows:
int m = 5;
int n = 4;
int[][] snakeArr = IntStream.range(0, n)
.mapToObj(i -> IntStream.range(0, m)
// even row - straight order,
// odd row - reverse order
.map(j -> (i % 2 == 0 ? j : m - j - 1) + i * m + 1)
.toArray())
.toArray(int[][]::new);
// output
Arrays.stream(snakeArr)
.map(row -> Arrays.stream(row)
.mapToObj(e -> String.format("%2d", e))
.collect(Collectors.joining(" ")))
.forEach(System.out::println);
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
Transposing snake array:
int[][] transposedSA = new int[m][n];
IntStream.range(0, m).forEach(i ->
IntStream.range(0, n).forEach(j ->
transposedSA[i][j] = snakeArr[j][i]));
// output
Arrays.stream(transposedSA)
.map(row -> Arrays.stream(row)
.mapToObj(e -> String.format("%2d", e))
.collect(Collectors.joining(" ")))
.forEach(System.out::println);
1 10 11 20
2 9 12 19
3 8 13 18
4 7 14 17
5 6 15 16
An easy way to do it is to create a 2-D array as shown below and then print its transpose.
1 2 3 4 5
10 9 8 7 6
11 12 13 14 15
20 19 18 17 16
21 22 23 24 25
It is a 2-D array of the dimension, LEN x LEN, where LEN = 5.
The above pattern goes like this:
The pattern starts with a start value of 1.
When the main loop counter is an even number, the counter, which assigns a value to the array, starts with start value and increases by one, LEN times. Finally, it sets start for the next row to start with final_value_of_the_array_value_assignment_counter - 1 + LEN.
When the main loop counter is an odd number, the counter, which assigns a value to the array, starts with start value and decreases by one LEN times. Finally, it sets start for the next row to start with start + 1.
The transpose of the above matrix will look like:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
In terms of code, we can write it as:
public class Main {
public static void main(String[] args) {
final int LEN = 5;
int[][] arr = new int[LEN][LEN];
int start = 1, j, k, col;
for (int i = 0; i < LEN; i++) {
if (i % 2 == 0) {
k = 1;
for (j = start, col = 0; k <= LEN; j++, k++, col++) {
arr[i][col] = j;
}
start = j - 1 + LEN;
} else {
k = 1;
for (j = start, col = 0; k <= LEN; j--, k++, col++) {
arr[i][col] = j;
}
start++;
}
}
// Print the transpose of the matrix
for (int r = 0; r < LEN; r++) {
for (int c = 0; c < LEN; c++) {
System.out.print(arr[c][r] + "\t");
}
System.out.println();
}
}
}
Output:
1 10 11 20 21
2 9 12 19 22
3 8 13 18 23
4 7 14 17 24
5 6 15 16 25
Change the value of LEN to 10 and you will get the following pattern:
1 20 21 40 41 60 61 80 81 100
2 19 22 39 42 59 62 79 82 99
3 18 23 38 43 58 63 78 83 98
4 17 24 37 44 57 64 77 84 97
5 16 25 36 45 56 65 76 85 96
6 15 26 35 46 55 66 75 86 95
7 14 27 34 47 54 67 74 87 94
8 13 28 33 48 53 68 73 88 93
9 12 29 32 49 52 69 72 89 92
10 11 30 31 50 51 70 71 90 91

Power table using while loop formatting and logic error

I am trying to make a table from 1 - 5, which displays there power up to 6 values.
so for example, the 2 column would go from, 1,2,4,8,16,32,64 and would stop there.
I am having trouble getting proper table format. Since the numbers don't align where they should be.
for example:
the problem I am facing right now is this
1 2 3 4 5
1 1 1 1 1 1 1 2 4 8 16 and so and so on
any well would be appreciated, my code is down below.
int powNumb=5;
int powValue=6;
for (int i = 1; i <= powValue; i++) {
System.out.printf("%10d",i);
}
System.out.println();
for (int i = 1; i <= powNumb; i++) {
for (int j = 0; j <=powValue; j++) {
System.out.printf("%10.0f",Math.pow(i, j));
}
}
This should help you
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10d", i); //Print the number (1st col)
for (int j = 0; j <= powValue; j++) { //This loop prints the powers of the curent number 'i'
System.out.printf("%10.0f", Math.pow(i, j));
}
System.out.println(); //To end the current row
}
This prints
num num^0 num^1 num^2 ... num^powValue
where num is from 1 to powNumb
Output
1 1 1 1 1 1 1 1
2 1 2 4 8 16 32 64
3 1 3 9 27 81 243 729
4 1 4 16 64 256 1024 4096
5 1 5 25 125 625 3125 15625
You mean the same base for every element, so there is no need for inner loop:
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10.0f", Math.pow(powValue, i));
}
This way the base of power is always powValue.
First, you need a println statement somewhere in your inner for loop to separate the rows.
Second, you need to switch the i and j in your call to Math.pow. Because with how it's currently set up, each row is value i = row number to powers 0 through 6. For example, the first row would be 1^0 1^1 1^2 1^3 1^4 1^5 1^6. Then, the second row would be 2^0 2^1 2^2 2^3 2^4 2^5 2^6 However, you want the first row to be 1^0 2^0 3^0 4^0 5^0, second row 1^1 2^1 3^1 4^1 5^1, etc. So your code should be changed to something like this,
int powNumb=5;
int powValue=6;
for (int i = 1; i <= powNumb; i++) {
System.out.printf("%10d",i);
}
for (int i = 0; i <= powValue; i++) {
System.out.println();
for (int j = 1; j <=powNumb; j++) {
System.out.printf("%10.0f",Math.pow(j, i));
}
}
Output:
1 2 3 4 5
1 1 1 1 1
1 2 3 4 5
1 4 9 16 25
1 8 27 64 125
1 16 81 256 625
1 32 243 1024 3125
1 64 729 4096 15625
Also, I had to switch powNumb and powValue in the for loop conditions.

How to check duplicate numbers and print out the read input numbers in the same order that they were read (excluding all duplicates.)

I'm trying to write a code. There I'll get max 1000 (int)inputs from an user (it has to be array[1000]) and it'll print out the ints in the same order as they were written.
Reading can be stopped by ctrl+z if the user wants that. The program will not write out duplicate numbers.
Example;
Input: 45 77 -22 3 45 0 21 -1 3
Output: 45 77 -22 3 0 21 -1
So far I've coded(within 2 days):
static int i = 0;
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] array = new int[1000];
int[] arrayCopy = new int[1000];
int k=0,j=0;
System.out.println("enter your integer numbers");
while(input.hasNext())
{
array[i] = input.nextInt();
for(j =0 ; j< array.length; j++)
{
arrayCopy[j] = array[j];
}
for( k =1; k<arrayCopy.length; k++)
{
int aV = arrayCopy[k];
}
i++;
}
input.close();
}
}
Use a HashMap to keep track of numbers already seen. Only add to your output string if it is a new number. You can modify your code with the following:
int[] array = new int[1000];
Scanner input = new Scanner(System.in);
int index = 0;
while(input.hasNext()) {
array[index] = input.nextInt();
index++;
}
HashMap<Integer, Boolean> seenNumbers = new HashMap<Integer, Boolean>();
String result = "";
for (int i = 0; i < index; i++) {
int value = array[i];
if (!seenNumbers.containsKey(value)) {
result += " " + value;
seenNumbers.put(value, true);
}
}
System.out.println(result);
The simplest solution is for me to use LinkedHashSet - will not allow duplicates and preserves insertion order
Set <Integer> set = new LinkedHashSet<>(1000);
while (input.hasNext()) {
int next = input.nextInt();
set.add(next);
}
input.close();
for (Integer number : set) {
System.out.print(number+" ");}
Should work
Provided you can resolve a sort order, and use arrays:
Below pseudocode and data. It's written as arrays, but you can ofc always loop where required. I also write the data without commas, as that's what my language Dyalog APL outputs ;-), but the data below are simply 9-element 1-dimensional arrays. The result seems to hold 7 elements.
You have
A = 45 77 -22 3 45 0 21 -1 3
Resolve the ascending sort order for A:
order = 3 8 6 4 9 7 1 5 2 // A[3] is smallest, then A[8], A[6], etc.
Write:
B = A[order] // B now holds: -22 -1 0 3 3 21 45 45 77
Loop through all but first element of B, check if next element is same as current. Write the result to C, which is a same-length vector of zeroes, however first element of C must be 1:
C = 1 0 0 0 0 0 0 0 0
s = 2
:While (s <= [length of C])
C[s] = (B[s-1] == B[s]) // C[s] is 0 or 1
s += 1
:End
Now C holds:
1 1 1 1 0 1 1 1 0
Create an empty variable D (or just copy from A or B - you will overwrite it):
D = A
Assign the elements of D as follows:
D[order] = C // D now holds: 1 1 1 1 0 1 1 1 0
Take only D elements of A (you pick elements of A and append them to a Result, which is initially empty - ie. has zero length):
s = 1
:While (s <= [lenght of A])
:if D[s] // Means: If (D[s] == 1)
[append A[s] to Result]
s += 1
:End
:End
Result now contains
45 77 -22 3 0 21 -1
Use Set instead of array. Set wont add duplicates.

Outputting values 1 to A, with B values per row (Java)

public static void applicationB(int A, int B) {
int number = 1;
for (int row = 0; row < A; row++) {
for (int col = 0; col < B; col++) {
int output = number + row++;
System.out.printf("% 4d", output);
}
// does it skip because of this?
System.out.println("");
}
}
It outputs with A = 20, B = 5
1 2 3 4 5
7 8 9 10 11
13 14 15 16 17
19 20 21 22 23
The correct output should be
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
I cannot figure out how to get it to stop skipping 6, 12, and 18.
Am I just doing this a horrible way? or am I on the right track?
You are incrementing row in two places. Also, it would be easier to just have one loop, and output a line break every B elements (you can use i % B to test for this).
I would suggest the following approach. Iterate over the values you want to print out, from 1 to the maximum value (A). Then, print a newline whenever the remainder of value divided by the number of columns (B) is zero.
for (int value = 1; value <= A; value++) {
System.out.printf("% 4d", value);
if (value % B == 0) {
System.out.println("");
}
}

longest common subsequence function does not work for all examples

EDIT: UP
The code does not work properly with the strings below.
"1 11 23 1 18 9 15 23 5"
"11 1 18 1 20 5 11 1"
EDIT: I noticed, that if I change 20 to 40 in second string, the function works properly...
For strings:
"12 4 55 11 8 43 22 90 5 88 15"
"15 66 4 36 43 22 78 88 32"
it works properly. Where is the problem?
Here is my code:
int[][] tabelka = new int[linia1.length()+1][linia2.length()+1];
for (int i = 0; i<linia1.length(); i++) {
for (j = 0; j<linia2.length(); j++) {
if ( linia1.charAt(i) == linia2.charAt(j) ) {
tabelka[i+1][j+1] = tabelka[i][j] + 1;
}
else {
tabelka[i+1][j+1] = Math.max(tabelka[i+1][j], tabelka[i][j+1]);
}
}
}
for (int i = 0; i<linia1.length(); i++) {
for (j = 0; j<linia2.length(); j++) {
System.out.println(tabelka[i][j]);
}
}
StringBuffer podciag = new StringBuffer();
for(int x = linia1.length(), y = linia2.length(); x != 0 && y != 0; ) {
if( tabelka[x][y] == tabelka[x-1][y] ) {
licznik++;
x--;
}
else if( tabelka[x][y] == tabelka[x][y-1] ) {
licznik++;
y--;
}
else {
licznik++;
assert linia1.charAt(x-1) == linia2.charAt(y-1);
podciag.append(linia1.charAt(x-1));
x--;
y--;
}
}
String buff = podciag.reverse().toString();
The output of this code (for the first two strings) is:
11 1 18 1 2 5
However, the output should be:
11 1 18 5
For a full / better explanation, please refer to:
http://www.geeksforgeeks.org/dynamic-programming-set-4-longest-common-subsequence/
http://www.geeksforgeeks.org/printing-longest-common-subsequence/
I think that you are constructing the array correctly. However, I am not sure about the way the table is being read in order to construct the LCS.
The idea is to start at the end of the 2D array solution[str1.length()][str2.length()] and if:
The last characters of str1 and str2 are equal then the last character is part of the LCS and decrement both indexes
If they are not equal, compare solution[i-1][j] and solution[i][j-1] and go in direction of greater value.
Repeat until either of the indexes are 0.

Categories