Java wordsearch method, searching given 2d array - java

I am trying to pass a word to my findWord method which checks a 2d array of stype String[][] "a" for said word. Row and column are the dimensions of "a". I am not checking diagonal or reverse, only forwards. I believe that nearly if not all of my logic is correct, but I think I'm getting a bounds error. No error is being thrown, but the code just isn't working properly by returning false in random cases that it should return true. Code compiles and runs fine. (i.e it checking past the amount of columns that exist).
public boolean findWord(String word) {
int cL = column;
for(int i = 0; i < row; i++) {
for(int j = 0; j < column; j++) {
if(a[i][j].equals(word.substring(0,1))) {
int c = 1;
int parameter = j + word.length();
if(parameter <= cL) {
for(int k = j; k < parameter; k++) {
if(!a[i][k].equals(word.substring(c,c+1)))
return false;
c++;
}
return true;
}
} else {
return false;
}
}
}
return true;
}

I have run a few test cases. I have not yet found a case where your method returns true despite the word being in the array.
The flaws I have seen in your code are:
You start looking in a[0][0]. If the string found here isn’t equal to the first letter of your word, you immediately return false without looking any further.
Say that the first letter of the word does match a[0][0]. Now you set c to 1, but since i and k are 0, you now compare the second letter of the word to a[0][0]. That is unlikely to match. It only does of the word begins with the same letter twice.
Finally, I did manage to get a StringIndexOutOfBoundsException, namely by searching for aa in a row containing a, b, c. Second time through the innermost loop c is 2, and you therefore try to take out the substring between indices 2 and 3 of a word that has length 2.
You’ve got some fixing to do. Enjoy your work.

Related

Remove same subnet proxies from text file

I want to remove same subnet proxies from a text file.
txt.file= proxy.txt
19.15.15.90:61234
19.15.15.29:28010
19.15.15.80:8998
19.15.15.102:8998
25.25.24.15:8998
25.25.24.80:8998
210.192.38.25:8998
210.192.38.29:8998
I need output be
19.15.15.90:61234
25.25.24.15:8998
210.192.38.25:8998
It doesn't matter which proxies are removed, I just needs to keep 1 from each subnet.
subnet= first 3 numbers the same.
One potential solution1 is to add all the items to a List, sort the list, and then iterate over the list checking if the first n characters are the same as the previous entry, and if not, print it.
First, we'd need to get the third index of . in this scenario2:
public static int nthIndexOf(String text, char needle, int n) {
for (int i = 0; i < text.length(); i++) {
if (text.charAt(i) == needle) {
n--;
if (n == 0) {
return i;
}
}
}
return -1;
}
Then simply perform the iteration as mentioned above:
for (int i = 1; i < list.size(); i++) {
int pos = nthIndexOf(list.get(i), '.', 3);
if (!list.get(i).substring(0, pos).equals(list.get(i - 1).substring(0, pos))) {
System.out.println(list.get(i));
}
}
Oh, and just print the first entry too, as it's going to be unique, considering it hasn't been compared to anything yet.
Of course, I am just printing System.out.println(list.get(i));, but do whatever is necessary with it there.
Example
1There may be edge cases I've missed, but that's up to you to check
2Credit where credit is due

Why I am returning the wrong output?

I am not sure why I am returning false for the first test run as shown in the test table attachment. This was one of my assignments last semester and I never figured out how to solve it:/ My assignment was to:
Write the definition of a method , oddsMatchEvens, whose two parameters are arrays of integers of equal size. The size of each array is an even number. The method returns true if and only if the even-indexed elements of the first array equal the odd-indexed elements of the second, in sequence. That is if w is the first array and q the second array , w[0] equals q[1], and w[2] equals q[3], and so on.
Test table
My code was:
public boolean oddsMatchEvens(int[] w, int[] q) {
int count = 0;
for (int i = 0; i < w.length; i++) {
if (w[i] == q[i + 1])
count++;
if (count == (w.length - 1))
return true;
}
return false;
}
if (count == (w.length - 1))
return true;
This is wrong, since you have only w.length/2 indices which you have to compare.
You should just return false, if w[i] != q[i+1].
And you should increase i by 2, not by 1.
There are two problems with the code:
Firstly, it is clearly mentioned the two input arrays are of equal length and you have to compare them even index to odd index. So the corner case occurs when you are checking last item of first array with last+1 item of second array(which doesn't exist as arrays are of equal length.
Secondly, you have to check first array even with second array odd so increment should be i+=2 and not i++.
Correct code with optimization(if one check fails you can come out of loop):
public boolean oddsMatchEvens(int[] w, int[] q) {
for (int i = 0; i < w.length-1; i+=2) {
if (w[i] != q[i + 1])
return false;
else
continue;
}
return true;
}
public boolean oddsMatchEvens (int []w, int []q) {
for (int j = 0; j < w.length-1; j+=2) {
if (w [j] != q [j+1])
return false;
continue;
}
return true;
}

Matching subsequence of length 2 (at same index) in two strings

Given 2 strings, a and b, return the number of the positions where they contain the same length 2 substring. For instance a and b is respectively "xxcaazz" and "xxbaaz" yields 3, since the "xx", "aa", and "az" substrings appear in the same place in both strings.
What is wrong with my solution?
int count=0;
for(int i=0;i<a.length();i++)
{
for(int u=i; u<b.length(); u++)
{
String aSub=a.substring(i,i+1);
String bSub=b.substring(u,u+1);
if(aSub.equals(bSub))
count++;
}
}
return count;
}
In order to fix your solution, you really don't need the inner loop. Since the index should be same for the substrings in both string, only one loop is needed.
Also, you should iterate till 2nd last character of the smaller string, to avoid IndexOutOfBounds. And for substring, give i+2 as second argument instead.
Overall, you would have to change your code to something like this:
int count=0;
for(int i=0; i < small(a, b).length()-1; i++)
{
String aSub=a.substring(i,i+2);
String bSub=b.substring(i,i+2);
if(aSub.equals(bSub))
count++;
}
}
return count;
Why I asked about the length of string is, it might become expensive to create substrings of length 2 in loop. For length n of smaller string, you would be creating 2 * n substrings.
I would rather not create substring, and just match character by character, while keeping track of whether previous character matched or not. This will work perfectly fine in your case, as length of substring to match is 2. Code would be like:
String a = "iaxxai";
String b = "aaxxaaxx";
boolean lastCharacterMatch = false;
int count = 0;
for (int i = 0; i < Math.min(a.length(), b.length()); i++) {
if (a.charAt(i) == b.charAt(i)) {
if (lastCharacterMatch) {
count++;
} else {
lastCharacterMatch = true;
}
} else {
lastCharacterMatch = false;
}
}
System.out.println(count);
The heart of the problem lies with your usage of the substring method. The important thing to note is that the beginning index is inclusive, and the end index is exclusive.
As an example, dissecting your usage, String aSub=a.substring(i,i+1); in the first iteration of the loop i = 0 so this line is then String aSub=a.substring(0,1); From the javadocs, and my explanation above, this would result in a substring from the first character to the first character or String aSub="x"; Changing this to i+2 and u+2 will get you the desired behavior but beware of index out of bounds errors with the way your loops are currently written.
String a = "xxcaazz";
String b = "xxbaaz";
int count = 0;
for (int i = 0; i < (a.length() > b.length() ? b : a).length() - 1; i++) {
String aSub = a.substring(i, i + 2);
String bSub = b.substring(i, i + 2);
if (aSub.equals(bSub)) {
count++;
}
}
System.out.println(count);

View if a word's letters are in ascending order

I've been at this for a while, but as the title says, I'm trying to create a method that will compare each letter to the letter after it and see if the word is ascending. The method should then return a boolean value. But when it's implemented in my code, it will fail with:
java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(Unknown Source)
and multiple other lines of error code.
Here's my source code:
public static boolean ascending(String word){
int i = 0;
boolean ascend;
do {
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
} while (i <= word.length());
i = 0;
return (ascend);
}
I can't see where I'm going wrong?
condition should be
i < word.length()-1
and the i = 0; at the end should be in side the loop as i++, else it will be infinite loop.
also, you have actually put the reverse check. once you fix ArrayIndexOutOfBoundsException you will return false for ascending string and true otherwise
public static boolean ascending(String word){
if(word == null || word.length <2) return false;
int i = 0;
boolean ascend = false;
while(i < word.length()-1){
if (word.charAt(i) <= word.charAt(i+1))
ascend = true;
else{
ascend = false;
break;
}
i++;
}
return (ascend);
}
In pseudo code:
take the first letter (F) => store it
take the next letter (N) => check against first => stop here if not OK
is there another next letter => stop here if not
update first letter (F) with next letter (N)
repeat starting from 2
Few things needs to be fixed here:
You need to increment "i" to traverse through the word.
Restrict your while loop till (i < word.length() )
You may break at any point when you find ascend is false. No need to continue with the looping.
I would not use a do while because there is an opportunity to run this on an empty string causing it to crash. I would instead use a regular while and at the beginning test for while (i < word.length()-1). You never want to test past the end of the string. You always want to check to see for a string length of n that charAt(n-1) < charAt(n). Also I don't see an incrementer to increase the value of i. Loop will never continue on to the next letter and will run forever.
public static boolean ascending(String word){
int i = 0;
boolean ascend;
while (i < word.length()-1)
{
if (word.charAt(i) <= word.charAt(i+1))
ascend = false;
else
ascend = true;
i++;
}
i = 0;
return (ascend);
}
Do not use do-while loop. Even if you do you need to run some checks beforehand to make sure your word has length more than 1 otherwise your code will raise an IndexOutOfBounds Exception. If you insist on using it, change your condition to i
Here is a working code example:
public boolean isAscending(String word){
if (word==null || word.length==0){
return false;
}
for (int i=1; i<word.length(); i++){
if (word.charAt(i) < word.charAt(i-1))
return false;
}
return true;
}

Allow indexOf to check for match multiple times in Java

I'm currently working on a project for a class to create a TextLine class that represents the a line of text that must be represented as an array of characters. I am not allowed to represent the TextLine object by using the string class indirectly or directly in any way, however, I can use it to work with the parameters.
For one of the methods, I am supposed to take in a string as an argument of a parameter, which is also a fragment to the TextLine object, and then return the index position of the first occurrence of the fragment in this TextLine, or -1, if the fragment is not found.
Right now, I'm trying to figure out the indexOf method, but my problem is that my method only checks for a starting point once. So if the letter of the TextLine object doesn't match the letter of the fragment the first time, but there is another match somewhere else in the object, the method doesn't check for that starting point.
For example, lets say I enter penplay as the TextLine, then I enter play as the fragment. Clearly, there is an occurrence of play in the TextLine, but what my indexOf method does, is that it checks the first p from penplay at index 0, then continues to see if the following letters match for the length of play, and if it doesn't, it returns -1. Any idea how I could allow the algorithm to keep searching for another starting point?
This is what I have for my code:
public int indexOf(String fragment){
char[] temp = fragment.toCharArray();
int j = 0;
for(int i = 0; i < someText.length; i++){
while(someText[i] == temp[j]){
for(j = 1; j < temp.length; j++){
if(temp[j] != someText[i+j]){
return -1;
}
}
return i;
}
}
return -1;
}
You're special-casing the first character, when there's no need to. Basically you need to say:
For each potential starting character...
Does the whole of fragment match, starting at that candidate position?
So something like:
// Only deal with *viable* starting points
for (int i = 0; i < someText.length - temp.length; i++) {
boolean found = true;
for (int j = 0; j < temp.length && found; j++) {
if (temp[j] != someText[i + j]) {
found = false;
}
}
if (found) {
return i;
}
}
return -1;
This can be refactored by extracting the inner loop:
for (int i = 0; i < someText.length - temp.length; i++) {
if (textMatches(temp, i)) {
return i;
}
}
return -1;
...
// TODO: Javadoc to explain parameters :)
private boolean textMatches(char[] chars, int startingIndex) {
for (int i = 0; i < chars.length; i++) {
if (chars[i] != someText[i + startingIndex]) {
return false;
}
}
return true;
}
The way you have it set up seems suitable as a kind of doesStringExistAtIndex(j, fragment) function. Since that returns -1 if the string doesn't exist at the first index, you could do something like this:
//assuming that "this" is the subject that you are searching in
public int indexOf(String fragment){
for(int i=0; i<this.length; ++i){
if(doesStringExistAtIndex(i, fragment))
return i;
}
return -1;
}
Not sure if this is what you wanted, but I basically wrote up an indexOf method. I did some testing and it seemed to work just fine in some tests I did. Of course, its going to look different because I wanted to make testing easier, but it should be 30 seconds or less of converting if you decide to use it.
public int indexOf(String fragment, String source)
{
char[] temp = fragment.toCharArray();
char[] someText = source.toCharArray();
outer : for(int i = 0; i <= someText.length - temp.length;i++) //stops looping because why loop after the fragment is longer than the source we have left when its impossible to find
{
if(someText[i] == temp[0]) //if the first characters are the same
{
int q = 0;
while(q < temp.length) //loop through the fragment
{
if(someText[i+q] != temp[q]) //if the characters are not the same, stop, and go to the next character of the source. Don't return anything
{
continue outer; //continues the loop labeled 'outer' (e.g. outer : for(...) )
}
q++; //increment index since they both match
}
return i; //fragment and some part of the source matched since it reached here. Return the index of the first character
}
}
return -1; //reached here because nothing was found :( return -1
}
EDIT 0 Added line comments

Categories

Resources