How to search word in word list? - java

today I learn to write code puzzle word in java. I stress with search word in a list and I want to search it only (Vertical,horizontal) but not diagonal. My code is not gave me error and result. and can you help me to refresh it.
public class WordPuzzle {
private final String puzzleString[][];
private final int rowNumber;
public WordPuzzle(String[][] puzzleString,int rowNumber){
this.puzzleString=puzzleString;
this.rowNumber=rowNumber;
}
public void showPuzzle(){
for(int i=0;i<rowNumber;i++){
for(int j=0;j<rowNumber;j++){
System.out.print(" "+puzzleString[i][j]);
}
System.out.println();
}
}
public Set<String> searchWord(Set<String> word){
Set<String> foundWord=new HashSet<String>();
int minimumWordLength=findMinimumWordLenght(word);
Set<String>compWord=CompatitableWord(minimumWordLength);
for(String w:word){
for(String posibleWord:compWord){
if(posibleWord.contains(w) || posibleWord.contains(new StringBuffer(w).reverse())){
foundWord.add(w);
break;
}
}
}
return foundWord;
}
private int findMinimumWordLenght(Set<String> wordLength){
int minimumLenght=Integer.MAX_VALUE;
for(String w:wordLength){
if(w.length()<minimumLenght){
minimumLenght=w.length();
}
}
return minimumLenght;
}
private Set<String> CompatitableWord(int minimumWordLength){
Set<String>compWord=new LinkedHashSet<String>();
int puzzleLength=puzzleString.length;
if(puzzleLength>=minimumWordLength){
for(int i=0;i<puzzleLength;i++){
if(puzzleString[i].length>=minimumWordLength){
compWord.add(new String(puzzleString[i].toString()));
}
}
for(int i=0;i<puzzleLength;i++){
StringBuffer tmp=new StringBuffer();
for(int j=0;j<puzzleLength;j++){
tmp=tmp.append(puzzleString[j][i]);
}
compWord.add(new String(tmp));
}
}
return compWord;
}
public static void main(String[] args){
String[][] a={{"g","y","r","a","r","b","i","l","e"},
{"u","a","a","n","c","h","o","r","i"},
{"i","b","y","d","v","e","x","t","r"},
{"t","z","c","h","y","n","e","q","u"},
{"a","m","a","n","g","o","d","v","q"},
{"r","n","i","h","p","l","o","d","l"},
{"f","o","r","e","s","t","u","d","y"},
{"j","d","l","w","a","r","c","h","u"},
{"h","a","v","g","h","y","e","t","y"}
};
WordPuzzle pn=new WordPuzzle(a,9);
pn.showPuzzle();
Set<String> str=new HashSet<String>();
str.add("library");
Set<String>wordFound=pn.searchWord(str);
for(String w:wordFound){
System.out.println("Found"+pn.searchWord(str));
}
}
}

You can rewrite your program, because it is so complex and hardly. First, replace strings to chars: you should have matrix of char, char[][] mat. Second, save all rows and columns to String:
String[] rows = ... // use new String(mat[i])
String[] columns = ... // transform matrix and see solution for rows
After this, use rows[i].indexOf or columns[i].indexOf.
Also, you can use rows[i].reverse().indexOf or columns[i].reverse().indexOf.
Sorry for my bad English

Related

Java - printing values of HashSet

I have a simple program here which is meant to find all permutations of a set of letters, or a set of words. From what I can see the program does work in finding the number of permutations there are, however it will only print blank lines in place of where the possible permutations should be.
(Note, UI.println() works in every other case in printing outlines, but for some reason will not work here :( )
I included my method here which should do as I've described, as well as a method that should be able to print out the permutations.
Would anyone have any ideas on what I have done wrong here?
public class Permutations {
public List<List<String>> findPermutations(Set<String> items){
Set<String> copyOfItems = new HashSet<String>(items); // a copy of the set of items that can be modified
List<List<String>> ans = new ArrayList<List<String>>(); // where we will collect the answer
counter=0;
//suggested approach:
extendPermutation(copyOfItems, new Stack<String>(), ans);
return ans;
}
public void extendPermutation(Set<String> remainingItems, Stack<String> permutationSoFar, List<List<String>> allPermutations){
/*# YOUR CODE HERE */
Set<String> alternateSet = new HashSet<String>(remainingItems);
if (remainingItems.isEmpty()) {
allPermutations.add(permutationSoFar);
this.counter = counter + 1;
}
for (String str : remainingItems) {
alternateSet.remove(str);
permutationSoFar.push(str);
extendPermutation(alternateSet,permutationSoFar,allPermutations);
permutationSoFar.pop();
}
}
public void setupGUI(){
UI.addButton("A B C D E", ()->{printAll(findPermutations(Set.of("A","B","C","D","E")));});
UI.addTextField("Letters", (String v)->{printAll(findPermutations(makeSetOfLetters(v)));});
UI.addTextField("Words", (String v)->{printAll(findPermutations(makeSetOfWords(v)));});
UI.addButton("Quit", UI::quit);
UI.setDivider(1.0);
}
public void printAll(List<List<String>> permutations){
UI.clearText();
for (int i=0; i<permutations.size(); i++){
for (String str : permutations.get(i)){UI.print(str+" ");}
UI.println();
}
UI.println("----------------------");
UI.printf("%d items:\n", permutations.get(0).size());
UI.printf("%,d permutations:\n", counter);
UI.println("----------------------");
}
public Set<String> makeSetOfLetters(String str){
Set<String> ans = new HashSet<String>();
for (int i=0; i<str.length(); i++){
if (str.charAt(i)!=' '){
ans.add(""+str.charAt(i));
}
}
return Collections.unmodifiableSet(ans);
}
public Set<String> makeSetOfWords(String str){
Set<String> ans = new HashSet<String>();
for (String v : str.split(" ")){ans.add(v);}
return Collections.unmodifiableSet(ans);
}
// Counter for the number of complete permutations found
private long counter = 0;
public void reportCounter(){
if ((counter<<54)==0) {UI.printMessage((counter>10000000)?((counter>>>20)+"M"):((counter>>>10)+"K"));}
}
// Main
public static void main(String[] arguments) {
Permutations p = new Permutations();
p.setupGUI();
}
}
Your code
permutationSoFar.push(str);
extendPermutation(alternateSet, permutationSoFar, allPermutations);
permutationSoFar.pop();
You first add an item to the permutationSoFar,
then you add a refrence (not a deep copy) the permutationSoFar to your allPermutations, only to pop permutationSoFar. Making sure that your permutationSoFar never contains any elements.
When you print the list of permutationSoFars, the allPermutations, you print an list of empty lists.
Just glancing over your problem, this will likely solve the issue:
allPermutations.add(List.copyOf(permutationSoFar));
But, to be blunt, it is like the rest of your code, not the cleanest solution.

How can I make the Array List be called in another class java

I need to write a code that checks all the words in an array list and tells me how many of these have a certain length. I understand how to do that, but I can't figure out how to make the ArrayList to be read in the second class so I can apply it in the program.
MAIN
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
java.util.ArrayList myList = new java.util.ArrayList();
myList.add("cat");
myList.add("mouse");
myList.add("frog");
myList.add("dog");
myList.add("dog");
int len = in.nextInt();
WordList wl = new WordList();
wl.numWordsOfLength(len);
}
}
SECOND CLASS
public class WordList{
public int numWordsOfLength(int len){
int count = 0;
for(int i=0;i<len;i++){
if(((String)myList.get(i)).length()==len){
count++;
}
}
return count;
}
}
You need to pass the list as parameter:
public int numWordsOfLength(int len, List<String> myList){
int count = 0;
for(int i=0;i<myList.size;i++){
if((myList.get(i)).length()==len){
count++;
}
}
return count;
}
or via the WordList Constructor:
import java.util.List;
public class WordList{
private final List<String> myList;
WordList(List<String> myList){
this.myList = myList;
}
public int numWordsOfLength(int len){
int count = 0;
for (String s : myList) {
if (s.length() == len) {
count++;
}
}
return count;
}
}
Side node instead of :
java.util.ArrayList myList = new java.util.ArrayList();
just do :
import java.util.List;
....
List<String> myList = new ArrayList();
Full Running example:
public class Test {
public static class WordList{
private final List<String> myList;
WordList(List<String> myList){
this.myList = myList;
}
public int numWordsOfLength(int len){
int count = 0;
for (String s : myList) {
if (s.length() == len) {
count++;
}
}
return count;
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
List<String> myList = new ArrayList<>();
myList.add("cat");
myList.add("mouse");
myList.add("frog");
myList.add("dog");
myList.add("dog");
int len = in.nextInt();
WordList wl = new WordList(myList);
System.out.println(wl.numWordsOfLength(len));
}
}
This depends on your interpretation of "read in the second class".
My guess is you want the second class to have "myList" as a private variable, so the code will work when you call the numWordsOfLength() function.
In order to do this, you should pass the array you built to WordList as a dependency. There are generally two ways to give an object a dependency. Either when you create the object (constructor based) or later by calling a method (setters).
So in main, your goal would be to do either:
WordList wl = new WordList();
wl.setList(myList)
wl.numWordsOfLength(len);
Or:
WordList wl = new WordList(myList);
wl.numWordsOfLength(len);
Either way, you will have to add "myList" variable inside the WordList and then expose it either via a separate setter method (setList) or in the constructor itself.
I'd prefer a constructor in this case, since the name of the class "WordList" implies that it IS a list of things and therefore should encapsulate the thing it is.
i.e.
public class WordList{
private List<String> myList;
public WordList(List<String> listOfWords) {
this.myList = listOfWords;
}
public int numWordsOfLength....
}
You don't need that second class at all, if you use Java 8+:
...
java.util.ArrayList<String> myList = new java.util.ArrayList();
myList.add("cat");
myList.add("mouse");
myList.add("frog");
myList.add("dog");
myList.add("dog");
int len = in.nextInt();
int count = myList.stream().map(String::length).filter(c->c==len).count(); <--that's your answer
...
If you prefer to use that second class, you can just use this "count" expression in your numWordsOfLength method in the WordList class once you've passed the list there as the previous answers suggest.
BTW, the loop in your WordList class seem to be incorrect: you're only iterating the list up to len, instead you want to iterate over the entire list. I assume the len variable is the searched lengths of a word:
public int numWordsOfLength(int len, List<String> list){
int count = 0;
for(int i=0;i<list.size();i++){
if(list.get(i).length()==len){
count++;
}
}
return count;
}

I'm trying to find the rank of given strings using recursion

I'm trying to find the rank of given strings using recursion, but can't seem to to come out of the recursion the way I want to. Where am I going wrong?
class Solution {
public static int flag=0;
public static int ans=0;
public static int findRank(String A) {
/* write your solution here */
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
int rank=0;
rank=generate(rank,"",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
return rank;
}
public static int generate(int rank,String prefix,String suffix, ArrayList<String> list,String A){
if(suffix.length()==0){
list.add(prefix);
rank++;
if(prefix.equals(A)){
return rank;
}
}
for(int i=0;i<suffix.length();i++) {
// System.out.println(rank);
return generate(rank,prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A);
}
return rank;
}
}
This is the question:
Given a string, find the rank of the string amongst its permutations sorted lexicographically.
Assume that no characters are repeated.
Example :
Input : 'acb'
Output : 2
The order permutations with letters ‘a’, ‘c’, and ‘b’ :
abc
acb
bac
bca
cab
cba
I tried putting it in a visualizer, here's the code for that:
import java.util.*;
public class Solution {
public static int flag=0;
public static int ans=0;
public static void main(String args[]) {
/* write your solution here */
String A="dbca";
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
int rank=0;
rank=generate(rank,"",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
System.out.println(rank);
}
public static int generate(int rank,String prefix,String suffix, ArrayList<String> list,String A){
if(suffix.length()==0){
list.add(prefix);
rank++;
if(prefix.equals(A)){
return rank;
}
}
for(int i=0;i<suffix.length();i++){
// System.out.println(rank);
return generate(rank,prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A);
}
return rank;
}
}
https://cscircles.cemc.uwaterloo.ca/java_visualize/#mode=edit
Your for loop causes you to end the recursion after you find the first permutation, which is why you always return 1.
What you should be doing is to end the recursion once you find the permutation you are looking for. You can do that, for example, if your recursive method would return a boolean flag instead of an int.
Once the recursive method returns, the length of your list will be the rank you are looking for:
public static int findRank(String A)
{
char[] carr=A.toCharArray();
Arrays.sort(carr);
String suffix=new String(carr);
ArrayList<String> list=new ArrayList<String>();
generate("",suffix,list,A);
for(int i=0;i<list.size();i++)
System.out.print(list.get(i)+" ");
return list.size();
}
public static boolean generate(String prefix,String suffix, ArrayList<String> list,String A)
{
if(suffix.length()==0){
list.add(prefix);
return (prefix.equals(A));
}
for(int i=0;i<suffix.length();i++) {
if (generate(prefix+suffix.charAt(i),suffix.substring(0,i)+suffix.substring(i+1),list, A)) {
return true;
}
}
return false;
}

Sorting using comparable

Intro
My code to do a custom sort by using Comparable is not work the way I want it to. I'm basically taking an Array of directories and sorting them by:
First number of directories, the fewer comes first.
If it's a tie alphabetically.
The problem
An example of an input you be:
["/", "/usr/", "/usr/local/", "/usr/local/bin/", "/games/",
"/games/snake/", "/homework/", "/temp/downloads/" ]
Which should return this:
["/", "/games/", "/homework/", "/usr/", "/games/snake/",
"/temp/downloads/", "/usr/local/", "/usr/local/bin/" ]
But for some reason my code is return this:
["/", "/usr/", "/games/", "/homework/", "/usr/local/",
"/games/snake/", "/usr/local/bin/", "/temp/downloads/" ]
My code [edited with comments]
import java.util.*;
public class Dirsort { public String[] sort(String[] dirs) {
//Creates Array list containing Sort object
ArrayList<Sort> mySort = new ArrayList<Sort>();
//Loop that gets the 3 needed values for sorting
for (String d: dirs){
String [] l = d.split("/");//String array for alphabetical comparison
int di = d.length();//Length of array for sorting by number of directories
mySort.add(new Sort(di,l,d));//adds Sort object to arraylist (note d (the entire directory) is needed for the toString)
}
Collections.sort(mySort);//sorts according to compareTo
String [] ans = new String [mySort.size()];//Creates a new string array that will be returned
int count = 0;//to keep track of where we are in the loop for appending
for (Sort s: mySort){
ans[count] = s.toString();
count++;
}
return ans;
}
class Sort implements Comparable<Sort>{
private int d;//number of directories
private String [] arr;//array of strings of names of directories
private String dir;//full directory as string for toString
//Constructor
public Sort(int myD, String [] myArr, String myDir){
d = myD;
arr = myArr;
dir = myDir;
}
//toString
public String toString(){
return dir;
}
#Override
public int compareTo(Sort arg0) {
// TODO Auto-generated method stub
//If they are the same return 0
if (this.equals(arg0)){
return 0;
}
//if the directories are empty
if("/".equals(arg0.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
//If they are not the same length the shorter one comes first
if (this.d != arg0.d){
return this.d - arg0.d;
}
//If they are the same length, compare them alphabetically
else{
for (int i = 0; i < arg0.d; i++){
if (!this.arr[i].equals(arg0.arr[i])){
return this.arr[i].compareTo(arg0.arr[i]);
}
}
}
return 0;
}
}
}
The bug is here:
for (String d: dirs){
String [] l = d.split("/");
int di = d.length(); // <- here
mySort.add(new Sort(di,l,d));
}
Because there you are comparing the length of the entire directory String, not the number of 'folders' in the directory. That's why "/usr/" comes before "/homework/", for example, because:
"/usr/".length() == 5
"/homework/".length() == 10
I believe what you wanted was this, using the length of the split:
int di = l.length;
Then the output is:
/
/games/
/homework/
/usr/
/games/snake/
/temp/downloads/
/usr/local/
/usr/local/bin/
There's another small bug though (possibly), which is that calling split on a String that starts with the delimiter will result in an empty String at the beginning.
IE:
"/usr/".split("/") == { "", "usr" }
So you might want to do something about that. Though here it means that all of them start with the empty String so it doesn't end up with an effect on the way you're doing the comparison.
And as a side note, it's also true what #JBNizet is suggesting that giving your variables more meaningful names helps a lot here. fullDir.length() and splitDir.length would have made this much easier to spot (and it may have never happened in the first place).
Here's a fixed version of your code, which handles the case where both directories are "/", which removes the unnecessary, and incorrectly passed length of the parts array, and which uses more meaningful variable names:
public class Dirsort {
public static void main(String[] args) {
String[] input = new String[] {
"/",
"/usr/",
"/usr/local/",
"/usr/local/bin/",
"/games/",
"/games/snake/",
"/homework/",
"/temp/downloads/"
};
String[] result = new Dirsort().sort(input);
System.out.println("result = " + Arrays.toString(result));
}
public String[] sort(String[] dirs) {
ArrayList<Sort> sorts = new ArrayList<Sort>();
for (String dir : dirs) {
String[] parts = dir.split("/");
sorts.add(new Sort(parts, dir));
}
Collections.sort(sorts);
String[] result = new String[sorts.size()];
int count = 0;
for (Sort sort: sorts) {
result[count] = sort.toString();
count++;
}
return result;
}
class Sort implements Comparable<Sort> {
private String[] parts;
private String dir;
public Sort(String[] parts, String dir) {
this.parts = parts;
this.dir = dir;
}
public String toString(){
return dir;
}
#Override
public int compareTo(Sort other) {
if (this.equals(other)){
return 0;
}
if("/".equals(other.dir) && "/".equals(dir)) {
return 0;
}
if("/".equals(other.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
if (this.parts.length != other.parts.length){
return this.parts.length - other.parts.length;
}
else {
for (int i = 0; i < other.parts.length; i++){
if (!this.parts[i].equals(other.parts[i])){
return this.parts[i].compareTo(other.parts[i]);
}
}
}
return 0;
}
}
}
I spotted the problem by simply using my debugger and make it display the value of all the variables.
public class Disort
{
public static String[] sort(String[] dirs)
{
ArrayList<Path> mySort = new ArrayList<Path>();
Path pathDir;
for(String dir : dirs){
pathDir = Paths.get(dir);
// check if directory exists
if(Files.isDirectory(pathDir)){
mySort.add(pathDir);
}
}
// sort the ArrayList according a personalized comparator
Collections.sort(mySort, new Comparator<Path>(){
#Override
public int compare(Path o1, Path o2)
{
if(o1.getNameCount() < o2.getNameCount()){
return -1;
}
else if(o1.getNameCount() > o2.getNameCount()){
return 1;
}
else{
return o1.compareTo(o2);
}
}
});
// to return a String[] but it will better to return a ArrayList<Path>
String[] result = new String[mySort.size()];
for(int i = 0; i < result.length; i++){
result[i] = mySort.get(i).toString();
}
return result;
}
}

ClassCast Exception

I've written a method that has some casting errors:
public class Factor {
public static int[] findFactors(ArrayList<Integer> nums){
ArrayList<Integer> factors= new ArrayList();
for(Integer i=new Integer(0);i<nums.size();i++) {
System.out.println(nums.get(i));
for(int j=0;j<nums.get(i);j++) {
if (nums.get(i) %j==0) {
factors.add(j);
}
}
}
int ct=0;
String factorString= factors.toString();
char[] charArray= factorString.toCharArray();
int[] factorArray= new int[(charArray.length+1)/2];
for(int a=0;a<charArray.length;a++) {
if(charArray[a]==',') {
continue;
} else {
String s= Character.toString(charArray[a]);
factorArray[ct]=Integer.parseInt(s);
ct++;
}
}
return factorArray;
}
}
any help would be appreciated
The problem you have that you only escape the , but when you use toString() on a List it is enclose in square brackets []. When you fix that you will discover that size of result array is not valid also you have to subtract 2 (the brackets).
Good Luck with rest. And please read some basic manual about Java.

Categories