Given a word, find other words in an array with same length and same characters
$begingroup$
I tried solving the problem in the following manner; I am just a beginner and wanted to know my mistakes and a more efficient way with better time complexity (if any).
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
java
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
|
show 4 more comments
$begingroup$
I tried solving the problem in the following manner; I am just a beginner and wanted to know my mistakes and a more efficient way with better time complexity (if any).
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
java
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday
|
show 4 more comments
$begingroup$
I tried solving the problem in the following manner; I am just a beginner and wanted to know my mistakes and a more efficient way with better time complexity (if any).
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
java
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$endgroup$
I tried solving the problem in the following manner; I am just a beginner and wanted to know my mistakes and a more efficient way with better time complexity (if any).
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
java
java
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 35 mins ago
Jamal♦
30.3k11116226
30.3k11116226
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked yesterday
AdityaAditya
83
83
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
Aditya is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday
|
show 4 more comments
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday
|
show 4 more comments
2 Answers
2
active
oldest
votes
$begingroup$
Whitespace is very important for readability. For posting to Stack Exchange sites I recommend replacing tabs with spaces, because otherwise the site does that for you and the tabstops might not match. Here, though, the whitespace is so crazy that I think you need to look at configuring your IDE to pretty-print the code. Reformatting so that I can understand the structure:
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
Names
Java convention is that camel-case names which start with a capital letter are types (classes, interfaces, etc), so Search as the name of a variable is unexpected.
counter is not entirely uninformative, but a better name would tell me what it counts. Similarly, it would be helpful to distinguish which variables relate to the search query and which to the items searched. The best convention I've seen there is PHP's needle and haystack, so I would suggest needleLetters and haystackWords.
foreach statement
Instead of for(int i=0;i<words.length;i++) ... words[i] you can use for (String word : words) ... word. This removes a variable and simplifies the naming, making it easier to see what the code does.
Decomposing strings
String has a method toCharArray(). I think it would make more sense to use that than split("").
Don't put something in a loop which can go outside it
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
...
}
}
could be rewritten
if(letters.length==ssplit.length)
{
for(int j=0;j<ssplit.length;j++)
{
...
}
}
Executing the test once is more efficient, and it's also easier to understand because the maintainer doesn't have to reason about loop invariants to work out what might have changed the second time the test is executed.
Since there's nothing after this test in the loop body, an alternative would be
if(letters.length!=ssplit.length)
{
continue;
}
for(int j=0;j<ssplit.length;j++)
{
...
}
Beware hard-coded constants
Why
if (counter == 4)
{
System.out.println(words[i]);
}
? That's a bug. The comparison should be with letters.length. Also, it would make more sense to move the test outside the loop over j.
Use advanced data structures
for(int j=0;j<words[i].length();j++)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
}
takes time proportional to words[i].length() * letters.length. If you use java.util.HashMap<Character, Integer> to store a per-character count, you can generate a representation for each word in time proportional to the length of the word, and you can compare the representations of two words in time proportional to the length of each word. In this toy example it doesn't matter, but for real applications the difference between $O(n^2)$ and $O(n)$ can be the difference between a project being feasible and not. The first place to look for optimisations is always the algorithm.
$endgroup$
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
add a comment |
$begingroup$
welcome on Codereview.
I am pretty sure that you will find many other ways to do it the comments from @NateGardner is already a good suggestion. But the goal is to review your code so I will just try to suggest some improvements to your code.
First of all I will just reformat the code, create a dedicated class for it and define the input and output.
class WordFinder {
private final String words;
WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
String find(String word) {
// Your code here
}
}
Then you can start to split your nested logic in different methods and use exiting methods to simplify your code (like String#toCharArray() instead of String#split(""))
String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( this.matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
As said in the beginning, there is a lot of way to test two words for matching and I am sure that you will find the best one. For this answer, I decided to compare the hash of each array of char.
Here is my code if you want. But if you can use other structure from the collections or the stream API, this one can be totally different.
public class WordFinder {
private final String words;
public WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
public String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
private boolean matches(char requirement, char candidate) {
/* Edited to replace Arrays.hashCode with Arrays.equals, see comments
return candidate.length==requirement.length &&
hash(candidate)==hash(requirement);*/
if ( candidate.length!=requirement.length ) {
return false;
}
char left = Arrays.copyOf(requirement, requirement.length);
Arrays.sort(left);
char right = Arrays.copyOf(candidate, candidate.length);
Arrays.sort(right );
return Arrays.equals(left, right);
}
/*private int hash(char array) {
char copy = Arrays.copyOf(array, array.length);
Arrays.sort(copy);
return Arrays.hashCode(copy);
}*/
}
$endgroup$
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such thatArrays.equals(a, b), it is also the case thatArrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can useArrays.equalsonce they are sorted.
$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash withArrays.equals.
$endgroup$
– gervais.b
13 hours ago
|
show 1 more comment
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Aditya is a new contributor. Be nice, and check out our Code of Conduct.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211538%2fgiven-a-word-find-other-words-in-an-array-with-same-length-and-same-characters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Whitespace is very important for readability. For posting to Stack Exchange sites I recommend replacing tabs with spaces, because otherwise the site does that for you and the tabstops might not match. Here, though, the whitespace is so crazy that I think you need to look at configuring your IDE to pretty-print the code. Reformatting so that I can understand the structure:
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
Names
Java convention is that camel-case names which start with a capital letter are types (classes, interfaces, etc), so Search as the name of a variable is unexpected.
counter is not entirely uninformative, but a better name would tell me what it counts. Similarly, it would be helpful to distinguish which variables relate to the search query and which to the items searched. The best convention I've seen there is PHP's needle and haystack, so I would suggest needleLetters and haystackWords.
foreach statement
Instead of for(int i=0;i<words.length;i++) ... words[i] you can use for (String word : words) ... word. This removes a variable and simplifies the naming, making it easier to see what the code does.
Decomposing strings
String has a method toCharArray(). I think it would make more sense to use that than split("").
Don't put something in a loop which can go outside it
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
...
}
}
could be rewritten
if(letters.length==ssplit.length)
{
for(int j=0;j<ssplit.length;j++)
{
...
}
}
Executing the test once is more efficient, and it's also easier to understand because the maintainer doesn't have to reason about loop invariants to work out what might have changed the second time the test is executed.
Since there's nothing after this test in the loop body, an alternative would be
if(letters.length!=ssplit.length)
{
continue;
}
for(int j=0;j<ssplit.length;j++)
{
...
}
Beware hard-coded constants
Why
if (counter == 4)
{
System.out.println(words[i]);
}
? That's a bug. The comparison should be with letters.length. Also, it would make more sense to move the test outside the loop over j.
Use advanced data structures
for(int j=0;j<words[i].length();j++)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
}
takes time proportional to words[i].length() * letters.length. If you use java.util.HashMap<Character, Integer> to store a per-character count, you can generate a representation for each word in time proportional to the length of the word, and you can compare the representations of two words in time proportional to the length of each word. In this toy example it doesn't matter, but for real applications the difference between $O(n^2)$ and $O(n)$ can be the difference between a project being feasible and not. The first place to look for optimisations is always the algorithm.
$endgroup$
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
add a comment |
$begingroup$
Whitespace is very important for readability. For posting to Stack Exchange sites I recommend replacing tabs with spaces, because otherwise the site does that for you and the tabstops might not match. Here, though, the whitespace is so crazy that I think you need to look at configuring your IDE to pretty-print the code. Reformatting so that I can understand the structure:
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
Names
Java convention is that camel-case names which start with a capital letter are types (classes, interfaces, etc), so Search as the name of a variable is unexpected.
counter is not entirely uninformative, but a better name would tell me what it counts. Similarly, it would be helpful to distinguish which variables relate to the search query and which to the items searched. The best convention I've seen there is PHP's needle and haystack, so I would suggest needleLetters and haystackWords.
foreach statement
Instead of for(int i=0;i<words.length;i++) ... words[i] you can use for (String word : words) ... word. This removes a variable and simplifies the naming, making it easier to see what the code does.
Decomposing strings
String has a method toCharArray(). I think it would make more sense to use that than split("").
Don't put something in a loop which can go outside it
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
...
}
}
could be rewritten
if(letters.length==ssplit.length)
{
for(int j=0;j<ssplit.length;j++)
{
...
}
}
Executing the test once is more efficient, and it's also easier to understand because the maintainer doesn't have to reason about loop invariants to work out what might have changed the second time the test is executed.
Since there's nothing after this test in the loop body, an alternative would be
if(letters.length!=ssplit.length)
{
continue;
}
for(int j=0;j<ssplit.length;j++)
{
...
}
Beware hard-coded constants
Why
if (counter == 4)
{
System.out.println(words[i]);
}
? That's a bug. The comparison should be with letters.length. Also, it would make more sense to move the test outside the loop over j.
Use advanced data structures
for(int j=0;j<words[i].length();j++)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
}
takes time proportional to words[i].length() * letters.length. If you use java.util.HashMap<Character, Integer> to store a per-character count, you can generate a representation for each word in time proportional to the length of the word, and you can compare the representations of two words in time proportional to the length of each word. In this toy example it doesn't matter, but for real applications the difference between $O(n^2)$ and $O(n)$ can be the difference between a project being feasible and not. The first place to look for optimisations is always the algorithm.
$endgroup$
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
add a comment |
$begingroup$
Whitespace is very important for readability. For posting to Stack Exchange sites I recommend replacing tabs with spaces, because otherwise the site does that for you and the tabstops might not match. Here, though, the whitespace is so crazy that I think you need to look at configuring your IDE to pretty-print the code. Reformatting so that I can understand the structure:
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
Names
Java convention is that camel-case names which start with a capital letter are types (classes, interfaces, etc), so Search as the name of a variable is unexpected.
counter is not entirely uninformative, but a better name would tell me what it counts. Similarly, it would be helpful to distinguish which variables relate to the search query and which to the items searched. The best convention I've seen there is PHP's needle and haystack, so I would suggest needleLetters and haystackWords.
foreach statement
Instead of for(int i=0;i<words.length;i++) ... words[i] you can use for (String word : words) ... word. This removes a variable and simplifies the naming, making it easier to see what the code does.
Decomposing strings
String has a method toCharArray(). I think it would make more sense to use that than split("").
Don't put something in a loop which can go outside it
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
...
}
}
could be rewritten
if(letters.length==ssplit.length)
{
for(int j=0;j<ssplit.length;j++)
{
...
}
}
Executing the test once is more efficient, and it's also easier to understand because the maintainer doesn't have to reason about loop invariants to work out what might have changed the second time the test is executed.
Since there's nothing after this test in the loop body, an alternative would be
if(letters.length!=ssplit.length)
{
continue;
}
for(int j=0;j<ssplit.length;j++)
{
...
}
Beware hard-coded constants
Why
if (counter == 4)
{
System.out.println(words[i]);
}
? That's a bug. The comparison should be with letters.length. Also, it would make more sense to move the test outside the loop over j.
Use advanced data structures
for(int j=0;j<words[i].length();j++)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
}
takes time proportional to words[i].length() * letters.length. If you use java.util.HashMap<Character, Integer> to store a per-character count, you can generate a representation for each word in time proportional to the length of the word, and you can compare the representations of two words in time proportional to the length of each word. In this toy example it doesn't matter, but for real applications the difference between $O(n^2)$ and $O(n)$ can be the difference between a project being feasible and not. The first place to look for optimisations is always the algorithm.
$endgroup$
Whitespace is very important for readability. For posting to Stack Exchange sites I recommend replacing tabs with spaces, because otherwise the site does that for you and the tabstops might not match. Here, though, the whitespace is so crazy that I think you need to look at configuring your IDE to pretty-print the code. Reformatting so that I can understand the structure:
public class d3 {
public static void main(String args){
String Search="loop";
String letters = Search.split("") ;
int counter;
String words={"pole","pool","lopo","book","kobo"};
for(int i=0;i<words.length;i++)
{
counter=0;
String ssplit = words[i].split("");
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
if (counter == 4)
{
System.out.println(words[i]);
}
}
}
}
}
}
Names
Java convention is that camel-case names which start with a capital letter are types (classes, interfaces, etc), so Search as the name of a variable is unexpected.
counter is not entirely uninformative, but a better name would tell me what it counts. Similarly, it would be helpful to distinguish which variables relate to the search query and which to the items searched. The best convention I've seen there is PHP's needle and haystack, so I would suggest needleLetters and haystackWords.
foreach statement
Instead of for(int i=0;i<words.length;i++) ... words[i] you can use for (String word : words) ... word. This removes a variable and simplifies the naming, making it easier to see what the code does.
Decomposing strings
String has a method toCharArray(). I think it would make more sense to use that than split("").
Don't put something in a loop which can go outside it
for(int j=0;j<words[i].length();j++)
{
if(letters.length==ssplit.length)
{
...
}
}
could be rewritten
if(letters.length==ssplit.length)
{
for(int j=0;j<ssplit.length;j++)
{
...
}
}
Executing the test once is more efficient, and it's also easier to understand because the maintainer doesn't have to reason about loop invariants to work out what might have changed the second time the test is executed.
Since there's nothing after this test in the loop body, an alternative would be
if(letters.length!=ssplit.length)
{
continue;
}
for(int j=0;j<ssplit.length;j++)
{
...
}
Beware hard-coded constants
Why
if (counter == 4)
{
System.out.println(words[i]);
}
? That's a bug. The comparison should be with letters.length. Also, it would make more sense to move the test outside the loop over j.
Use advanced data structures
for(int j=0;j<words[i].length();j++)
{
for(int k=0;k<letters.length;k++)
{
if(letters[j].equals(ssplit[k]))
{
counter++;
ssplit[k]="*";
break;
}
}
}
takes time proportional to words[i].length() * letters.length. If you use java.util.HashMap<Character, Integer> to store a per-character count, you can generate a representation for each word in time proportional to the length of the word, and you can compare the representations of two words in time proportional to the length of each word. In this toy example it doesn't matter, but for real applications the difference between $O(n^2)$ and $O(n)$ can be the difference between a project being feasible and not. The first place to look for optimisations is always the algorithm.
answered yesterday
Peter TaylorPeter Taylor
15.9k2759
15.9k2759
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
add a comment |
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
Thank you for responding. I had no clue that indentation could be so important. And I'll make sure I use better variable names. You mentioned a bug in the " if " statement. I understand that if the length of the search word and the words in the dictionary are greater than 4 than the results produced will not be accurate. But since I know the word-length and as long as it is not something the user will input, it is okay to use constants right?
$endgroup$
– Aditya
15 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
$begingroup$
One of the axes of code quality is brittleness. If changing the search word means that you have to make changes elsewhere, the code is brittle. The problem is that in six months you might have forgotten about the changes which you need to make elsewhere. Making the code less brittle now costs very little, and potentially saves a lot of debugging in the future.
$endgroup$
– Peter Taylor
13 hours ago
add a comment |
$begingroup$
welcome on Codereview.
I am pretty sure that you will find many other ways to do it the comments from @NateGardner is already a good suggestion. But the goal is to review your code so I will just try to suggest some improvements to your code.
First of all I will just reformat the code, create a dedicated class for it and define the input and output.
class WordFinder {
private final String words;
WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
String find(String word) {
// Your code here
}
}
Then you can start to split your nested logic in different methods and use exiting methods to simplify your code (like String#toCharArray() instead of String#split(""))
String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( this.matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
As said in the beginning, there is a lot of way to test two words for matching and I am sure that you will find the best one. For this answer, I decided to compare the hash of each array of char.
Here is my code if you want. But if you can use other structure from the collections or the stream API, this one can be totally different.
public class WordFinder {
private final String words;
public WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
public String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
private boolean matches(char requirement, char candidate) {
/* Edited to replace Arrays.hashCode with Arrays.equals, see comments
return candidate.length==requirement.length &&
hash(candidate)==hash(requirement);*/
if ( candidate.length!=requirement.length ) {
return false;
}
char left = Arrays.copyOf(requirement, requirement.length);
Arrays.sort(left);
char right = Arrays.copyOf(candidate, candidate.length);
Arrays.sort(right );
return Arrays.equals(left, right);
}
/*private int hash(char array) {
char copy = Arrays.copyOf(array, array.length);
Arrays.sort(copy);
return Arrays.hashCode(copy);
}*/
}
$endgroup$
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such thatArrays.equals(a, b), it is also the case thatArrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can useArrays.equalsonce they are sorted.
$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash withArrays.equals.
$endgroup$
– gervais.b
13 hours ago
|
show 1 more comment
$begingroup$
welcome on Codereview.
I am pretty sure that you will find many other ways to do it the comments from @NateGardner is already a good suggestion. But the goal is to review your code so I will just try to suggest some improvements to your code.
First of all I will just reformat the code, create a dedicated class for it and define the input and output.
class WordFinder {
private final String words;
WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
String find(String word) {
// Your code here
}
}
Then you can start to split your nested logic in different methods and use exiting methods to simplify your code (like String#toCharArray() instead of String#split(""))
String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( this.matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
As said in the beginning, there is a lot of way to test two words for matching and I am sure that you will find the best one. For this answer, I decided to compare the hash of each array of char.
Here is my code if you want. But if you can use other structure from the collections or the stream API, this one can be totally different.
public class WordFinder {
private final String words;
public WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
public String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
private boolean matches(char requirement, char candidate) {
/* Edited to replace Arrays.hashCode with Arrays.equals, see comments
return candidate.length==requirement.length &&
hash(candidate)==hash(requirement);*/
if ( candidate.length!=requirement.length ) {
return false;
}
char left = Arrays.copyOf(requirement, requirement.length);
Arrays.sort(left);
char right = Arrays.copyOf(candidate, candidate.length);
Arrays.sort(right );
return Arrays.equals(left, right);
}
/*private int hash(char array) {
char copy = Arrays.copyOf(array, array.length);
Arrays.sort(copy);
return Arrays.hashCode(copy);
}*/
}
$endgroup$
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such thatArrays.equals(a, b), it is also the case thatArrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can useArrays.equalsonce they are sorted.
$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash withArrays.equals.
$endgroup$
– gervais.b
13 hours ago
|
show 1 more comment
$begingroup$
welcome on Codereview.
I am pretty sure that you will find many other ways to do it the comments from @NateGardner is already a good suggestion. But the goal is to review your code so I will just try to suggest some improvements to your code.
First of all I will just reformat the code, create a dedicated class for it and define the input and output.
class WordFinder {
private final String words;
WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
String find(String word) {
// Your code here
}
}
Then you can start to split your nested logic in different methods and use exiting methods to simplify your code (like String#toCharArray() instead of String#split(""))
String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( this.matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
As said in the beginning, there is a lot of way to test two words for matching and I am sure that you will find the best one. For this answer, I decided to compare the hash of each array of char.
Here is my code if you want. But if you can use other structure from the collections or the stream API, this one can be totally different.
public class WordFinder {
private final String words;
public WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
public String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
private boolean matches(char requirement, char candidate) {
/* Edited to replace Arrays.hashCode with Arrays.equals, see comments
return candidate.length==requirement.length &&
hash(candidate)==hash(requirement);*/
if ( candidate.length!=requirement.length ) {
return false;
}
char left = Arrays.copyOf(requirement, requirement.length);
Arrays.sort(left);
char right = Arrays.copyOf(candidate, candidate.length);
Arrays.sort(right );
return Arrays.equals(left, right);
}
/*private int hash(char array) {
char copy = Arrays.copyOf(array, array.length);
Arrays.sort(copy);
return Arrays.hashCode(copy);
}*/
}
$endgroup$
welcome on Codereview.
I am pretty sure that you will find many other ways to do it the comments from @NateGardner is already a good suggestion. But the goal is to review your code so I will just try to suggest some improvements to your code.
First of all I will just reformat the code, create a dedicated class for it and define the input and output.
class WordFinder {
private final String words;
WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
String find(String word) {
// Your code here
}
}
Then you can start to split your nested logic in different methods and use exiting methods to simplify your code (like String#toCharArray() instead of String#split(""))
String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( this.matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
As said in the beginning, there is a lot of way to test two words for matching and I am sure that you will find the best one. For this answer, I decided to compare the hash of each array of char.
Here is my code if you want. But if you can use other structure from the collections or the stream API, this one can be totally different.
public class WordFinder {
private final String words;
public WordFinder(String words) {
this.words = new String[words.length];
System.arraycopy(words, 0, this.words, 0, words.length);
}
public String find(String word) {
String result = new String[this.words.length];
char letters = word.toCharArray();
int counter = 0;
for (String candidate : this.words) {
if ( matches(letters, candidate.toCharArray()) ) {
result[counter++] = candidate;
}
}
return Arrays.copyOf(result, counter);
}
private boolean matches(char requirement, char candidate) {
/* Edited to replace Arrays.hashCode with Arrays.equals, see comments
return candidate.length==requirement.length &&
hash(candidate)==hash(requirement);*/
if ( candidate.length!=requirement.length ) {
return false;
}
char left = Arrays.copyOf(requirement, requirement.length);
Arrays.sort(left);
char right = Arrays.copyOf(candidate, candidate.length);
Arrays.sort(right );
return Arrays.equals(left, right);
}
/*private int hash(char array) {
char copy = Arrays.copyOf(array, array.length);
Arrays.sort(copy);
return Arrays.hashCode(copy);
}*/
}
edited 13 hours ago
answered yesterday
gervais.bgervais.b
1,085410
1,085410
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such thatArrays.equals(a, b), it is also the case thatArrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can useArrays.equalsonce they are sorted.
$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash withArrays.equals.
$endgroup$
– gervais.b
13 hours ago
|
show 1 more comment
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such thatArrays.equals(a, b), it is also the case thatArrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can useArrays.equalsonce they are sorted.
$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash withArrays.equals.
$endgroup$
– gervais.b
13 hours ago
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
The most significant suggestion of this answer introduces a bug. Comparing hashes is a valid way of showing that two objects are different, but it is not a valid way of showing that they're the same.
$endgroup$
– Peter Taylor
yesterday
$begingroup$
"For any two char arrays a and b such that
Arrays.equals(a, b), it is also the case that Arrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can use Arrays.equals once they are sorted.$endgroup$
– gervais.b
17 hours ago
$begingroup$
"For any two char arrays a and b such that
Arrays.equals(a, b), it is also the case that Arrays.hashCode(a) == Arrays.hashCode(b)." docs.oracle.com/javase/7/docs/api/java/util/… But if you prefer you can use Arrays.equals once they are sorted.$endgroup$
– gervais.b
17 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
You are arguing my point. It doesn't say "For any two char arrays a and b such that Arrays.hashCode(a) == Arrays.hashCode(b), it is also the case that Arrays.equals(a, b)". And that can't be the case, if for no other reason then due to the pigeon-hole principle.
$endgroup$
– Peter Taylor
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
Interesting solution, thanks!
$endgroup$
– Aditya
15 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash with
Arrays.equals.$endgroup$
– gervais.b
13 hours ago
$begingroup$
@PeterTaylor it may be due to the language that is not my native one. But I don't get the nuance. I will edit my code to replace the hash with
Arrays.equals.$endgroup$
– gervais.b
13 hours ago
|
show 1 more comment
Aditya is a new contributor. Be nice, and check out our Code of Conduct.
Aditya is a new contributor. Be nice, and check out our Code of Conduct.
Aditya is a new contributor. Be nice, and check out our Code of Conduct.
Aditya is a new contributor. Be nice, and check out our Code of Conduct.
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f211538%2fgiven-a-word-find-other-words-in-an-array-with-same-length-and-same-characters%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
$begingroup$
Hi Aditya. Do you have to use arrays for the words and characters or can you use another structure ?
$endgroup$
– gervais.b
yesterday
$begingroup$
@gervais.b I'm currently not too familiar with other data structures. But I'm open to suggestions. Is there a better option than using arrays?
$endgroup$
– Aditya
yesterday
$begingroup$
@PeterTaylor Thank you for pointing out the bug. I'll try to fix it and update the question as soon as possible.
$endgroup$
– Aditya
yesterday
$begingroup$
Just for inspiration, here's something to consider, without going into the depth of a full answer. If I understand correctly, your goal is to return all the words from your dictionary that contain the same length and character set as your input word. One approach might be to take your dictionary and for every word sort the characters in alphabetical order. Then generate a one-to-many map of the sorted versions of the words to all the words they can make up. Then, once you possess such a map, perform the same operation on the input word, and you're returning a simple key/value lookup; O(1).
$endgroup$
– Nate Gardner
yesterday
$begingroup$
The advantage to such an approach would be that it can process your dictionary offline, offloading the work of testing for your condition and effectively creating a hash index for your search criteria. While generating such a map might take a while, it would only need to be done when the dictionary is modified, while making your performance of searching for these words extremely good, since you can instantly skip to your answer without ever processing any irrelevant words. This approach would make sense if you have a dictionary that stays the same for many inputs.
$endgroup$
– Nate Gardner
yesterday