I'm having trouble with this, maybe you could help me:
I have 3 strings like: word1, word2, word3 and I have to build a matrix with them, like this:
on the first row : word1("ABC"), second row: word2("DEF") and third row: word3("GHI").
A|B|C
D|E|F
G|H|I
I need this because after that I have to check if the formed words ("ADG","BEH","CFI") are in an array of words. And I don't know how to put those strings in the matrix so I can check. Any help is useful.
Thanks
Based on this comment:
the words have the same size, because the matrix is actually like a puzzle. I choose randomly 3 words from an array, put them in a matrix and check after that if the words resulted are from the same array.
I'll assume some things in order to make this work (since we don't have enough info):
You have an array of Strings where you have all the words
private String[] words;
You have a method to randomly pick up 3 Strings from this array.
private String s1, s2, s3;
public void pickThreeRandomWords() {
s1 = aRandomWord(words);
s2 = aRandomWord(words);
s3 = aRandomWord(words);
//or maybe another fancy algorithm to get this...
}
So you would need an array of array of chars based on these 3 Strings. This code could do the work for you:
public char[][] createMatrixFromStrings(String s1, String s2, String s3) {
char[][] theMatrix = new char[3][]; //yes, hardcoded
theMatrix[0] = s1.toCharArray();
theMatrix[1] = s2.toCharArray();
theMatrix[2] = s3.toCharArray();
return theMatrix;
}
Of course, if you would want to make this method to support more than 3 Strings you can make the method to receive a random quantity of Strings:
public char[][] createMatrixFromStrings(String ... strings) {
if (strings == null || strings.length == 0) return null;
char[][] theMatrix = new char[strings.length][];
int i = 0;
for(String s : strings) {
theMatrix[i++] = s.toCharArray();
}
return theMatrix;
}
You can build the result words without a matrix:
List<String> verticalWords = new ArrayList<String>();
for (int i = 0; i < horizontalLen; i++){
String currentWord = "";
for (int j = 0; j < wordCount; j++)
currentWord += words.get(j).get(i);
verticalWords.add(currentWord);
}
P.S. For the currentWord you can use a StringBuilder to make it more efficient, but I doubt it is highly needed here.
Java doesn't have matrix.It has array of array
So,you can try this
List<char[]> lst=new ArrayList();//stores a list of char[]
lst.add(("ADC".toCharArray()));//adds array of characters i.e 'A','D','C'
lst.add(("DEF".toCharArray()));
lst.get(0)[0];//A
lst.get(1)[0];//D
Now you can iterate vertically
for(int i=0;i<lst.size();i++)temp+=lst.get(i)[0];
temp would have AD which you can now cross check with equals method
The main thrust of this goal is that you're taking a one-dimensional value, and converting it into a two-dimensional value. There are many ways you can do this, but here are the two that come off the top of my head:
Set up a nested while loop to iterate over the first dimension, and when it reaches the length, reset and cause the outer loop to increment, much like a clock
You can create a new subarray using ArrayUtils.toSubArray(), and with some finagling, get that to work:
Create a new row of the array each time, based on the dimension slices you want to hit up. I'll leave figuring this one out as an exercise for the reader. But here's a hint:
for(int i = 0; i < theDimension; i++, j += 3) {
ret[i] = ArrayUtils.subarray(word, i*theDimension, j);
}
Lastly, I assume that there's a restraint on the type of input you can receive. The matrix must be square, so I enforce that restriction before we build the array.
I strongly encourage you to poke and prod this answer, and not just blindly copy it into your schoolwork. Understand what it's doing so you can reproduce it when you're asked to again in the future.
public char[][] toMatrix(int theDimension, String theEntireWord) {
if(theEntireWord.length() != theDimension * theDimension) {
throw new IllegalArgumentException("impossible to add string to matrix of uneven dimension");
}
char[][] ret = new char[theDimension][theDimension];
int i = 0;
int j = 0;
while(i < theDimension) {
if(j == theDimension) {
j = 0;
++i;
} else {
ret[i][j] = theEntireWord.charAt((i * theDimension) + j);
j++;
}
}
return ret;
}
I think this will sort your problem.
package printing;
public class Matrix {
public static void main(String[] args) {
//Length can define as you wish
String[] max = new String[10];
String[] out = null;
//Your Inputs
max[0]="ADG";
max[1]="BEH";
max[2]="CFI";
//following for loop iterate your inputs
for (int i = 0; i < max.length; i++) {
if(out==null){out= new String[max.length];}
String string = max[i];
if(string==null){ break;}
//Here breaking input(words) one by one into letters for later contcatnating.
String[] row = string.split("");
for (int j = 0; j < row.length; j++) {
String string1 = row[j];
// System.out.println(string1);
//create the values for rows
if(out[j]!=null){ out[j]=out[j]+string1;}
else{
out[j]=string1;
}
}
}
//following for loop will out put your matrix.
for (int i = 0; i < out.length; i++) {
String string = out[i];
if(out[i]==null){break;}
System.out.println(out[i]);
}
}
}
Related
String quantityArray[] = GetStringArray(quantity);
String foodItemArray[] = GetStringArray(fooditems);
this is to change from ArrayList to a String Array
int n1 = fooditems.size();
int n2 = quantity.size();
for(int s = 0; s<n1;s++){
totalFood[s] = quantityArray[s] + foodItemArray[s];
}
I cannot make this totalFood[] function to work as it just keeps crashing my app
public static String[] GetStringArray(ArrayList<String> arr) {
// declaration and initialise String Array
String str[] = new String[arr.size()];
// ArrayList to Array Conversion
for (int j = 0; j < arr.size(); j++) {
// Assign each value to String array
str[j] = arr.get(j);
}
return str;
}
The error that pops up is (Attempt to write to null array)
You need to make sure totalFood array is allocated.
Arrays are themselves Objects in Java.
For example:
totalFood = new String[n1];
This is because totalFood seems to be null according to the error you are seeing. You need to allocate some space (n1 references to be precise for the above example) for the Strings resulting from the concatenation to be stored at. You can take a look at the corresponding Java tutorial here.
Also make sure n1 is equal to n2 which should be equal also to the size of the totalFood array in order to not overrun any of them in your loop.
Finally, there are 2 handy Collection#toArray methods which will do what you are doing in your GetStringArray method. You can use it for example like so:
String quantityArray[] = quantity.toArray(new String[quantity.size()]);
Using the toArray method seems not to be related to the problem, but I just mention it for completeness.
public static String[] GetStringArray(ArrayList<String> arr) {
String str[] = new String[arr.size()];
for (int j = 0; j < arr.size(); j++) {
str[j] = arr.get(j);
}
return Arrays.stream(str).filter(s -> s!=null).toArray(String[]::new);
}
When I run the method below keep in mind ADFGVX will be printed to the left and over the top of the array when its displayed, just like a classic ADFGVX cypher.
static char [][] poly = new char[][]{
{'p','h','0','q','g','6'},
{'4','m','e','a','1','y'},
{'l','2','n','o','f','d'},
{'x','k','r','3','c','v'},
{'s','5','z','w','7','b'},
{'j','9','u','t','i','8'}};
I have written a method that displays a polybius square using a 2d array(array can be seen above) and what I want to do is pair what ever the user enters with the square, so if the user types OBJECT I want it to return FG VX XA DF GV XG.
Scanner console = new Scanner (System.in);
String phrase;
displayGrid();
System.out.println("");
System.out.print("Please enter a phrase you want to use\n");
phrase = console.nextLine();
console.close();
Does anyone here know how I would go about this? I was going to make a switch statement or something but I don't think that would work and even if it did it would be very long and inefficient.
You could just iterate over your array to get the position of the character you are looking for and than decode this position to the letter.
public static String[] cypherADFGVX(String phrase){
String[] output=new String[phrase.length()];
for (int i = 0; i < phrase.length(); i++) {
//optional for breaking
//squareIteration:
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
if(poly[j][k]==phrase.charAt(i)){
output[i]=new String(new char[]{switchChar(j),switchChar(k)});
//To stop the iteration over poly and take care of the next char
//break squareIteration;
}
}
}
}
return output;
}
public static char switchChar(int integer){
switch (integer) {
case 0:
return 'A';
case 1:
return 'D';
//and so on
}
}
If I left any questions just ask.
To answer your questions
Oh. I see. I made it a bit too complicated for java beginners.
An easier solution with just one String would be:
public static String cypherADFGVX(String phrase){
String output=new String[phrase.length()];
for (int i = 0; i < phrase.length(); i++) {
//optional for breaking
//squareIteration:
for (int j = 0; j < 6; j++) {
for (int k = 0; k < 6; k++) {
if(poly[j][k]==phrase.charAt(i)){
output=output+switchChar(j)+switchChar(k)+" ";
//To stop the iteration over poly and take care of the next char
//break squareIteration;
}
}
}
}
return output;
}
Now let me explain what my lines do.
String[] output=new String[phrase.length()];
creates a new array of string where each string are the two capital letters.
It would look like ["FG","VX",...]. It is easier for futher processing in my opinion.
if(poly[j][k]==phrase.charAt(i))
Compares the character at position jk in your square with the i-th character of the input String.
output[i]=new String(new char[]{switchChar(j),switchChar(k)});
I use the String constructor that takes a char-array as argument.
new char[]{'a','b'}
creates the array and fills it with the elements listed in the brackets.
Sure you can use the switch to set the value of a variable and than return that variable.
I have a 2D String array freq:
String freq[][] = new String[26][2];
and I would like to use the contents of the first column only with new String(freq) which would work if freq is a normal array. However I would like to do this with the first column of my 2D array, or would I have to use two 1D arrays to do this:
String freq[][] = new String[26][2];
int free = 0;
for (int b = 0; b < words.length; b++) {
for (int l = 0; l < words[b][0].length(); l++) {
if (new String(freq[0]).indexOf(words[b][0].charAt(l)) < 0) {
freq[free][0] = Character.toString(words[b][0].charAt(l));
free++;
}
}
}
Thanks! :)
Use a StringBuilder and concat all the values (replace 8 with whatever your average word length is):
final StringBuilder builder = new StringBuilder(words.length * 8);
for (String[] nestedWords : words)
{
builder.append(nestedWords[0]);
}
return builder.toString();
You could also do this in java 8 as so:
return Arrays.stream(words).map(a -> a[0]).collect(Collectors.joining());
I'm not quiet sure if I understand what you want to achive but if you only want to iterate over the first column just do something like this and just drop the inner loop
for(int i = 0; i < words.length; i++) {
//Do stuff with words[i][0], e.g.
words[i][0] = Some_usefull_thing;
}
I am trying to reverse all the strings in an array in java, but seem to over write all of them with the first.
private static void palindrome(String[] s) {
int flag=0;
String reverse;
for(int i=0;i<n;i++) // n is declared globally as number of strings
{
reverse="";
for (int j=s[i].length()-1;i>=0;i--)
reverse=reverse+s[i].charAt(j);
if(s[i].equals(reverse))
{
System.out.println(s[i]);
flag=1;
}
}
if(flag==0)
System.out.println("There are no palindromic strings");
}
This line looks wrong:
for (int j = s[i].length()-1; i >= 0; i--)
It should be:
for (int j = s[i].length()-1; j >= 0; j--)
In other words: the indexes in the inner loop are mistaken, they should be using j instead of i. As a side comment - here's a simpler way to reverse a string:
reverse = new StringBuilder(s[i]).reverse().toString();
Try these steps:
String[] strDays = new String[]{"Sunday", "Monday", "Tuesday", "Wednesday"};
List<String> list = Arrays.asList(strDays);
Collections.reverse(list);
strDays = (String[]) list.toArray();
Looks like you used i instead of j in the inner loop.
for (int j=s[i].length()-1;j>=0;j--)
reverse=reverse+s[i].charAt(j);
I'd advise you to break even this small problem into chunks.
Write a separate method that reverses a single String. Get that working and tested. Only then should you iterate over a collection or array and apply it to each member.
You'd have an easier time debugging this if you did it in smaller steps. The fact that your string reversing method was borked would have been apparent right away.
You shouldn't write stuff to System.out like that from methods.
public static String reverse(String s) {
StringBuilder reversed = new StringBuilder(s.length());
// reverse one string here
return reversed.toString();
}
public static String [] reverseAll(String [] originals) {
String [] reversed = new String[originals.length];
for (int i = 0; i < originals.length; ++i) {
reversed[i] = reverse(originals[i]);
}
return reversed;
}
Your inner loop should be:
for (int j=s[i].length()-1; j>=0; j--){
reverse=reverse+s[i].charAt(j);
// ... //
}
for (int j=s[i].length()-1; j >=0; j-- )
### ###
you need to correct your inner loop. Instead of i you need to use loop variable j.
Why are you using this:
for (int j=s[i].length()-1;i>=0;i--)
You should use this instead:
for (int j=s[i].length()-1;j>=0;j--)
I am working on a DP problem in which a string of words with space removed, and I need to implement both buttom-up and memoization version to split the string into individual english words. However, I got the buttom-up version, however, the memoization seems a little complicated.
/* Split a string into individual english words
* #String str the str to be splitted
* #Return a sequence of words separated by space if successful,
null otherwise
*/
public static String buttom_up_split(String str){
int len = str.length();
int[] S = new int[len+1];
/*Stores all the valid strings*/
String[] result = new String[len+1];
/*Initialize the array*/
for(int i=0; i <= len; i++){
S[i] = -1;
}
S[0] =0;
for(int i=0; i < len; i++){
if(S[i] != -1){
for(int j= i+1; j <= len; j++){
String sub = str.substring(i, j);
int k = j;
if(isValidEnglishWord(sub)){
S[k] = 1; //set true indicates a valid split
/*Add space between words*/
if(result[i] != null){
/*Add the substring to the existing words*/
result[i+ sub.length()] = result[i] + " " + sub;
}
else{
/*The first word*/
result[i+ sub.length()] = sub;
}
}
}
}
}
return result[len]; //return the last element of the array
}
I really confused how to convert this buttom_up_version to the memoized version, hope someone can help..
Well, I'm not an export of memoization, but the idea is to have a "memory" of previous good english words.
The objective is to save computation time: in your case, the call to isValidEnglishWord().
Therefore, you need to adapt your alorythm this way:
walk through the 'str' string
extract a substring from it
checkif the substring is a valid word in your memory.
It's in memory: add a space and the word to your result.
It's not in memory: calls isValidEnglishWord and process its return.
It will give something like (not tested nor compiled)
// This is our memory
import java.util.*
private static Map<String, Boolean> memory = new HashMap<String, Boolean>()
public static String buttom_up_split(String str){
int len = str.length();
int[] S = new int[len+1];
String[] result = new String[len+1];
for(int i=0; i <= len; i++){
S[i] = -1;
}
S[0] =0;
for(int i=0; i < len; i++){
if(S[i] != -1){
for(int j= i+1; j <= len; j++){
String sub = str.substring(i, j);
int k = j;
// Order is significant: first look into memory !
Boolean isInMemory = memory.contains(sub);
if (isInMemory || isValidEnglishWord(sub)){
S[k] = 1;
if(result[i] != null){
// Memoize the result if needed.
if (!isInMemory) {
memory.put(sub, true);
}
result[i+ sub.length()] = result[i] + " " + sub;
} else {
result[i+ sub.length()] = sub;
}
}
}
}
}
return result[len];
}
Personally I always prefer to use memoization as transparently as possible without modifying the algorithm. This is because I want to be able to test the algorithm separately from memoization. Also I am working on a memoization library in which you only have to add #Memoize to methods to which memoization is applicable. But unfortunately this will come too late for you.
The last time I used memoization (without my library) I implemented it using a proxy class. An important remark is that this implementation does not support recursion. But this shouldn't be a problem since your algorithm is not recursive.
Some other references are:
wikipedia
Java implementation
memoize using proxy class
Remark about your algorithm:
How do you handle words that have other words in them? like "verbose" contains "verb", "theory" contains "the" etc...