For a program I have to write I am required to turn a 2 dimensional array of single digit intgers into a string of numbers separated by spaces. A test code is provided for me and when I run it, my code fails both arrayToString tests. I am unable to find where my logic error is. Someone help!
public static String arrayToString(int[][] a) {
String aString;
aString = "";
int column;
int row;
for (row = 0; row < a.length; row++) {
for (column = 0; column < a[0].length; column++ ) {
aString = aString + " " + a[row][column];
}
aString = aString + "\n";
}
return aString;
}
I can think of three possible issues.
The test code doesn't want to see the space that you are putting at the beginning of every line.
The test code is passing an array where some of the entries are null. Your code doesn't cope with this.
The test code is passing an array where the entries have different lengths. Your code doesn't cope with this either.
Until you post the test code, we can't see which one the problem is. But you could deal with all three by changing your loop to this.
for (row = 0; row < a.length; row++) {
if (a[row] != null && a[row].length > 0) {
aString = aString + a[row][0];
for (column = 1; column < a[row].length; column++) {
aString = aString + " " + a[row][column];
}
}
aString = aString + "\n";
}
int[][] a = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
public static String arrayToString(int[][] a) {
String aString;
aString = "";
int column;
int row;
for (row = 0; row < a.length; row++) {
for (column = 0; column < a[0].length; column++ ) {
aString = aString + " " + a[row][column];
}
aString = aString + "\n";
}
return aString;
}
Output:
1 2 3
4 5 6
7 8 9
If you skip this line aString = aString + "\n"; your output will look like this
1 2 3 4 5 6 7 8 9
#dawood-ibn-kareem explain good the possible cause of the failure of the test.
With Java 8 Stream, it's pretty easy to do what you want!
With the input: [[1,2,3], [3,4,5], [5,6,7]]
public static String arrayToString(int[][] a) {
return Arrays.stream(a)
.map(s -> Arrays.stream(s)
.mapToObj(String::valueOf)
.collect(Collectors.joining(" "))
)
.collect(Collectors.joining("\n"));
}
Output:
1 2 3
3 4 5
5 6 7
Other method, to separate each line of the 2D array without carriage return
public static String arrayToString(int[][] a) {
return Arrays.stream(a)
.flatMapToInt(Arrays::stream)
.mapToObj(String::valueOf)
.collect(Collectors.joining(" "));
}
Output
1 2 3 3 4 5 5 6 7
Have fun!
Your code is basically OK, except you are putting a leading space at the start of every line. To clean them up before returning, add this line:
aString = aString.replaceAll("(?m)^ ", "");
This uses regex to delete (by replacing with a blank) all spaces at the start of lines. The regex flag (?m) makes ^ match the start of every line of the input (normally ^ matches only the start of input).
Related
I am posting this question related to how to write values one below the other without using System.out.println(). I believe generally when we want to print out values we can use arrays or lists etc. It would go something like this, for example:
public class Main {
public static void main(String[]args){
int[] myList = new int[10] ;
for(int i = 0 ; i < myList.length ; i++){
myList[i] = i ;
System.out.println(myList[i] + "\n");
}
}
}
But I want to know how to print values in a box like this:
1 2 3 4
5 6 7 8
Thank you,
It is not completely clear what you want to achieve. If your purpose is to display data on standard out (console) I don't see any reason not to use System.out.println(), .print() or .printf().
Warning, long answer with questionable relevance
To print your values in two rows can be done in many different ways. Here is one option:
private static void printNums2() {
int rowLength = 4;
for (int i = 1; i < 9; i++) {
System.out.print(i + ((i % rowLength == 0) ? " \n" : " "));
}
System.out.println();
}
Prints the current number, i, and then checks if i has reached the end of a row with modulus. If so, prints a new line character. (Loop starts at 1 and goes to 8 to match the numbers in your output.)
I noticed in your example output there are varying number of spaces as well. Here is a version of the above which achieves this as well:
private static void printNums2b() {
int rowLength = 4;
for (int i = 1; i < 9; i++) {
System.out.printf("%-" + (i % rowLength + 2) + "d" + ((i % rowLength == 0) ? " \n" : ""), i);
}
System.out.println();
}
In short, it uses printf() to format the output and sets the padding on the number to modulus of the position (to account for rows) + 1 (because 0 doesn't work).
One interpretation of your question is that you don't want to print too often. There is no reason we have to print every number by itself. We can accumulate the output and then print it all at once.
Here is a solution using a StringBuilder (standard Java, no extra libraries needed):
private static void printNums3() {
int rowLength = 4;
StringBuilder sb = new StringBuilder();
for (int i = 1; i < 9; i++) {
sb.append(i).append(' ');
if ((i % rowLength == 0)) {
sb.append('\n');
}
}
System.out.println(sb.toString());
}
Puts all the numbers in the StringBuilder, adds a newline at the end after every 4th number and then prints the entire thing at the end.
And again, with varying spaces:
private static void printNums3b() {
int rowLength = 4;
StringBuilder sb = new StringBuilder();
for (int i = 1; i < 9; i++) {
sb.append(String.format("%-" + (i % rowLength + 2) + "d", i));
if ((i % rowLength == 0)) {
sb.append('\n');
}
}
System.out.println(sb.toString());
}
I don't think there is any particular benefit to using arrays. But then again, there are many ways to achieve this output. Since we don't know more about what you really want to achieve, if your array serves some other purpose (I removed the array because it's not needed for the printing) or what type of data you want to print other than numbers, I can't really give more ideas.
I have an algorithm for Java that shuffles a string. I already have the output of the shuffled string and the algorithm that shuffled it...
static String Validate(String f) {
StringBuilder str = new StringBuilder(f);
for (int i = 0; i < str.length(); i++) {
for (int j = i; j < str.length()-1; j++) {
char t = str.charAt(j);
str.setCharAt(j, str.charAt(j+1));
str.setCharAt(j + 1, t);
}
}
System.out.print(str);
return "" + str.toString();
}
and the output string is...
lgcnyurVr34d0Df{__3_R}43na501
My question is: how to retrieve the original string?
Yes, it is possible to revert the process. The original String was flag{c4n_y0u_r3V3r53_4ndR01D}
The original algorithms makes the following steps:
0 0 ABCDEF
0 1 BACDEF
0 2 BCADEF
0 3 BCDAEF
0 4 BCDEAF
1 1 BCDEFA //A is at the end now
1 2 BDCEFA
1 3 BDECFA
1 4 BDEFCA
2 2 BDEFAC //C was at index 2 at the beginning of this outer loop iteration
2 3 BDFEAC
2 4 BDFAEC
3 3 BDFACE //now E went to the end of the String
3 4 BDFCAE
4 4 BDFCEA
To revert it, one needs to reverse the direction of the loops and the direction the letters are swapped.
static String reverseValidate(String reversed) {
StringBuilder str = new StringBuilder(reversed);
for (int i = str.length() - 1; i >= 1; i--) {
for (int j = str.length() - 1; j >= i; j--) {
char t = str.charAt(j);
str.setCharAt(j, str.charAt(j - 1));
str.setCharAt(j - 1, t);
}
}
return str.toString();
}
The algorith you have posted works it the following way:
For each index in the string length, it starts from this index and moves that letter to the end.
To see it, try printing System.out.println(i + " " + j + " " + str);
somewhere in the inner loop.
Following this question, I want to now code "6 choose 2" times "4 choose 2." By that I mean, lets say I have 6 characters "A B C D E F." The first time I choose any two characters to delete. The 2nd time I want to choose 2 different letters to delete and then I append the results of these two trials. Hence, I will receive 90("6 choose 2" times "4 choose 2") eight character strings. The characters in the pattern are from the same pattern {1,2,3,4,5, 6}. All the characters are unique and no repetition.
Here is what I have so far.
public String[] genDelPatterns(String design){
char[] data = design.toCharArray();
String[] deletionPatterns = new String[15];
int x = 0;
StringBuilder sb = new StringBuilder("");
int index = 0;
for(int i = 0; i < (6-1); i++){
for(int j = i+1; j < 6; j++){
for(int k= 0; k < 6; k++){
if((k != j) && (k != i))
sb.append(String.valueOf(data[k]));
}
deletionPatterns[x++] = sb.toString();
sb = new StringBuilder("");
}
}
return deletionPatterns;
}
public String[] gen8String(String[] pattern1, String[] pattern2){
String[] combinedPatterns = new String[225];
int k = 0;
for(int i = 0; i < 15; i++)
{
for(int j = 0; j < 15; j++)
combinedPatterns[k++] = pattern1[i] + pattern2[j];
}
return combinedPatterns;
}
I will be calling the methods like this:
gen8String(genDelPatterns("143256"), genDelPatterns("254316"));
Currently, I am generating all the possible 8 letter strings. But I want to only generate the 8 character strings according to the aforementioned specifications. I am really stuck on how I can elegantly do this multiplication. The only way I can think of is to make another method that does "4 choose 2" and then combine the 2 string arrays. But this seems very roundabout.
EDIT: An example of an 8 character string would be something like "14322516", given the inputs I have already entered when calling gen8String, (143256,254316). Note that the first 4 characters are derived from 143256 with the 5 and 6 deleted. But since I deleted 5 and 6 in the first trail, I am no longer allowed to delete the same things in the 2nd pattern. Hence, I deleted the 3 and 4 from the 2nd pattern.
you have a chain of methods , each one called a variation itself.
For so, my advice is to use a recursive method!
to achieve your goal you have to have a little experience with this solution.
A simple example of a method that exploits the recursion:
public static long factorial(int n) {
if (n == 1) return 1;
return n * factorial(n-1);
}
I can also suggest you to pass objects (constructed to perfection) for the method parameter, if is too complex to pass simple variables
This is the heart of this solution in my opinion.
While what you tried to do is definitely working, it seems you are looking for other way to implement it. Here is the skeleton of what I would do given the small constrains.
// Very pseudo code
// FOR(x,y,z) := for(int x=y; x<z;x++)
string removeCharacter(string s, int banA, int banB){
string ret = "";
FOR(i,1,7){
if(i != banA && i != banB){
ret += s[i];
}
}
return ret;
}
List<string> Generate(s1,s2){
List<string> ret = new List<string>();
FOR(i,1,7) FOR(j,i+1,7) FOR(m,1,7) FOR(n,m+1,7){
if(m != i && m != j && n != i && n != j){
string firstHalf = removeCharacter(s1,i,j);
string secondHalf = removeCharacter(s2,m,n);
ret.Add(firstHalf + secondHalf);
}
}
return ret;
}
This should generate all possible 8-characters string.
Here is the solution I came up with. Doesn't really take "mathematical" approach, I guess. But it does the job.
//generating a subset of 90 eight character strings (unique deletion patterns)
public static String[] gen8String(String[] pattern1, String[] pattern2){
String[] combinedSubset = new String[90]; //emty array for the subset of 90 strings
String combinedString = ""; //string holder for each combined string
int index = 0; //used for combinedSubset array
int present = 0; //used to check if all 6 characters are present
for(int i = 0; i < 15; i++){
for(int j = 0; j < 15; j++){
combinedString = pattern1[i] + pattern2[j]; //combine both 4 letter strings into 8 char length string
char[] parsedString = combinedString.toCharArray(); //parse into array
//check if all 6 characters are present
for(int k = 1; k <= 6; k++)
{
if(new String(parsedString).contains(k+"")) {
present++;
}
else
break;
//if all 6 are present, then add it to combined subset
if(present == 6)
combinedSubset[index++] = combinedString;
}
present = 0;
}
}
return combinedSubset;
}
I have a text file. I am reading it then placing it into a 2D-Array. There are spaces. I need to get rid of those spaces. But I can't use trim properly. Here is my code:
while ((line = br.readLine() ) != null ){
char[] row = line.toCharArray();
line.trim();
int counter = 0;
for (int i = 0; i < row.length; i++) {
maze[counter][i] = row[i];
System.out.print(maze[i]);
counter++;
}
System.out.printf("%n");
}
The output is as follows:
1 1 1 0
0 0 1 0
0 0 1 0
0 9 1 0
The elements in the text file I read has one space between each other. But I get too many spaces as output. I need to get this as
1110
0010
0010
0910
I think I should use trim method, but I could not figure it out.
You can use String#split with a regular expression of something like \s+, for example...
String text = "1 1 1 0";
String elements[] = text.split("\\s+");
for (String value : elements) {
System.out.println("[" + value + "]");
}
Which outputs
[1]
[1]
[1]
[0]
(The braces are there to demonstrate that no spaces remain)
In your example I might still be tempted to still us line = line.trim(); to ensure that there are no leading or trailing space which might cause empty values to be included...
You can use (string).replace(" ", '\0') to replace all spaces with blanks
For example:
String line = "1 2 2 3 4 2 122 23 3 3 3 3"; //example
line = line.replace(' ', '\0'); //'\0' is the key for blank (or nothing)
System.out.println(line);
will produce
122342122233333
This will get rid of the spaces and only use the valid input (i.e. the numbers). It says row, but the only input will be the same characters.
Hope this helps.
Quickest way for me would be to just use a nested loop to print each element of the array individually. E.g.
String [][] maze = new String [4][4];
for (int i = 0; i < maze.length; i++) {
maze[i][0] = "1";
maze[i][1] = "0";
maze[i][2] = "1";
maze[i][3] = "0";
}
for (int k =0;k<maze.length;++k){
for(int j=0;j<maze.length;++j)
{
System.out.print(maze[k][j]);
}
System.out.println();
}
My problem requires me to create a list of all 20 amino acids permutations based on a user imputed chain length. For example, I currently have code that works if the user wants a 3 chain length. This is 20^3 possibilities. So I have 3 nested for loops that run through all possibilities, then a counter that outputs the number of permutations to make sure the answer is correct. How could I code this method so it output permutations based on user input?
protected void getPermutations(int chainlength) {
int counter = 0;
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 20; j++) {
for (int k = 0; k < 20; k++) {
System.out.println(AcidArray[i].getTcode() + "-"
+ AcidArray[j].getTcode() + "-"
+ AcidArray[k].getTcode());
counter++;
}
}
}
System.out.println("chain length = " + chainlength);
System.out.println(counter + " permutations");
}
Thanks
Recursion is your friend in this situation
protected String getPermutations(int chainlength) {
int counter = 0;
if(chainlength > 0) { // so that the counter is not 1
counter = getSubPermutations("", chainlength));
}
System.out.println("chain length = " + chainlength);
System.out.println(counter + " permutations");
}
private int getSubPermutations(String prefix, int chainlength){
if(chainlength == 0){ //The bottom of the stack, print out the combination
System.out.println(prefix.substring(0,prefix.length-1)); //remove the final '-'
return 1;
} else {
int counter = 0
for(int i = 0; i < 20; i++) {
//Add this level T code to the string and pass it on
counter += getSubPermutations(prefix + AcidArray[i].getTcode() + "-", chainlength-1);
}
return counter;
}
}
What this will do is make a tree of calls. If chainlength is one then it will call getSubPermutations with 1. This will run through the for loop calling getSubPermutations again with the String for the first value and a chainlength of 0. In this case the string will only have one T code in it. Each inner call will hit the first if statement so it will print out the string containing one T code and return 1. All these will be added up so the counter returned to getPermutations will be 20. By this stage all the permutations will have been printed out.
As chain length increases getSubPermuations is called recursively. With a chainlength of 2 it will call getSubPermutations 20 times with a chain length of 1, passing in the string of the T code. Each of these will call getSubPermutations with a chainlength of 0, with a string containing two T codes. This will then print out the full string and return 1. These return values will get added up to 20 as in the previous example but now when they are returned to the next level they are added up to return a final 400 to getPermutations and 400 Strings will have been printed.